I have implemented a data logger to test several new features of SdFat and a small RTOS.
This logger produces a CSV file and performs very well for a logger that formats text. I have logged two analog pins at 1000 Hz on a Uno and 16 pins at 100 Hz on a Mega.
It is designed to log any number of analog pins starting with pin zero. This could be modified easily.
It works best with a quality SD card but will provide good results with lower quality cards.
Several features of SdFat and the RTOS enhance performance.
Two threads and a large buffer are used to overcome the occasional large write latency of SD cards.
A special version of analogRead() is used that sleeps during the ADC conversion. This saves CPU time for the SD write thread.
A new SdFat function, printField(), is used to format data. This function is several times faster than the standard Print class.
The logger is the nilSdLogger example in NilRTOS.
Three parameters configure the program. Here is an example to log the 16 Mega analog pins at 100 Hz.
// Time between points in microseconds. // Maximum value is 4,194,304 (2^22) usec. const uint32_t PERIOD_USEC = 10000; // Number of ADC channels to log const uint8_t NADC = 16; // FIFO buffer size. Adjust so unused idle thread stack is about 100 bytes. const size_t FIFO_SIZE_BYTES = 4000;
Here is the beginning of the data file:
Statistics are printed at the end of a run. Here are stats for the Mega.
Max Write Latency: 68780 usec
Unused Stack: 49 3207
FIFO record count: 125
Minimum free count: 117
A very good SD card was used so the max write latency was about 69 ms.
The data read thread had 49 bytes of unused stack.
The SD write thread had 3207 unused bytes so more buffering could have been used. Adjust FIFO_SIZE_BYTES so the write thread has about 100 unused bytes for best buffer performance.
125 buffers were allocated with space for 16 ADC value in each buffer. The total buffer space was 4000 = 125*32 bytes.
The minimum free count was 117 buffers so there was never danger of a data overrun.