 frequency sampling on U3 | LabJack

# frequency sampling on U3

6 posts / 0 new
Hakim frequency sampling on U3

Hello everyone

I started working with labjack U3-HV recently and I use the analog inputs to make an acquisition of electrical signals. So I started working with the exemples code provided here:

https://labjack.com/support/software/installers/exodriver

I use the u3Stream.c code, it's an example given by labjack above, where it's explained how to make a streaming acquisition.

If I have understand well the u3 datasheets,

https://labjack.com/support/datasheets/u3/operation/stream-mode

it's specifed that we can make a streaming acquisition with different frequency sampling.

So my question is: How I can to do a streaming acquisition with a frequency that I choise? like 2ksamples/second

Thank you

LabJack Support In the StreamConfig low-level

In the StreamConfig low-level function, you configure the stream scan frequency with the Scan Interval setting in bytes 10 and 11. The StreamConfig_examples in u3Stream.c demonstrates this and the setting is documented here:

https://labjack.com/support/datasheets/u3/low-level-function-reference/s...

The interval between scans (in seconds) is the ScanInterval/ClockFrequency. So in relation to the ScanInterval and ScanFrequency (Hz), you would set the ScanInterval like so:

ScanInterval = ClockFrequency / ScanFrequency

For example, if you are streaming 1 channel at a scan rate of 2kscans/second (2ksamples/second), you could set it with the following scan interval with the 4MHz clock (StreamConfig: bit 3 of byte 9 set to 0):

ScanInterval = 4000000 / 2000 = 2000

Note that SampleRate = NumberOfChannels * ScanRate. Sample rate and scan rate terminology is discussed in the stream mode page you linked to in your post.

Hakim Hello,

Hello,

Thank you for the response, I find the scanInterval in the code u3Stream.c

1 - Can you given me some details about the StreamData_example function? I don't understand why you use two loops numReadsPerDisplay and readSizeMultiplier to read the data?

2 - In case when I need use multiple analog input, I have a segmentation fault if I try use 2 inputs for example. How I can do to resolve this problem?

Best regards

LabJack Support 1. At the beginning of the

1. At the beginning of the StreamData_example function, where the variables are declared there are comments describing the purpose of the variables. In more detail:

The numReadsPerDisplay variable is for outputting/displaying information to the terminal. Every numReadsPerDisplay number of LJUSB_Stream calls, stream status information is displayed.

The readSizeMultiplier variable indicates how many StreamData responses to read per LJUSB_Stream call. In the loop using this variable, its going through the readSizeMultiplier amount of StreamData responses and parsing out the samples.

In your own code, a numReadsPerDisplay loop would be optional and you could instead just use a loop that performs the LJUSB_Stream calls and a readSizeMultiplier loop to parse through the StreamData responses.

2. First, make sure numChannels is set to 2 or the amount of inputs you want to read so the voltages array size is the correct size. Second, make sure your recBuff and voltages arrays are large enough for the changes you make to the code.

If that doesn't help, attach your code in the next post so I can see your changes. What call in the code is causing the seg. fault?

Hakim Hello,

Hello,

Sorry to give response late.

I attached the following code, the number of channels is 2. In the streaDta_example, I removed the numdisplay loop.

So If I understand well, I kept the numReadsPerDisplay loop which calls the LJUSB_Stream 24 times. In this case, I have an error process retourned 139 (0x8B). But if I use 1 channel, it works well.

• In the same way, I have an Error : did not read all of the buffer, expected 310 bytes but received 62(StreamData), If I changed the number of sampleperpacket between 1-25.

`<``code` `type``=``"c"``>`#include "u3.h"
#include <iostream>
#include <fstream>
using namespace std;

int ConfigIO_example(HANDLE hDevice, int *isDAC1Enabled);
int StreamConfig_example(HANDLE hDevice);
int StreamStart(HANDLE hDevice);
int StreamData_example(HANDLE hDevice, u3CalibrationInfo *caliInfo, int isDAC1Enabled);
int StreamStop(HANDLE hDevice);

const uint8 NumChannels = 2;  //For this example to work proper,
//SamplesPerPacket needs to be a multiple of
//NumChannels.
const uint8 SamplesPerPacket = 25;  //Needs to be 25 to read multiple StreamData
//responses in one large packet, otherwise
//can be any value between 1-25 for 1
//StreamData response per packet.

int main(int argc, char **argv)
{
HANDLE hDevice;
u3CalibrationInfo caliInfo;
int dac1Enabled;

//Opening first found U3 over USB
if( (hDevice = openUSBConnection(-1)) == NULL )
goto done;

//Getting calibration information from U3
if( getCalibrationInfo(hDevice, &caliInfo) < 0 )
goto close;

if( ConfigIO_example(hDevice, &dac1Enabled) != 0 )
goto close;

//Stopping any previous streams
StreamStop(hDevice);

if( StreamConfig_example(hDevice) != 0 )
goto close;
if( StreamStart(hDevice) != 0 )
goto close;

StreamData_example(hDevice, &caliInfo, dac1Enabled);
StreamStop(hDevice);

close:
closeUSBConnection(hDevice);
done:
return 0;
}

....

int StreamStart(HANDLE hDevice)
{
uint8 sendBuff, recBuff;
int sendChars, recChars;

sendBuff = (uint8)(0xA8);  //CheckSum8
sendBuff = (uint8)(0xA8);  //command byte

//Sending command to U3
sendChars = LJUSB_Write(hDevice, sendBuff, 2);
if( sendChars < 2 )
{
if( sendChars == 0 )
printf("Error : write failed.\n");
else
printf("Error : did not write all of the buffer.\n");
return -1;
}

if( recChars < 4 )
{
if( recChars == 0 )
else
printf("Error : did not read all of the buffer.\n");
return -1;
}

if( normalChecksum8(recBuff, 4) != recBuff )
{
return -1;
}

if( recBuff != (uint8)(0xA9) || recBuff != (uint8)(0x00) )
{
printf("Error : read buffer has wrong command bytes \n");
return -1;
}

if( recBuff != 0 )
{
printf("Errorcode # %d from StreamStart read.\n", (unsigned int)recBuff);
return -1;
}

return 0;
}

//Reads the StreamData low-level function response in a loop.  All voltages from
//the stream are stored in the voltages 2D array.
int StreamData_example(HANDLE hDevice, u3CalibrationInfo *caliInfo, int isDAC1Enabled)
{
uint16 voltageBytes, checksumTotal;
long startTime, endTime;
double hardwareVersion;
int recBuffSize, recChars, backLog, autoRecoveryOn;
int packetCounter, currChannel, scanNumber;
int i, j, k, m;
int totalPackets;  //The total number of StreamData responses read
int numDisplay;  //Number of times to display streaming information
//streaming information
int responseSize;  //The number of bytes in a StreamData response
//(differs with SamplesPerPacket)

numDisplay = 1;
responseSize = 14 + SamplesPerPacket*2;

/* Each StreamData response contains (SamplesPerPacket / NumChannels) * readSizeMultiplier
* samples for each channel.
* Total number of scans = (SamplesPerPacket / NumChannels) * readSizeMultiplier * numReadsPerDisplay * numDisplay
*/

packetCounter = 0;
currChannel = 0;
scanNumber = 0;
totalPackets = 0;
recChars = 0;
autoRecoveryOn = 0;
recBuffSize = 14 + SamplesPerPacket*2;
hardwareVersion = caliInfo->hardwareVersion;

startTime = getTickCount();

for( j = 0; j < numReadsPerDisplay; j++ )
{
/* For USB StreamData, use Endpoint 3 for reads.  You can read the
* multiple StreamData responses of 64 bytes only if
* SamplesPerPacket is 25 to help improve streaming performance.  In
* variable.
*/

{
if( recChars == 0 )
else
printf("Error : did not read all of the buffer, expected %d bytes but received %d(StreamData).\n", responseSize*readSizeMultiplier, recChars);
return -1;
}

//Checking for errors and getting data out of each StreamData
//response
for( m = 0; m < readSizeMultiplier; m++ )
{
totalPackets++;

checksumTotal = extendedChecksum16(recBuff + m*recBuffSize, recBuffSize);
if( (uint8)((checksumTotal / 256) & 0xFF) != recBuff[m*recBuffSize + 5] )
{
return -1;
}

if( (uint8)(checksumTotal & 0xFF) != recBuff[m*recBuffSize + 4] )
{
return -1;
}

checksumTotal = extendedChecksum8(recBuff + m*recBuffSize);
if( checksumTotal != recBuff[m*recBuffSize] )
{
return -1;
}

if( recBuff[m*recBuffSize + 1] != (uint8)(0xF9) ||
recBuff[m*recBuffSize + 2] != 4 + SamplesPerPacket ||
recBuff[m*recBuffSize + 3] != (uint8)(0xC0) )
{
printf("Error : read buffer has wrong command bytes (StreamData).\n");
return -1;
}

if( recBuff[m*recBuffSize + 11] == 59 )
{
if( !autoRecoveryOn )
{
printf("\nU3 data buffer overflow detected in packet %d.\nNow using auto-recovery and reading buffered samples.\n", totalPackets);
autoRecoveryOn = 1;
}
}
else if( recBuff[m*recBuffSize + 11] == 60 )
{
printf("Auto-recovery report in packet %d: %d scans were dropped.\nAuto-recovery is now off.\n", totalPackets, recBuff[m*recBuffSize + 6] + recBuff[m*recBuffSize + 7]*256);
autoRecoveryOn = 0;
}
else if( recBuff[m*recBuffSize + 11] != 0 )
{
printf("Errorcode # %d from StreamData read.\n", (unsigned int)recBuff);
return -1;
}

if( packetCounter != (int)recBuff[m*recBuffSize + 10] )
{
printf("PacketCounter (%d) does not match with with current packet count (%d)(StreamData).\n", recBuff[m*recBuffSize + 10], packetCounter);
return -1;
}

backLog = (int)recBuff[m*48 + 12 + SamplesPerPacket*2];

for( k = 12; k < (12 + SamplesPerPacket*2); k += 2 )
{
voltageBytes = (uint16)recBuff[m*recBuffSize + k] + (uint16)recBuff[m*recBuffSize + k+1]*256;

if( hardwareVersion >= 1.30 )
getAinVoltCalibrated_hw130(caliInfo, currChannel, 31, voltageBytes, &(voltages[scanNumber][currChannel]));
else
getAinVoltCalibrated(caliInfo, isDAC1Enabled, 31, voltageBytes, &(voltages[scanNumber][currChannel]));

currChannel++;
if( currChannel >= NumChannels )
{
currChannel = 0;
scanNumber++;
}
}

if( packetCounter >= 255 )
packetCounter = 0;
else
packetCounter++;
}
}

printf("\nNumber of scans: %d\n", scanNumber);
printf("Current PacketCounter: %d\n", ((packetCounter == 0) ? 255 : packetCounter-1));
printf("Current BackLog: %d\n", backLog);

for( k = 0; k < NumChannels; k++ )
printf("  AI%d: %.4f V\n",k, voltages[scanNumber - 1][k]);//remplacer [scanNumber - 1] par[scanNumber - 1][k]

ofstream datalabjack("/home/mahfoud/Bureau/CodeBlocks/labjackU3streaming/data.txt", ios::out | ios::trunc);
ofstream datalabjack2("/home/mahfoud/Bureau/CodeBlocks/labjackU3streaming/data2.txt", ios::out | ios::trunc);

datalabjack2 << voltages[i] << endl;
datalabjack << voltages[i] << endl;
}
datalabjack2.close();
datalabjack.close();

endTime = getTickCount();
printf("\nRate of samples: %.0lf samples per second\n", ((scanNumber*NumChannels) / ((endTime-startTime) / 1000.0)));
printf("Rate of scans: %.0lf scans per second\n\n", (scanNumber / ((endTime - startTime) / 1000.0)));

return 0;
}
`</``code``>`

LabJack Support The voltages array is too

The voltages array is too small, so you are going out of its bounds eventually causing the segmentation fault. Integer math is being performed to calculate the array size, so "SamplesPerPacket/NumChannels" is getting rounded down and causing the array to be too small.So try something like this instead for your voltages array size: