Jump to content
  • 0

High Speed Data on MCC 128




I am using a Raspberry Pi 4B with 3 MCC 128 HATs. I have the HATs synced to capture 3 streams of data at the same time (with one board being the master and the clocks synced). I am capturing 4 kS/s per board in continuous mode. I am only using 1 differential channel per board.

The data capture itself is working correctly but the hurdle we are trying to overcome is getting the data from the HATs to the program on the Pi in a timely manner (using C). We have a requirement to receive and process the data within 5ms of capturing the data via the A/D converter.

My question is: Are the MCC 128 HATs capable of sending data to the pi fast enough? It seems that when polling the board for data while it is in continuous mode repeatedly leads to having 0 samples for up to 400 periods (25ms) then the poll returns 400 data points from the capture. We have gotten it down to 200 sample points returned but that is still not fast enough. Ideally we would like 1 or 2 sample points returned very shortly after they are taken and not the hundreds that get "saved up". Is there any way to reduce this and receive the data points closer to when they are taken?


Link to comment
Share on other sites

3 answers to this question

Recommended Posts

  • 0

Hello @DavidH.

When using the 'mcc128_a_in_scan_start' function in continuous mode, the buffer size must be large enough for the data to be read before being overwritten in order to avoid a buffer overrun error.  The online help contains a default buffer size table.  https://mccdaq.github.io/daqhats/c.html#c.mcc128_a_in_scan_start 

What value do you set for the 'samples_per_channel' parameter, in the 'mcc128_a_in_scan_start' function?

If you could acquire single values in the range of 4-6 KHz per channel, using the 'mcc128_a_in_read' function, would that be acceptable for your application?




Link to comment
Share on other sites

  • 0

The samples_per_channel is set to 1,000 but according to the online help page it should be 10,000 as per the table given and it is a larger value for 4 kS/s.

If 'mcc128_a_in_read' could give data back fast enough that could work. We did some preliminary testing and doing that on one board worked (took something like 150us to return if i recall correctly) but when calling that on 3 board in a row it took longer then the required 250us "loop time" to collect the data before needing the next data point. We also didn't know if the sync on the boards worked the same or differently in the single vs continuous mode. (maybe have to use triggers instead of clock?) We didn't explore that path very far as the time to read from all 3 board was too long as stated.

If there was a way to get that to work, there would be no problem with it.

Link to comment
Share on other sites

  • 0

Here is an update on what we have tested so far:

When reading single inputs one right after another:
mcc128_a_in_read(address[0], CHAN0, 0, &value1);
mcc128_a_in_read(address[1], CHAN0, 0, &value2);
mcc128_a_in_read(address[2], CHAN0, 0, &value3);

This is the timing output:
Read Board 1 time: 171815ns
Read Board 2 time: 175556ns
Read Board 3 time: 175611ns
Loop time: 658814ns
Read Board 1 time: 175315ns
Read Board 2 time: 180148ns
Read Board 3 time: 176000ns
Loop time: 639500ns
Read Board 1 time: 167889ns
Read Board 2 time: 178296ns
Read Board 3 time: 178482ns
Loop time: 639463ns

So each single board read takes ~175us to read. For one board that is below our requirement of 250us. But taking 3 readings in a row that time is too long as well at the readings are not synced like in the continuous mode.


When testing in continuous mode:
result = mcc128_a_in_scan_read(address[0],&scan_status[0],-1,0,&value1_to_be_processed,1000, &samples_read[0]);
result = mcc128_a_in_scan_read(address[1],&scan_status[1],-1,0,&value2_to_be_processed,1000, &samples_read[1]);
result = mcc128_a_in_scan_read(address[2],&scan_status[2],-1,0,&value3_to_be_processed,1000, &samples_read[2]);

The loop time when there is no data (samples_read[n] == 0) is:
Loop time: 9648ns
Loop time: 9741ns
Loop time: 9796ns

The loop time when there is data varies wildly:
Loop time: 25314ns
Loop time: 6231056ns
Loop time: 175686ns
Loop time: 28037ns

These reads contain anywhere from 1 data point to 200 data points and anywhere in between with most of then being less then 3 (which is great);

I edited mcc128.c to take out the usleep(100) on line 2410 and added "info->read_threshold = 1;" on line 1762 to make this possible.

After these changes the boards work speedy and return a small number of data points. We can process the data in "realtime" (less then 5ms). Then after a small amount of time (500ms give or take) one of the boards has a hiccup of sorts and "builds up" 100 data points or more and then makes them available. The delay is then (100 samples * 250us/sample = 25ms) and the program cannot process the data in "realtime" anymore (less then 5ms). 


Is there anything else I can do to make the board run "smoother" or use a single read to get simultaneous readings on all 3 boards (faster then 250us)?

Edited by DavidH
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Create New...