Jump to content

As of July 17, 2015, the LabJack forums here at forums.labjack.com are shut down. New registrations, topics, and replies are disabled. All forums are in a read-only state for archive purposes.

Please visit our current forums at labjack.com/forums to view and make new posts. To post on the current forums, use your labjack.com login account. Your old LabJack forums login credentials have been retired. There are no longer separate logins for labjack.com and LabJack forums.


Stream U3-LV, scan data problem in C

  • Please log in to reply
3 replies to this topic

#1 AdrienA

  • Members
  • 2 posts

Posted 14 May 2013 - 09:13 AM

I'm pretty new to programming and during a placement I have to timestamp with high accuracy (< 1ms) several events from sensors. Those sensors provide pulses when they get a new data, and data are sent to a computer through different kind of connectors.

So the idea is to be able to timestamp every frame between sensors with a common clock. Then those timestamps can be sent to the computer and I can match every data to every timestamp. I should be able to timestamp different input pulse with respect to one input pulse (the important thing is to get the relative delay between one main input pulse with all others).

I tested the LabJack with a low frequency generator which give me 1 pulse (from 0V to 2V) during 1 second and it happens every 5 second. I succeeded to streamed it but there're things that i don't really understand in the following code. I obtain something like that :
Click here
I don't understand the value of "Scan" (which is the value in "channelA").

Otherwise, as I said, i'm a beginner and i wanted to know how to detect a pulse (rising edge) in stream mode ?

Here is a part of my code :

/********************************************* CONFIG *********************************************/
// Get the scan rate.
lngErrorcode = m_pAddRequest(lngHandle, LJ_ioPUT_CONFIG, LJ_chSTREAM_SCAN_FREQUENCY, 4000, 0, 0);
ErrorHandler(lngErrorcode, __LINE__, 0);
// Give the UD Driver a 5 second buffer (scanRate*2channels*5seconds).
lngErrorcode = m_pAddRequest(lngHandle, LJ_ioPUT_CONFIG, LJ_chSTREAM_BUFFER_SIZE, 4000*2*5, 0, 0);
ErrorHandler(lngErrorcode, __LINE__, 0);
// Configure reads to wait and retrieved desire amount of data
lngErrorcode = m_pAddRequest(lngHandle, LJ_ioPUT_CONFIG, LJ_chSTREAM_WAIT_MODE, LJ_swSLEEP, 0, 0);
ErrorHandler(lngErrorcode, __LINE__, 0);
lngErrorcode = m_pAddRequest(lngHandle, LJ_ioPUT_CONFIG, LJ_chSTREAM_SAMPLES_PER_PACKET, 25, 0, 0);
ErrorHandler(lngErrorcode, __LINE__, 0);
lngErrorcode = m_pAddRequest(lngHandle, LJ_ioPUT_CONFIG, LJ_chSTREAM_READS_PER_SECOND, 25, 0, 0);
ErrorHandler(lngErrorcode, __LINE__, 0);

// Clear all stream channels
lngErrorcode = m_pAddRequest(lngHandle, LJ_ioCLEAR_STREAM_CHANNELS, 0, 0, 0, 0);
ErrorHandler(lngErrorcode, __LINE__, 0);

// Define the scan list as single ended AIN2/FIO2
lngErrorcode = m_pAddRequest(lngHandle, LJ_ioADD_STREAM_CHANNEL, 2, 0, 0, 0);
ErrorHandler(lngErrorcode, __LINE__, 0);

lngErrorcode = m_pGoOne(lngHandle);
ErrorHandler(lngErrorcode, __LINE__, 0);

// Start the stream
lngErrorcode = m_peGet(lngHandle, LJ_ioSTART_STREAM, 0, &dblValue, 0);
ErrorHandler(lngErrorcode, __LINE__, 0);

actualScanRate = dblValue;
printf("Actual Scan Rate = %.3f Hz\n",dblValue);
actualSampleRate = 2*dblValue;
printf("Actual Sample Rate = %.3f\n\n",2*dblValue);

/******************************************** WHILE ***********************************************/
// Read data until done.
int done = 10;
long data[4000*2*5];
long dataAddr = (long)&data;
long channelA = 0;

while(done > 0)
double actualNumberRead = 0;
double numScans = 1000;

lngErrorcode = m_peGet(lngHandle, LJ_ioGET_STREAM_DATA, LJ_chALL_CHANNELS, &numScans, dataAddr);
ErrorHandler(lngErrorcode, __LINE__, 0);

//The displays the number of scans that were actually read.
actualNumberRead = numScans;
printf("Number read = %.0f\n",numScans);

// When all channels are retrieved in a single read, the data
//is interleaved in a 1-dimensional array. The following lines
//get the first sample from each channel.
channelA = data[0];

//This displays just the first scan.
printf("Scan = %d\n", channelA);

lngErrorcode = m_peGet(lngHandle, LJ_ioGET_CONFIG, LJ_chSTREAM_BACKLOG_COMM, &dblCommBacklog, 0);
ErrorHandler(lngErrorcode, __LINE__, 0);
printf("Comm Backlog = %.0f\n",dblCommBacklog);

lngErrorcode = m_peGet(lngHandle, LJ_ioGET_CONFIG, LJ_chSTREAM_BACKLOG_UD, &dblUDBacklog, 0);
ErrorHandler(lngErrorcode, __LINE__, 0);
printf("UD Backlog = %.0f\n",dblUDBacklog);

printf("Done = %d\n\n",done);
Sleep(1000); // Wait for 1 second

// Stop the stream
lngErrorcode = m_pAddRequest(lngHandle, LJ_ioSTOP_STREAM,0, 0, 0, 0);
ErrorHandler(lngErrorcode, __LINE__, 0);
lngErrorcode = m_pGoOne(lngHandle);

if(getchar() == 'a')
return (0);

This code has been made for a test but i hope to be on the right way to succeed because my superior diploma depends of that.


#2 LabJack Support

LabJack Support
  • Admin
  • 8677 posts

Posted 14 May 2013 - 02:04 PM

Using analog inputs, you would probably have some sort of state machine code to find rising edges. Start with the initial condition State=0. Then test each sample in order and if the voltage>1.5 set State=1 and call that your rising edge. Then keep testing each sample and if the voltage<0.5 set State=0 and start over. What is the width of the pulses? Perhaps you could use counters rather than analog inputs? How many channels do you need to acquire? That is, how many sensors will you have creating pulses? I think the reason Scan is showing a funny number is that your are doing a printf with %d formatting but the value is a floating-point double. Another problem is that your UD Backlog is growing. The reason for that is you are using SLEEP wait mode and you also have a 1000ms delay in your loop. If using SLEEP wait mode, then you don't need any delay in your loop. What example did you start with? I suggest you look at U3_SimpleStream in the VC6_LJUD archive as that does not have these mistakes. You can change that example from static linking to dynamic linking and get it working properly before you make further changes.

#3 AdrienA

  • Members
  • 2 posts

Posted 22 May 2013 - 05:26 AM

Hi, As an exemple I took a look at the U3_SimpleStream in the VC6_LJUD, it was helpful. My UD Backlog was growing because i took that screenshot when i was in debug mode with breakpoints, by the way i removed the 1000ms delay as you said. I also changed my "channelA" variable to a %.2f, thanks for that. The pulses stay 1.4 second at the high state. I have to acquire 4 signals, 3 from LIDARs and 1 from a ladybug camera but i don't really know how to do it at the same time. I guess that the acquisition have to be way more faster than my test but if i succeed to stream all that signals the rest will belong to the scan rate and so the global configuration, isn't it ?

#4 LabJack Support

LabJack Support
  • Admin
  • 8677 posts

Posted 22 May 2013 - 08:47 AM

The U3 can count up to 4 signals, so I suggest you try that first rather than using analog inputs that you process in software to find the edges.

To count 4 signals you use the 2 hardware Counters and configure the 2 Timers in firmware counter mode:



Try it in the test panel in LJControlPanel first, and confirm that your signals correctly increment the counts on Timer0 (FIO4), Timer1 (FIO5), Counter0 (FIO6), and Counter1 (FIO7).

The next step is to go into "config defaults" in LJControlPanel, and make the desired timer/counter configuration the power-up default.

Then go to your stream program and stream 8 channels: 200, 224, 201, 224, 210, 224, 211, 224.


To get your desired relative time accuracy of 1ms, you need to stream at at least 1 kscans/second, which with your 8 channels is 8 ksamples/second. You could stream at up to 6 kscans/second which is 48 ksamples/second.

0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users