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.
2 Answers 2
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.
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)
-
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.Edgar Bonet– Edgar Bonet2019年06月27日 08:06:28 +00:00Commented Jun 27, 2019 at 8:06
-
github.com/greiman/SdFat/blob/master/examples/AnalogBinLogger/… is an interesting example. Thanks @Edgar and HariniDataFiddler– DataFiddler2019年06月28日 09:18:21 +00:00Commented Jun 28, 2019 at 9:18
Explore related questions
See similar questions with these tags.