SD card intermittant timing read?

Austin2

Member
Hi all,

Found a weird issue and am wondering what folks think. I'm reading values from the SD card out of a single file. The file is a text file containing simply:
16 bit int # + \n
16 bit int # + \n

so I read values from the card, and set those values to an analog output.
Normally the read operation in it's entirety takes 7-8us (awesome!), but, once in every ~ 171 reads, the system requires ~ 200us to return it's value.
I've tested multiple SD cards and it seems that the faster card will run @ 180-200us or so, where the slow cards are 2x that speed (7-8us on normal reads, 400us on this delay interval read).
So - AFAIKT this is some buffer issue on the card or something? Only other issue is it may be the readstringuntil function?

Just curious if someone had an obvious answer - my next approach will be trying a char read and then possibly playing with a buffer of some kind on the read. Ultimately this function produces an arbitrary waveform - so right now I have shelves in the form and am seeking to eliminate those.
I'd note that I HAVE isolated the delay to this read - all other functions run consistently - so the delay is in this chunk of code for sure.


Here is the serial output on the monitor:
Where line # = the current read line from the card, val = the 16 bit int number read in, D = the micros() delay in reading the value.

Line#: 1, val: 33715, D: 200
Line#: 25, val: 33581, D: 5
Line#: 49, val: 33447, D: 5
Line#: 73, val: 33313, D: 5
Line#: 97, val: 33179, D: 5
Line#: 121, val: 33045, D: 5
Line#: 145, val: 32911, D: 5
Line#: 169, val: 32777, D: 5
Line#: 171, val: 32766, D: 182
Line#: 195, val: 32632, D: 5
Line#: 219, val: 32498, D: 5
Line#: 243, val: 32364, D: 5
Line#: 267, val: 32230, D: 5
Line#: 291, val: 32096, D: 5
Line#: 315, val: 31962, D: 5
Line#: 339, val: 31828, D: 5
Line#: 341, val: 31817, D: 182
Line#: 365, val: 31683, D: 5
Line#: 389, val: 31549, D: 5
Line#: 413, val: 31415, D: 5
Line#: 437, val: 31281, D: 5
Line#: 461, val: 31147, D: 5
Line#: 485, val: 31013, D: 6
Line#: 513, val: 30857, D: 182
Line#: 537, val: 30723, D: 5
Line#: 561, val: 30589, D: 5
Line#: 585, val: 30455, D: 5
Line#: 609, val: 30321, D: 5
Line#: 633, val: 30187, D: 5
Line#: 657, val: 30053, D: 5
Line#: 681, val: 29919, D: 5
Line#: 683, val: 29908, D: 182
Line#: 707, val: 29796, D: 5
Line#: 731, val: 29919, D: 5
Line#: 755, val: 30053, D: 5
Line#: 779, val: 30187, D: 5
Line#: 803, val: 30321, D: 5
Line#: 827, val: 30455, D: 5
Line#: 851, val: 30589, D: 5
Line#: 853, val: 30600, D: 182

etc....

HTML:
//Serial.println(millis() -e);
          unsigned long ms = micros();
          String v = df[0].readStringUntil('\n');
          currentval = currentval+1;
         if((micros()-ms) >3   ){
      Serial.print("Line#: "); Serial.print(currentval); Serial.print(", val: "); Serial.print(v);  Serial.print(", D: "); Serial.println(micros()-ms );
 
My guess is that it is needing to read in the next sector from the SD card.

That is storage on SD cards or stored in sectors of clusters... The size of each depends on how much storage is on the SD card (or partition) and what file system (fat16, fat32, exfat).

From your observations you were saying it is about every 171 reads.

So looking at your data it looks like most of the time your values take 5 bytes plus cr so 6 bytes per record:
so 171*6 = 1026...

So my guess is the sector size is 1024 on your SD card.
 
My guess is that it is needing to read in the next sector from the SD card.

That is storage on SD cards or stored in sectors of clusters... The size of each depends on how much storage is on the SD card (or partition) and what file system (fat16, fat32, exfat).

From your observations you were saying it is about every 171 reads.

So looking at your data it looks like most of the time your values take 5 bytes plus cr so 6 bytes per record:
so 171*6 = 1026...

So my guess is the sector size is 1024 on your SD card.

Ah! this makes a lot of sense.
So My next ignorant question would be - any way to avoid the sector-sector read delay?
I was considering the possibility of reading in batches - problem is, of course, i'm trying to keep the overall output timing of the function as tight as possible, so the only option I can see for this would be to buffer read the input and provide, say, a 20us while wait to smooth things out on the setting of the value.

-AB
 
Back
Top