Hello, using the library SD.h for ESP32 (I'm on an ESP32S3), I want to open a file on an SD card as read/write so I can do both without closing and reopening the file, which takes ages. I tried using the flags O_RDWR | O_APPEND but open() only accepts char*, so I have to use open("/file.txt", "a")
. I tried using SdFat.h but it doesn't work, the SD card isn't recognized. I tried using the latest file from here and initializing the card using SD.begin(SdSpiConfig(CS, USER_SPI_BEGIN, 40000000))
but it still doesn't work. SPI was already initialized before with SPI.begin(SCLK, MISO, MOSI, CS)
. How can I achieve it?
Please provide a link to the library documentation.
Always run the Espressif test code for SD:
arduino-esp32/libraries/SD/examples/SD_Test at master · espressif/arduino-esp32 · GitHub
Perhaps using the ESP32's SPI API which has duplex mode and makes use of 'low level' access to the ESP32's SPI bus driver
I don't want to read and write at the same time at the SPI level, I want to be able to read and write from a file without having to open it with FILE_READ and then FILE_APPEND, because it takes a lot of time. I think it has to do with the library, because there isn't any flag that lets me open a file with the RDWR attribute. Maybe it wasn't very clear.
The code works fine and there isn't any problem in opening the SD card or recognizing it. The problem is that I want to read and write from a file without having to open and close it twice, with the flags FILE_READ and FILE_APPEND. I want to use something like O_RDWR | O_APPEND
that is possible in the SdFat
library.
When I use SdFat
, though, I can't get the SD card to initialize because apparently there isn't any supported way to use the SPI bus with custom pins. I've already tried calling SD.begin
with this configuration: SdSpiConfig(CS, USER_SPI_BEGIN, 40000000)
, as shown here but it just doesn't work.
You can download the zip file here extract it and open index.html in the doc folder.
I believe that "we" sometimes forget that the ESP32 w/Arduino is running FreeRTOS and that there are lots of stuff happening in the background.
[SOLVED] Question about reading and writing to the same sd card simultaneously - ESP32 Forum
lbernstone wrote: ↑
Thu Jan 19, 2023 4:31 pmThere's not really any benefit to having this simultaneous, since there is only one pipeline to the hardware, and lots of downside. So, rather than shoehorning into "simultaneous", work on making the process asynchronous, and then put a mutex on the sd access. This means you need to have a storage buffer for your incoming data that is big enough to handle any possible delays, and a process for writing what may be more than 8 pieces of data. A mutex example will be added to the core soon- https://github.com/espressif/arduino-es ... c48b78a5d0
Another way to handle this, if data collection is the primary function of the device, would be to drop the extra $0.25 and get an esp32 with psram. This gives you an extra 4MB of data space to work with, so you could easily keep the whole "file" as a string in active memory, write it out to flash periodically, and deliver it to your permanent storage as needed. You can see an example of this methodology at https://github.com/lbernstone/rrdtool_E ... sramDB.ino
Hello, at the end I used another approach to my problem, removing the need of writing and reading at the same time. There is another problem now, though. Let's say I have this loop:
uint8_t buf[15];
for (int i = 0; i < 104; i++)
{
mapfile.seek(i * 1500);
mapfile.read(buf, 15);
}
it reads 15 bytes every 1500 bytes. When seeking at a far position, for example 154500, or 22500, the read fails. If you put Serial.printf("%d\n", mapfile.position())
after mapfile.seek(i * 1500)
, you'd see -1 in the serial console. Now if you use this loop:
uint8_t buf[15];
for (int i = 0; i < 156000; i++)
{
mapfile.seek(i);
mapfile.read(buf, 15);
}
it just works. I really don't understand what's going on.
Yea for just works. I'm on a Surface tablet, so cannot play around at this time, but the compiler is likely optimizing or casting something differently than expected. Glad it is working.
Interesting explanation. Do you have any idea how I can prevent this from happening? Yes the second loop is working, but it's not what I need because I have to be able to read from any position without worrying about this problem. Oh and when the weird behavior happens, so when mapfile.position()
returns -1, the SD card doesn't work anymore and I have to reset it by removing and putting it back into the SD card reader.
Maybe try...
for (unsigned long i = 0; i < 104; i++)
We need to be cautious with int as it is defined as 16-bit on AVR 8-bit platforms and as 32-bit on Espressif and other 32-bit architecture... creates a havoc for folk trying to make code portable.
Parameters
file
: an instance of the File class (returned by SD.open()).pos
: the position to which to seek (unsigned long).
Using unsigned long
it stops reading correctly at position 106515. Maybe the SD is somehow corrupted or something isn't right with it? I'll try formatting it, it's a 16 GB SD.
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.