SD card write is very slow in Arduino Due

Hi,

I need to store some ADC samples in the SD card using the wav file format, to get started, I’m only trying to write the header of the file and some sinewave samples, sampled at 44100 Hz, the problem is the time it takes, for the header it takes about 1 second (to write 36 bytes), for 60 seconds of samples it takes more than 1 minute (to write 10584000 bytes).
There is any way to write the wav file faster?
I need to write the wav file to the SD card with samples from the ADC almost in “real time”, using a 4 KB or 8 KB RAM buffer, due to the length of the files.
In those sketches the samples writting function is commented.

Hope someone can help me,
I’ve tried both SD.h and SdFat.h libraries and the times are similar.

Regards,
Danny

recordSineWave.ino (11 KB)

recordSineWaveSdFat.ino (11.1 KB)

I'm not a specialist, but I have my doubts.

When writing to SD card, buffering is involved; as far as I know, you can write 512 bytes to the 'buffer' after which the buffer is written to the card. That is where you're delays start showing up.

10 MegaBytes is a hell of a lot.

When writing to SD card, buffering is involved; as far as I know, you can write 512 bytes to the 'buffer' after which the buffer is written to the card. That is where you're delays start showing up.

Makes meaningful sense when we look into the following internal structure of the SD Memory Card. |225x500 Figure-1: Internal structure of SD Memory Card

I just saw this thread. No idea if and how it works.

Hi,

Using the SdFat library and 2 buffers, one for the 44 bytes header, and one with 100 ms of samples.
I’ve managed to reduce the total write time of 10.1 MiB to about 21-22 seconds, that’s a rate in excess of 0.4 MiB/second, I don’t know if it’s good or bad, but it definitely improved. I was able to write a file with a 100 Hz sinewave sampled at 44100 Hz, with 2 channels. I don’t know if this byte rate is good enough to use with the ADC, and what is the maximum sampling rate. I need to perform some more tests.

Regards,
Danny

recordSineWaveSdFatBuffer.ino (14.4 KB)

Hi,

I’ve tried to change the code to use the Due as data logger using the SD card and the internal ADC, but I only get lots of noise on channel 2 and a strange, high level signal on channel 1. What Am I doing wrong? I’ve tested with a sample rate of 8 kHz and only 2 seconds of sampling time, using an audio signal.

Regards,
Danny

adcRecordSdFatBuffer.ino (18.4 KB)

Hi,

I’m trying to make a data logger to read ECG signals at sample rate of up to 44100 Hz, it should use the internal ADC, and maybe later an external SPI ADC, and it should write an wav file to an SD card. I’m using the code attached, to sample at a rate of 8000 S/s using 2 channels. But the file generated only has lots of noise on channel 2 and a strange high voltage signal on channel 1, I’m currently using an audio signal, at the DAC input using a 1uF capacitor and a resistor in series, since currently I don’t have an ECG signal generator. What Am I doing wrong?

Regards,
Danny

adcRecordSdFatBuffer.ino (18.4 KB)

Hi everyone,

I want to know if it’s possible to record a wav file with Arduino Due using the two channels of the ADC, I would like to achieve a sample rate of up to 44100 Hz, but I don’t know if it’s possible. My sketch is not working properly, I think it is due to the slow SD writing bitrate. Could someone help me here?

Best regards,
Danny

adcRecordSdFatBuffer.ino (18.3 KB)

An Arduino is a microcontroller. If you want to record audio, it's better to use a dedicated audio recorder.

Yes, it's possible. But only if you add the right circuits to translate ECG signals into ADC values. And don't forget to connect the grounds...

I've never used the Due, but I'd suggest you do an experiment. Start a timer and write a megabyte or so to the SD card to see how fast you can do it.

If that looks promising, try software-generating a "WAV" and try writing it to the SD card at exactly 44,100Hz. (With 16-bit stereo, that's 176,400 bytes per second).

BTW - 44.1kHz is the sample rate, not the bit rate. A "CD quality" WAV file has a bitrate of 1411kbps.

And remember to design in enough RAM / EEPROM to save your samples

+1 lastchancename

See this thread reply #1:

http://forum.arduino.cc/index.php?topic=323421.0

If you sample for a relatively long time, move firstly your ADC samples to an EEPROM (or DUEFlashStorage lib), then into an SD card. AFAIK the maximum speed for writing into an SD card is ~ 120 K Bytes ps

@danny92, please do not cross-post. Threads merged.

Ditto.

44.1 kHz is a ridiculously high sampling rate for ECG signals. E.g. the records in the MIT-BIH Arrhythmia database are all sampled at 360 Hz. In a more recent report, the American Heart Association recommends 500 Hz. For some advanced high-frequency detections, you need higher frequencies, 10,000 Hz or even 15,000 Hz, but that's a very specialized application, and still less than 44.1 kHz.

PieterP: 44.1 kHz is a ridiculously high sampling rate for ECG signals. E.g. the records in the MIT-BIH Arrhythmia database are all sampled at 360 Hz. In a more recent report, the American Heart Association recommends 500 Hz. For some advanced high-frequency detections, you need higher frequencies, 10,000 Hz or even 15,000 Hz, but that's a very specialized application, and still less than 44.1 kHz.

Yes, I think you're right, maybe 10,000 Hz would suffice, or a bit less, this is for a test equipment that needs to capture the effects of interference up to about 1000-2000 Hz. By the Nyquist-Shannon sampling theorem I think something between 2000-4000 Hz could be enough. I need to perform some more tests. I think we are talking about a byte rate of about 8000-16000 bytes/s (two channels) or 4000-8000 bytes/s (one channel). I think the SD card can write at speeds of up to 100 kB/s using SPI interface but I'm not 100% sure.

danny92: the problem is the time it takes, for the header it takes about 1 second (to write 36 bytes)

1 second to write only 36 bytes ..... yep...something definitely wrong there.

Did the result from your sketch code say 1000 millisecond? Or did it say 1 millisecond?

Southpark:
1 second to write only 36 bytes … yep…something definitely wrong there.

Did the result from your sketch code say 1000 millisecond? Or did it say 1 millisecond?

Greetings,

It says about 700-800 milliseconds! An average of about 750 milliseconds! To write 44 bytes!

I’ve made some changes to the code and the average sampled ADC value seems ok (near Vcc/2). But there are some strange peaks, that resemble a sinc function, those peaks coincide with SD card activity (when Arduino is writting to the card). I’m sampling at 1000 S/s, one ADC channel.

Best regards,
Danny

adcRecordSdFatBuffer.ino (20.8 KB)