Sample rate 10k for Arduino Uno using sdfat library

Greetings,

I am trying to sample with my Arduino Uno about 10 ksps from a microphone. I have downloaded the sdfat library and I am trying to save on sd card the data from the microphone. Currently I can sample about 4ksps, but I need more to satisfy the Niquist theorem. I want to ask kindly, if there is another method to sample about 10ksps with my Arduino Uno, I have read in another posts I could save my data in .bin file instead of .txt file, could this method solve my problem(I don’t have try it, because I am bit newbee in programming)?

Thank you in advance

Code

//SD_CS_PIN 10

#include <SPI.h>
#include “SdFat.h”
#include “sdios.h”
#define SD_CS_PIN 10
ArduinoOutStream cout(Serial);
SdFat SD;
File myFile;
const char* NameOfTheFile = “Sound1000ms_v5.txt”;
long Period = 1000, StartTime;

void setup() {
Serial.begin(115200);
if (!SD.begin(SD_CS_PIN, SPI_FULL_SPEED)){
Serial.println(“initialization failed!”);
return;}

byte PS_128 = (1 << ADPS1) | (1 << ADPS0) | (1 << ADPS2);
ADCSRA &= ~PS_128;
ADCSRA |= (1 << ADPS1) ;

void loop() {

do{
delay(10);
}while (Serial.available() && Serial.read() >= 0);

cout << F(“Type any character to start\n”);
while (!Serial.available()) {
SysCall::yield();}
//////////////////////////////////////////////////////////////////////////
/////////////////////////////////WRITE DATA///////////////////////////
myFile.open(NameOfTheFile, O_RDWR | O_CREAT | O_TRUNC);
if (myFile) {
StartTime = millis();
do{
myFile.println((analogRead(A0)));
}while(millis() - StartTime <= Period);

myFile.flush();
myFile.close();
Serial.println(“done.”);
}else{
Serial.println(“error opening the File”);}

//////Just pause for now/////
delay(20000);
}

My sd card is SanDisk Ultra micro SD, HC1, Fortmat: fat32

georgekasa:
I have read in another posts I could save my data in .bin file instead of .txt file, could this method solve my problem

I have tried it both ways before, but you will never be able to get those sort of sample speeds while using the SDFAT library. The main reason for this is because you'll get periodic blocking delays in your code due to how the SDFAT library buffers and writes data to the SD card. I've had blocking delays of up to 200ms waiting for the SDFAT library to do it's thing.

My suggestion would be for you to do the data logging on a PC - you just have to have some program on your PC that can decode the data, create a text file, and save the data to said text file. Python would be perfect for this.

Power_Broker thank you for your reply, unfortunately I don't have the luxury to read the data from a PC, because the aim of this mini project would leave the arduino to "work" in nature.

Even if you did NOTHING but continuous analogReads, I'm not sure you'd hit 10K/second. Each analogRead takes roughly 100uSec, unless you reduce the resolution. below 10 bits.

Regards,
Ray L.

There is a method to read from SD-card with high sample rates:

https://www.hackerspace-ffm.de/wiki/index.php?title=SimpleSDAudio

Some features:

8-Bit PWM output - no external DAC required
16-Bit emulation using 2x 8-Bit PWM output - requires only two resistors
62.500 kHz (fullrate) / 31.250 kHz (halfrate) sampling rate @ 16 MHz
31.250 kHz (fullrate) / 15.625 kHz (halfrate) sampling rate @ 8 Mhz
PWM output is operating always at fullrate for easier filtering
Mono, bridge and stereo mode
Integrated SD library (minimal FAT only, optimized for low RAM usage and high performance)

I guess that writing on SD card will be somewhat slowlier, but it's woth to try.

SupArdu Thank you very much for the link.

SupArdu:
There is a method to read from SD-card with high sample rates:

SimpleSDAudio – Hackerspace Ffm

Some features:
I guess that writing on SD card will be somewhat slowlier, but it's woth to try.

Nope, this library is only for playback, not datalogging

Still really cool find tho :wink:

Saving data in binary has several benefits. First, every value is exactly 2 bytes. In ASCII, values can be 3, 4, 5, or 6 bytes (because analogRead() returns numbers from 0 to 1023, and println() adds a carriage return and line feed). Second, print() needs to convert the value to a string, to write in ASCII format. Writing in binary skips that step.

However, sine the analogRead() takes 104 uS, you'd still be very hard pressed to achieve your desired smaple rate with a Uno.

A Teensy would be a better choice - faster processor and faster analog to digital converter, and no more expensive than an Arduino, and it can be programmed like an Arduino. Have a look at some of the projects on the pjrc.com site, dealing with audio.

PaulS:
A Teensy would be a better choice - faster processor and faster analog to digital converter, and no more expensive than an Arduino, and it can be programmed like an Arduino. Have a look at some of the projects on the pjrc.com site, dealing with audio.

Yeah, even with sampling at 16bits precision and not doing anything extra fancy in terms of optimization, I've been able to sample at around 20KHz with a Teensy 3.5.

That being said - the SD card can still easily ruin your sample rate by introducing 10-200ms lag spikes periodically