0

Good evening,

I am using an Atmega32 (2kB RAM) at 14.7456MHz to log data to a SD card via SPI that runs at ~1.5MHz.

FatFs is set to FF_FS_TINY 0 (0 or 1 doesn't seem to influence the write speed as far as I could observe)

The data I want to log contains of: 5 Chars as name, 6 byte for date and time, 2 uint (16bit) for values

The date and time is stored in a byte array and the name and values are from a struct variable.

The goal is to sample data each millisecond from 8 inputs, so 8kSPS. The main program triggers an interrupt each millisecond and sets a flag. In the main loop, if the flag is 1, the ADCs are read and the values are stored in a struct variable. (Each ADC channel has a seperate one.)

For testing purposes, I tried to write a 8 samples with static values every 10ms for one second using f_printf. (Or should one rather use f_write?)

int i=0;
xprintf(PSTR("1 %d\n"), Timer*10 );
for (;;) {
    if(ISRFlag&&i<100){
    xprintf(PSTR("2 %d\n"), Timer*10 );
    f_printf(&file1, "%s %d %d %d %d %d %d %d %d %d \n",Name, i, day, mon, year, hour, minute, second, value1, value2);
    [... 7 more times f_printf]     
    ISRFlag=0;
    i++;
    }
    if(i==100){
    xprintf(PSTR("3 %d\n"), Timer*10 ); 
    xprintf(PSTR("f_sync1 rc=%d\n"), f_sync(&file1) );
    f_close(&file1);                        
    xprintf(PSTR("Timer end%d\n"), Timer*10 );
    i++;
    }
}

I tried this with two SD cards and with one this took ~1500ms and with the other one it took ~2100ms.

Since this takes too long, I wonder what strategies there are to make the write process more efficient or how to do it in general. I read that you should somehow align the card sectors but I don't know how this would be done. Others suggest using a Fifo buffer for situations when the card takes longer than usual, afaik this would mean another struct to combine the byte array for the time and the struct values from each datapoint.

Are there recommended ways on how tackle this? I often read that this has been done many times before, but somehow I couldn't find good examples so far. Maybe I am just looking at the wrong spots.

Winter
  • 23
  • 4

2 Answers2

0

I had similar issues while logging data to an SD-Card. First check your write(disk_write/xmit_datablock) operation in the low level disk I/O layer(diskio.c/mmc.c). If you used the given examples provided by FatFs they often have a preprogrammed delay in it, which isnt neccessary. If you use Hardware-SPI think about switching to Software-SPI and write your own routine for the used SPI-Mode.

keko
  • 37
  • 10
  • I followed that trail and there is indeed a !wait_ready(500) in each f_write->disk_write->xmit_datablock which would be a 500ms delay ? But from my experiments where I sent, for example, 8192*32byte, so 512*512byte buffers, wouldn't I get a 500ms delay every 512 bytes written? Yet I had a time of around 3300ms for the whole process. – Winter Oct 20 '17 at 22:34
0

If your only goal is to stream samples to SD card then you can consider not using file system at all. Simply write samples straight into SD. If you need append data, you could keep some header structure at the beginning of SDcard memory, with address of tail where to continue writing etc. Surely this comes at cost of extra software (to read data from SD later on e.g. on computer) yet on MCU side you could get utmost speed with serial interface to SD.

andy
  • 757
  • 5
  • 13