SdFat
SdFat copied to clipboard
Problem MicroSD Card Read Timing issue using SdFat.h or sd.h
I'm using an Arduino Uno to read 3 bytes from a MicroSD card connected to the SPI bus as a timing test.
Using a logic analyzer I noticed that it takes about 2msec to read the first byte, and microseconds for the remaining 2 bytes. I've used SdFat.h and sd.h same results.
On the first read I see CS go low followed by a burst of activity on the MISO and MOSI pins, then chip select goes high. After that CS goes high and the other 2 reads show no activity on MISO and MOSI pins and reads happen quickly.
On the first read does the Arduino Uno read in a block of data from the MicroSD card that it buffers up? If so, is there anyway around this? If not would using a NOR flash work?
I need to read in and shift out 9 bytes of data in under 1msec. I can't do this if the first read takes 2msec. Thanks
I don't have time to help with programming.
People write apps to read and play 16 bit quad channel audio from SD cards with SdFat. See this.
I have no idea if what you want to do is easy or impossible on an Uno.
"I need to read in and shift out 9 bytes of data in under 1msec" is not much of a description of your application.
Hi Bill, I'm trying to read in from and shift out 65bits at a time from a file on an MicroSD card in under 2msec. to control a piano. From what I've read and what I'm seeing on the logic analyzer is that MicroSD cards which use NAND flash memoryread in pages/blocks of data at a time. If you read just one byte the SPI program will read a full page/block.which takes longer than 2msec. So it appears that NAND flash won't work. Is that your understanding how NAND flash works? Though, I did run a similar read and shift program on the Raspberry Pi's SD card and it worked fine, but the Pi would interrupt the programoccasionally, so I switched over to the Arduion Uno. I tried increasing the SPI clock using from sd.begin(chipSelect, SPI_HALF_SPEED) to sd.begin(chipSelect, SPI_FULL_SPEED)but I saw no difference in the SPI timing. Not sure why? If I can get the same speed performance that I got from the PI then I can stay withthe MicroSD card. I'm now trying NOR flash which I understand reads/writes one byte at a time. Thanks,Alan
On Monday, November 28, 2022 at 11:56:16 AM PST, Bill Greiman ***@***.***> wrote:
I don't have time to help with programming.
People write apps to read and play 16 bit quad channel audio from SD cards with SdFat. See this.
I have no idea if what you want to do is easy or impossible on an Uno.
"I need to read in and shift out 9 bytes of data in under 1msec" is not much of a description of your application.
— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you authored the thread.Message ID: @.***>
After some more testing I can't seem to increase the SPI clock above 250khz. I've tried sd.begin(10);SPI.beginTransaction(SPISettings(4000000, MSBFIRST, SPI_MODE0));
orsd.begin(chipSelect, SPI_FULL_SPEED)
and other commands. What should I use after sd.begin(10); to get the max spi clock speed for a Arduino Uno Many thanksAlan
On Monday, November 28, 2022 at 02:41:48 PM PST, ***@***.*** ***@***.***> wrote:
Hi Bill, I'm trying to read in from and shift out 65bits at a time from a file on an MicroSD card in under 2msec. to control a piano. From what I've read and what I'm seeing on the logic analyzer is that MicroSD cards which use NAND flash memoryread in pages/blocks of data at a time. If you read just one byte the SPI program will read a full page/block.which takes longer than 2msec. So it appears that NAND flash won't work. Is that your understanding how NAND flash works? Though, I did run a similar read and shift program on the Raspberry Pi's SD card and it worked fine, but the Pi would interrupt the programoccasionally, so I switched over to the Arduion Uno. I tried increasing the SPI clock using from sd.begin(chipSelect, SPI_HALF_SPEED) to sd.begin(chipSelect, SPI_FULL_SPEED)but I saw no difference in the SPI timing. Not sure why? If I can get the same speed performance that I got from the PI then I can stay withthe MicroSD card. I'm now trying NOR flash which I understand reads/writes one byte at a time. Thanks,Alan
On Monday, November 28, 2022 at 11:56:16 AM PST, Bill Greiman ***@***.***> wrote:
I don't have time to help with programming.
People write apps to read and play 16 bit quad channel audio from SD cards with SdFat. See this.
I have no idea if what you want to do is easy or impossible on an Uno.
"I need to read in and shift out 9 bytes of data in under 1msec" is not much of a description of your application.
— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you authored the thread.Message ID: @.***>
SD cards init at 200-400KHz. sd.begin(CS_PIN) will switch to the highest SPI speed supported by the board that is less or equal to 50MHz. For Uno that is 8 MHz.
See the bench example, this explicitly selects 50MHz. On an Uno the result is:
read speed and latency
speed,max,min,avg
KB/Sec,usec,usec,usec
667.56,772,756,761
667.47,772,756,761
So you need to shift out the bits in a timer interrupt routine and read/buffer data in a loop for the interrupt routine. You only need to read about 9 KB/sec and Uno can do over 600 KB/sec so most of the time could be in the interrupt routine.
You need 65 K bits/sec so you could send one bit per timer interrupt which would leave plenty of time for reading from the SD in the background.
I would use something other than digitalWrite, it is slow. I did a library, DigitalIO, for things like this. I did SoftwareSPI and SoftwareI2C. These are not interrupt driven but I have used the DigitalIO routines in interrupt code.
Hi Bill,Sorry I didn't get back to you right away. As a Hardware Engineer by trade reading and understanding code is like learning a foreign language.I ran your bench test and it reported the same results with a clock speed of 8.33mhz., outputting a byte every 1.38usec. It takes about 450usec from the initiation of a read cycle to receiving the data.
So you are absolutely correct there should be more than enough time to read and shift out the data.Now I just need to implement your ideas using portions of your bench program to get the results that I need. Many thanks for your help,Alan
On Tuesday, November 29, 2022 at 06:23:55 AM PST, Bill Greiman ***@***.***> wrote:
SD cards init at 200-400KHz. sd.begin(CS_PIN) will switch to the highest SPI speed supported by the board that is less of equal to 50MHz. For Uno that is 8 MHz.
See the bench example, this explicitly selects 50MHz. On an Uno the result is: read speed and latency speed,max,min,avg KB/Sec,usec,usec,usec 667.56,772,756,761 667.47,772,756,761
So you need to shift out the bits in a timer interrupt routine and read/buffer data in a loop for the interrupt routine. You only need to read about 9 KB/sec and Uno can do over 600 KB/sec so most of the time could be in the interrupt routine.
You need 65 K bits/sec so you could send one bit per timer interrupt which would leave plenty of time for reading from the SD in the background.
I would use something other than digitalWrite, it is slow. I did a library, DigitalIO, for things like this. I did SoftwareSPI and SoftwareI2C. These are not interrupt driven but I have used the DigitalIO routines in interrupt code.
— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you authored the thread.Message ID: @.***>
Hi Bill, I have an SD card with a text file called SONGS.txt. The file contains a vertical list of songs.I want to read in one full line into a buffer and then take action on it. Then read in the next full line and take action on it. etc. Is there a simple SdFat.h command like String list = myFile.readStringUntil('\r'); that I can use withoutcreating creating a while loop, reading in one character at a time while testing for \r ? Thanks,Alan On Wednesday, November 30, 2022 at 09:30:15 PM PST, @.*** @.***> wrote:
Hi Bill,Sorry I didn't get back to you right away. As a Hardware Engineer by trade reading and understanding code is like learning a foreign language.I ran your bench test and it reported the same results with a clock speed of 8.33mhz., outputting a byte every 1.38usec. It takes about 450usec from the initiation of a read cycle to receiving the data.
So you are absolutely correct there should be more than enough time to read and shift out the data.Now I just need to implement your ideas using portions of your bench program to get the results that I need. Many thanks for your help,Alan
On Tuesday, November 29, 2022 at 06:23:55 AM PST, Bill Greiman ***@***.***> wrote:
SD cards init at 200-400KHz. sd.begin(CS_PIN) will switch to the highest SPI speed supported by the board that is less of equal to 50MHz. For Uno that is 8 MHz.
See the bench example, this explicitly selects 50MHz. On an Uno the result is: read speed and latency speed,max,min,avg KB/Sec,usec,usec,usec 667.56,772,756,761 667.47,772,756,761
So you need to shift out the bits in a timer interrupt routine and read/buffer data in a loop for the interrupt routine. You only need to read about 9 KB/sec and Uno can do over 600 KB/sec so most of the time could be in the interrupt routine.
You need 65 K bits/sec so you could send one bit per timer interrupt which would leave plenty of time for reading from the SD in the background.
I would use something other than digitalWrite, it is slow. I did a library, DigitalIO, for things like this. I did SoftwareSPI and SoftwareI2C. These are not interrupt driven but I have used the DigitalIO routines in interrupt code.
— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you authored the thread.Message ID: @.***>