I'm making some experiments using Arduino BLE 33 sense and the microphone. I developed this sample script that aims to store audio data in the SDCard.
#include <Arduino.h>
#include <PDM.h>
#include <SD.h>
// default number of output channels
static const char channels = 1;
// default PCM output frequency
static const int frequency = 16000;
// Buffer to read samples into, each sample is 16-bits
short sampleBuffer[512];
// Number of audio samples read
volatile int samplesRead;
void onPDMdata() {
// Query the number of available bytes
int bytesAvailable = PDM.available();
// Read into the sample buffer
PDM.read(sampleBuffer, bytesAvailable);
// 16-bit, 2 bytes per sample
samplesRead = bytesAvailable / 2;
}
File myFile;
void setup() {
Serial.begin(9600);
while (!Serial);
Serial.print("Initializing SD card...");
// see if the card is present and can be initialized:
if (!SD.begin(4)) {
Serial.println("Card failed, or not present");
// don't do anything more:
while (1);
}
Serial.println("card initialized.");
// open the file. note that only one file can be open at a time,
// so you have to close this one before opening another.
myFile = SD.open("test.txt", FILE_WRITE);
// Configure the data receive callback
PDM.onReceive(onPDMdata);
// Optionally set the gain
// Defaults to 20 on the BLE Sense and 24 on the Portenta Vision Shield
PDM.setGain(15);
// Initialize PDM with:
// - one channel (mono mode)
// - a 16 kHz sample rate for the Arduino Nano 33 BLE Sense
// - a 32 kHz or 64 kHz sample rate for the Arduino Portenta Vision Shield
if (!PDM.begin(channels, frequency)) {
Serial.println("Failed to start PDM!");
while (1);
}
}
bool finished = false;
void loop() {
// // Wait for samples to be read
if (samplesRead) {
// Clear the read count
samplesRead = 0;
myFile.write((uint8_t*)sampleBuffer, sizeof(sampleBuffer));
}
unsigned long now = millis();
if (now / 1000 > 20 && !finished) {
Serial.println(now);
finished = true;
PDM.end();
myFile.close();
}
}
The SDCard is connected to a breadboard using external pull-ups of 47kOhm.
With this script, I noticed I've not enough writing speed in the SDCard to process all the MIC samples. So I would like to hear your suggestions on how can I increase the writing speed in order to don't lose any samples.
I've no experience of the BLE 33 board, but you should check to see what the current SPI clock frequency is and then if you can increased it. This should reduce the time taken to transfer the data to the SD card.
Note that you will likely have to buffer your audio data as the SD card will usually stop accepting data/commands briefly whilst it writes to its internal flash.
What is the measurement period? Continuous? Audio, correct? Audio, you want around 44Khz sample rate, correct? Arduino Uno is limited to about 9.6Khz A BLE sample rate is limited to 35Khz sample rate. I'd not be blaming the SD card not being able to keep up, yet.
I just did that. However, the SDCard is not detected. I'm wondering if I should reduce the resistors on the data lines. Currently, I'm using 47k, which can contribute to increasing the impedance on the line. What do you think?
So now the hunt is on for where the slowness is coming from. I'd also reduce serial prints to minimum and comment out the ones not being used as they slow down the code a slight bit.
Also I'd open the SD card for append instead of write.