1

I would like to timestamp the data collected from AnalogBinLogger.ino on an Arduino Uno. The sketch uses 512-byte buffers, and I have read that writing data in 512-byte chunks is 'better' in terms of write latencies.

The sketch uses this structure for the buffers:

// Data block for 10-bit ADC mode.
const size_t DATA_DIM16 = 254;
struct block16_t {
  unsigned short count;    // count of data values
  unsigned short overrun;  // count of overruns since last block
  unsigned short data[DATA_DIM16];
};

Since I want to add the timestamps which are of unsigned long type, I would have to modify the structure as follows:

// Data block for 10-bit ADC mode.
const size_t DATA_DIM16 = 254;
struct block16_t {
  unsigned short count;    // count of data values
  unsigned short overrun;  // count of overruns since last block
  unsigned short data[DATA_DIM16];
  unsigned long  milli[DATA_DIM16]; // time in milliseconds
};

Now, this structure exceeds 512 bytes and is 1528 bytes. Due to unavailability of enough free stack, my program doesn't run (sketch reports FreeStack to be 1135 bytes). How can I go about this?

PS: My root problem is to achieve time-synchronisation among multiple data-collecting Arduinos which sample at high rates like 8kHz. Due to clock drifts, even if I sync the start times, the timestamps collected afterwards would not be relative to each other. Hence I plan to have a master Arduino send its time to the others in regular intervals.

0

2 Answers 2

1

The straightforward solution:

const size_t DATA_DIM16 = 84;
struct block16_t {
  unsigned short count;    // count of data values
  unsigned short overrun;  // count of overruns since last block
  unsigned short data[DATA_DIM16];
  unsigned long  milli[DATA_DIM16]; // time in milliseconds
  unsigned long padding;   // pad to 512 bytes
};

Now, I suggest to think again about your requirements. Do you really need a 32-bit timestamp for every data point? If they are closely spaced in time, a 16-bit, or even 8-bit timestamp should be enough. You could put a full 32-bit timestamp at the beginning of each block, then only 8-bit timestamps for every data point. This would allow you to store 168 samples per block. You could even pack a 6-bit timestamp with the data sample into an uint16_t, and have 252 samples per block.

1

Writing in 512 byte chunks is done by SD libraries, so you could rely on that layer and simply write and store single events

struct block_t {
  uint32_t  milli; // time in milliseconds
  uint16_t data;
  uint8_t  overrun;  // overrun status since last block
};

I do not know your AnalogBinLogger.ino. In other circumstances there's no such 512 byte limit, but a general and strict RAM limit. (You could decrease your DATA_DIM to make it fit safely)

2
  • My understanding is that a 512-byte buffer was chosen for its efficiency, which is an important consideration when you try to log data at a high rate. Commented Jun 27, 2019 at 8:06
  • github.com/greiman/SdFat/blob/master/examples/AnalogBinLogger/… is an interesting example. Thanks @Edgar and Harini Commented Jun 28, 2019 at 9:18

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.