My project is to adjust the sampling rate up to 10k and save data as CSV file to SDcard
Initially I adjusted the sampling rate to 10k and displayed it through the terminal on the arduino. The result of this adjustment was to receive 10K data in 1 second, but when I added the code for Saving data to SDcard, I found that the CSV data in the SDcard saved is only 200-250 data per second. With this problem, I realized later that it was caused by the SDcard's write speed, and would like to ask for advice on how to make the SDcard write 10k of data per second to a file.
The reality is you can't on a consistent basis. The SD card uses the old floppy disk logic and reads and write in blocks of 512 bytes only.
None of the potential ways I can think of will save enough time to help.
Sorry,
Paul
Bad SD cards can take up to 200 ms for a write and SD cards can pause to do flash wear levelling (in this pause they are copying 128K bytes from an frequently used location to a new location. This is slow and happens outside your control.)
So you should have realistic expectations...
How many bytes do you acquire in one sample (in its written SD representation)?
You may want to look at the SdFat library, and in particular at the LowLatencyLogger example. It goes to considerable lengths to get maximum write speed, including setting up and pre-erasing the files on the SD card in advance so writes can take place by writing directly to consecutive sectors, and updating all the file system data only after you're done. It also uses multiple ram buffers to provide for the occasional long write delay. I don't think it can get any faster than this, but the comments at the top of the code only claim 4000 readings per second with a Due.
I suspect your 10,000 readings per second is simply not possible. But I'd suggest you run the example, and see how fast you can make it work with your card and processor. The default sampling rate is once every 2000us, which is 500 Hz, but you can play with that variable and see how fast it will go.
so you want to log in ASCII the Date, the time and the sensed MAX9814 data... so that's likely ~30 bytes worth for one sample, opening and closing the file each time (which you should forget as mentioned by @jremington as a terrible mistake)
at 10KHz that would be close to 300 Kbyte / s
if you look the SdFat library the author says he measured
Shared SPI:
write speed latency
speed max min avg
KB/Sec, µs µs µs
294.45 24944 1398 1737
Dedicated SPI:
write speed latency
speed max min avg
KB/Sec, µs µs µs
3965.11 16733 110 127
If the data are collected at regularly timed intervals, it is not necessary to store the time and date along with each data sample.
You will have to think about how to handle the short delays when the internal SD card buffer is written out. Most people use double buffering to get around that, which is not implemented in the standard SD libraries.
But I agree with other posters, you are not likely to meet the stated timing requirements of this project, unless you are extremely familiar with the hardware and the programming language.
As ShermanP suggests, check out the LowLatencyLogger. Using a Mega2560, I'm logging 32bytes per record every 8ms and can do so for 30 seconds without any dropout. The data is recorded in binary format and post processed into a CSV file after the recording is completed. That's only about 8k of data per second which might no be enough for you.
The LLL needs to have data records padded to 2^^n e.g. record lengths must be 2,4,8,16,32... bytes long. I'm "wasting" 8 bytes as I only need 24 bytes/record but it has to be padded to 32 bytes. That wasted space may be enough for your requirements. It would be a close fit IMOSHO but it might work.
I tried to push the recording rate to 400hz with the Mega board, but the LLL wouldn't have it. You may have to go to a faster processor if you need a higher data rate. I have a reference for a fast data logger using a Teensy3.2 if you need to go that route.
ps: I hope you are not using an Uno as it will not have sufficient ram for the buffering that the LLL requires. I ran into that problem as soon as I tried to add code for reading a gyro/accel sensor. YMMV