Voice recorder: a file is created on Sd card but nothing is recorded.

Hi everyone,

I'm following a tutorial from a man named GreatScott on Instructables. The circuit is composed of a microphone, an sd card reader and an interrupt using the internal pullup resistor of the arduino.

I've modified the code a little bit to match my card and to have some feedback.

When i press the pushbutton, the serial monitor returns that the microphone is recording, then i press it again to stop. When i look on the card, a file of 5,1 Mo has been created, but is completely empty (only zeros on Hex editor). The size changes if i modify the space to pre-allocate in the PCMconfig.h file of the TMRPCM library.

That's very weird because i already recorded sound with the exact same setup and code two weeks ago.
But at that time, the builtin led was on when the system was recording, as it's written on the code.

Here is the code:

#include <SD.h>
#include <SPI.h>
#include <TMRpcm.h>
#define SD_ChipSelectPin 10
TMRpcm audio;
int audiofile = 0;
unsigned long i = 0;
bool recmode = 0;

void setup() {
  pinMode(A0, INPUT);
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(2, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(2), button, LOW);
  SD.begin(SD_ChipSelectPin);
  audio.CSPin = SD_ChipSelectPin;

  Serial.begin(9600);
  Serial.println("Audio recording test. hello");

  if (!SD.begin(SD_ChipSelectPin)) {
    Serial.println("SD BAD :( ");
    return;
  } else {
    Serial.println("SD OK");
  }

}

void loop() {
}

void button() {
  while (i < 300000) {
    i++;
  }
  i = 0;
  if (recmode == 0) {
    recmode = 1;
    audiofile++;
    digitalWrite(LED_BUILTIN, HIGH);
    switch (audiofile) {
      case 1: audio.startRecording("1.wav", 16000, A0); 
      Serial.println ("start recording 1.wav");
      break;
      case 2: audio.startRecording("2.wav", 16000, A0);
      Serial.println ("start recording 2.wav"); break;
      case 3: audio.startRecording("3.wav", 16000, A0); 
      Serial.println ("start recording 3.wav"); break;
      case 4: audio.startRecording("4.wav", 16000, A0); 
      Serial.println ("start recording 4.wav"); break;
      case 5: audio.startRecording("5.wav", 16000, A0);
      Serial.println ("start recording 5.wav"); break;
      case 6: audio.startRecording("6.wav", 16000, A0); 
      Serial.println ("start recording 6.wav"); break;
      case 7: audio.startRecording("7.wav", 16000, A0); 
      Serial.println ("start recording 7.wav"); break;
      case 8: audio.startRecording("8.wav", 16000, A0); 
      Serial.println ("start recording 8.wav"); break;
      case 9: audio.startRecording("9.wav", 16000, A0); 
      Serial.println ("start recording 9.wav"); break;
      case 10: audio.startRecording("10.wav", 16000, A0); 
      Serial.println ("start recording 10.wav"); break;
    }
  }
  else {
    recmode = 0;
    digitalWrite(LED_BUILTIN, LOW);
    switch (audiofile) {
      case 1: audio.stopRecording("1.wav"); 
      Serial.println ("stopped recording 1.wav");
      break;
      case 2: audio.stopRecording("2.wav"); 
      Serial.println ("stopped recording 2.wav"); break;
      case 3: audio.stopRecording("3.wav"); 
      Serial.println ("stopped recording 3.wav"); break;
      case 4: audio.stopRecording("4.wav"); 
      Serial.println ("stopped recording 4.wav"); break;
      case 5: audio.stopRecording("5.wav"); 
      Serial.println ("stopped recording 5.wav"); break;
      case 6: audio.stopRecording("6.wav"); 
       Serial.println ("stopped recording 6.wav"); break;
      case 7: audio.stopRecording("7.wav"); 
      Serial.println ("stopped recording 7.wav"); break;
      case 8: audio.stopRecording("8.wav"); 
      Serial.println ("stopped recording 8.wav"); break;
      case 9: audio.stopRecording("9.wav"); 
      Serial.println ("stopped recording 9.wav"); break;
      case 10: audio.stopRecording("10.wav"); 
      Serial.println ("stopped recording 10.wav"); break;
    }
  }
}

Thanks in advance!

Using an interrupt handler for checking if a button is pressed is overkill.

Trying to run all your business logic inside an ISR is plain demented.

An ISR should be very short (certainly less than a millisecond) and should never
call anything like delay() or Serial which itself relies on interrupts.

So get rid of the attachInterrupt completely, and add this test inside loop():

void loop()
{
  if (digitalRead (2))
    button() ;
}

And in button:

  while (i < 300000) {
    i++;
  }

Is completely pointless as the compiler will optimize it away - if you want a delay, call delay()

Also its plain wrong, a long constant is needed, which is written as 300000L, not 300000. On
the Uno the default integer size is 16 bits so that 300000 means the same as -27680.

BTW you need to use 8.3 filenames, which are all upper-case, I believe.

Hi MarkT, thanks for the reply. As i see, you're always here when needed!

But i'm not sure to understand what you're explaining to me here.

I just tried your suggestion (i removed the attachtointerrupt line and added your code in the loop)
and it's a mess, every file is recorded one after another, and they are still empty 5,1Mo files.

What did i understand wrong?

Note that i added the serial part of the code to debug, but the original project was intended to run without serial communication, on battery (my final goal).

When i try without serial communication, it's even worth, no file at all is created...

Also i must admit that i use this code without understanding everything about it...

But i'm not sure to understand what you're explaining to me here.

well

man named GreatScott on Instructables

What he is saying is that it is very important to know that 99% of what is posted on instructables is crap. Never follow one unless you know more than the author and can spot his mistakes.

Not sure if what I'm gonna say has any influence, but... I find weird you apply digitalWrite() to a pin already occupied by the SPI port.

In ATmega328-based Arduino boards, LED_BUILTIN is also the SCK. If enabling the SPI controller overrides part of any write attempt to port B (pins 8-13 + external oscillator inputs), then digitalWrite() on LED_BUILTIN should have no influcence.

PD: great YouTube channel by the way, I'm suscribed to it already. He called that project the "Spy Bug".

I built this and it works.
You must enable recording in the library, it is written in the github repository but it seems that is not written in the Instructables.
You must use a microphone with MAX9814 or similar chip, red mic modules usually doesn't work.
You will get a lot of noise, especially from the power source if you use a PC USB.