Datalogging, changing sampling frequency.

Hello everyone,

I built a arduino who logs data from a acceleroeter to a micro sd card, the sampling frequency I want to achive is about 200 Hz minimun, I'd like it to be as constant as posible, that means 0.005 seconds between samples, but every 50 samples or so, I get a delay of 0.006 seconds between samples... and then each 2040 samples or so, I get a 0.015 second, sometimes even 0.150 second between samples... then if I want to plot my samples they are not equally spaced in the time axis, and that's what I look for, equally spaced data... I think it could be the sd card maybe?

Then my question is, can you explain what is happening? why is that happenig? and Do you know something I can do to avoid or correct those variations in the time while collecting data, or some way I can get equally spaced data?. Sorry if I didn't explain myself clearly, this is my first time on a forum ever :confused:

Could you post some of your code to review?

edsnow: Hello everyone,

I built a arduino who logs data from a acceleroeter to a micro sd card, the sampling frequency I want to achive is about 200 Hz minimun, I'd like it to be as constant as posible, that means 0.005 seconds between samples, but every 50 samples or so, I get a delay of 0.006 seconds between samples... and then each 2040 samples or so, I get a 0.015 second, sometimes even 0.150 second between samples... then if I want to plot my samples they are not equally spaced in the time axis, and that's what I look for, equally spaced data... I think it could be the sd card maybe?

Then my question is, can you explain what is happening? why is that happenig? and Do you know something I can do to avoid or correct those variations in the time while collecting data, or some way I can get equally spaced data?. Sorry if I didn't explain myself clearly, this is my first time on a forum ever :confused:

Simplest explanation: (pure ass guess, because you did not post your code!)

  • You are writing single samples to the SDcard, after ~ 50 samples, the 512byte write buffer fills up, at which point the SdCard library actually writes the data to the SDcard.
  • After ~ 2040 samples, the SDcard has to allocate another cluster to extend your file.

Insulate your sampling code from the writing code. Use a few 512byte buffers to store your samples in. When a buffer is full, then send it to the SdCard.

Change your code to interrupt based sampling. Set up some interrupt source that matches your period. Sample the input, add it to a buffer. If the buffer fills, mark it 'full'. Shift to the next 'free' buffer, continue sampling.

In the 'Main' loop check for the 'full' mark on the buffers, when one is encountered, Write it to the SDcard. After the 'write' has completed, clear the 'full' mark, freeing it to be reused by the 'Sampling interrupt'.

Chuck.

Insulate your sampling code from the writing code. Use a few 512byte buffers to store your samples in. When a buffer is full, then send it to the SdCard.

On an Arduino with 2048 bytes of SRAM, how many 512 byte buffers are you going to create? The SD class already has one per file.

I don't see how this will help, since the File::print() methods block when the SD class buffer gets full, until the transfer to the card is complete.

PaulS: On an Arduino with 2048 bytes of SRAM, how many 512 byte buffers are you going to create? The SD class already has one per file.

I don't see how this will help, since the File::print() methods block when the SD class buffer gets full, until the transfer to the card is complete.

The File::print() method is interruptible. If the Sample routine is 'fast' enough (low overhead), the impact sampling will have on the File object is minimal. The OP never defined which Arduino he was using. If he is using one of the smaller memory size MCU's he could use multiple smaller buffers, (i.e. 128byte). As long as the maximum FILE blockage is less than his total buffer size it will work.

Let's say he wants 200 samples/second, and each sample is eight bytes (x,y,z + tick) so a 128 byte buffer will hold 16 samples. Or 0.080 seconds. If he has four 128byte buffers (0.320 seconds). His worst case was 0.150 seconds. I expect that using four buffers would usually have three buffers empty most of the time. If his main loop was posting each buffer, the FILE object would add the first three 128bytes to it's sector buffer and quickly return. The Fourth buffer write would block until the actual write is completed. Meanwhile, the other three buffers are empty, giving a 0.240 second period for the write to complete.

This is of course a simplistic example, we do not know how he is obtaining his samples, how big each sample is, and what hardware is being used to sample.

My assumption (ass, u, me) is that the accelerometer is NOT a SPI device. If it is a SPI device, the SPI.beginTransaction() locking of the SD library will inhibit sampling sometimes. Will these dropped samples be acceptable? That is for the OP to answer.

The code would need some statics:

  • buffer overflow (no empty buffers)
  • Maximum number of dirty buffers (main loop generated)
  • number of missed samples (if exclusive hardware interference exists)
  • Maximum duration of missed samples (Sample code increments counter until successful sample)

Chuck.