Teensy 3.2 & Audio Shield Record to SD

Ceiling

Member
Hey All-

I've been trying to use the recorder example sketch to validate recording to an SD card with a Teensy 3.2 and the audio shield's line in. The SD card reads fine with the CardInfo sketch but the Teensy never records to the SD card. I've tried reformatting the SD card but had no luck. At this point I'm thinking I should try a whole new SD card.

Anyone ever have similar issues with the Recorder example sketch not writing to the SD card

Code:
// Record sound as raw data to a SD card, and play it back.
//
// Requires the audio shield:
//   http://www.pjrc.com/store/teensy3_audio.html
//
// Three pushbuttons need to be connected:
//   Record Button: pin 0 to GND
//   Stop Button:   pin 1 to GND
//   Play Button:   pin 2 to GND
//
// This example code is in the public domain.

#include <Bounce.h>
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

// GUItool: begin automatically generated code
AudioInputI2S            i2s2;           //xy=105,63
AudioAnalyzePeak         peak1;          //xy=278,108
AudioRecordQueue         queue1;         //xy=281,63
AudioPlaySdRaw           playRaw1;       //xy=302,157
AudioOutputI2S           i2s1;           //xy=470,120
AudioConnection          patchCord1(i2s2, 0, queue1, 0);
AudioConnection          patchCord2(i2s2, 0, peak1, 0);
AudioConnection          patchCord3(playRaw1, 0, i2s1, 0);
AudioConnection          patchCord4(playRaw1, 0, i2s1, 1);
AudioControlSGTL5000     sgtl5000_1;     //xy=265,212
// GUItool: end automatically generated code

// For a stereo recording version, see this forum thread:
// https://forum.pjrc.com/threads/46150?p=158388&viewfull=1#post158388

// A much more advanced sound recording and data logging project:
// https://github.com/WMXZ-EU/microSoundRecorder
// https://github.com/WMXZ-EU/microSoundRecorder/wiki/Hardware-setup
// https://forum.pjrc.com/threads/52175?p=185386&viewfull=1#post185386

// Bounce objects to easily and reliably read the buttons
Bounce buttonRecord = Bounce(0, 8);
Bounce buttonStop =   Bounce(1, 8);  // 8 = 8 ms debounce time
Bounce buttonPlay =   Bounce(2, 8);


// which input on the audio shield will be used?
const int myInput = AUDIO_INPUT_LINEIN;
//const int myInput = AUDIO_INPUT_MIC;


// Use these with the Teensy Audio Shield
#define SDCARD_CS_PIN    10
#define SDCARD_MOSI_PIN  7
#define SDCARD_SCK_PIN   14

// Use these with the Teensy 3.5 & 3.6 SD card
//#define SDCARD_CS_PIN    BUILTIN_SDCARD
//#define SDCARD_MOSI_PIN  11  // not actually used
//#define SDCARD_SCK_PIN   13  // not actually used

// Use these for the SD+Wiz820 or other adaptors
//#define SDCARD_CS_PIN    4
//#define SDCARD_MOSI_PIN  11
//#define SDCARD_SCK_PIN   13


// Remember which mode we're doing
int mode = 0;  // 0=stopped, 1=recording, 2=playing

// The file where data is recorded
File frec;

void setup() {
  // Configure the pushbutton pins
  pinMode(0, INPUT_PULLUP);
  pinMode(1, INPUT_PULLUP);
  pinMode(2, INPUT_PULLUP);

  // Audio connections require memory, and the record queue
  // uses this memory to buffer incoming audio.
  AudioMemory(60);

  // Enable the audio shield, select input, and enable output
  sgtl5000_1.enable();
  sgtl5000_1.inputSelect(myInput);
  sgtl5000_1.volume(0.5);

  // Initialize the SD card
  SPI.setMOSI(SDCARD_MOSI_PIN);
  SPI.setSCK(SDCARD_SCK_PIN);
  if (!(SD.begin(SDCARD_CS_PIN))) {
    // stop here if no SD card, but print a message
    while (1) {
      Serial.println("Unable to access the SD card");
      delay(500);
    }
  }
}


void loop() {
  // First, read the buttons
  buttonRecord.update();
  buttonStop.update();
  buttonPlay.update();

  // Respond to button presses
  if (buttonRecord.fallingEdge()) {
    Serial.println("Record Button Press");
    if (mode == 2) stopPlaying();
    if (mode == 0) startRecording();
  }
  if (buttonStop.fallingEdge()) {
    Serial.println("Stop Button Press");
    if (mode == 1) stopRecording();
    if (mode == 2) stopPlaying();
  }
  if (buttonPlay.fallingEdge()) {
    Serial.println("Play Button Press");
    if (mode == 1) stopRecording();
    if (mode == 0) startPlaying();
  }

  // If we're playing or recording, carry on...
  if (mode == 1) {
    continueRecording();
  }
  if (mode == 2) {
    continuePlaying();
  }

  // when using a microphone, continuously adjust gain
  if (myInput == AUDIO_INPUT_MIC) adjustMicLevel();
}


void startRecording() {
  Serial.println("startRecording");
  if (SD.exists("RECORD.RAW")) {
    // The SD library writes new data to the end of the
    // file, so to start a new recording, the old file
    // must be deleted before new data is written.
    SD.remove("RECORD.RAW");
  }
  frec = SD.open("RECORD.RAW", FILE_WRITE);
  if (frec) {
    queue1.begin();
    mode = 1;
  }
}

void continueRecording() {
  if (queue1.available() >= 2) {
    byte buffer[512];
    // Fetch 2 blocks from the audio library and copy
    // into a 512 byte buffer.  The Arduino SD library
    // is most efficient when full 512 byte sector size
    // writes are used.
    memcpy(buffer, queue1.readBuffer(), 256);
    queue1.freeBuffer();
    memcpy(buffer+256, queue1.readBuffer(), 256);
    queue1.freeBuffer();
    // write all 512 bytes to the SD card
    //elapsedMicros usec = 0;
    frec.write(buffer, 512);
    // Uncomment these lines to see how long SD writes
    // are taking.  A pair of audio blocks arrives every
    // 5802 microseconds, so hopefully most of the writes
    // take well under 5802 us.  Some will take more, as
    // the SD library also must write to the FAT tables
    // and the SD card controller manages media erase and
    // wear leveling.  The queue1 object can buffer
    // approximately 301700 us of audio, to allow time
    // for occasional high SD card latency, as long as
    // the average write time is under 5802 us.
    //Serial.print("SD write, us=");
    //Serial.println(usec);
  }
}

void stopRecording() {
  Serial.println("stopRecording");
  queue1.end();
  if (mode == 1) {
    while (queue1.available() > 0) {
      frec.write((byte*)queue1.readBuffer(), 256);
      queue1.freeBuffer();
    }
    frec.close();
  }
  mode = 0;
}


void startPlaying() {
  Serial.println("startPlaying");
  playRaw1.play("RECORD.RAW");
  mode = 2;
}

void continuePlaying() {
  if (!playRaw1.isPlaying()) {
    playRaw1.stop();
    mode = 0;
  }
}

void stopPlaying() {
  Serial.println("stopPlaying");
  if (mode == 2) playRaw1.stop();
  mode = 0;
}

void adjustMicLevel() {
  // TODO: read the peak1 object and adjust sgtl5000_1.micGain()
  // if anyone gets this working, please submit a github pull request :-)
}
 
QMHL9tb.jpg


4QNRcwb.png


Here are some pictures of the setup. It reads all of the inputs fine but doesn't seem like it's writing anything to the SD card. With the the code to time SD writes uncommented I don't see anything on the serial monitor. I'm not sure why it wouldn't be writing to the SD card.

I'm using an 8GB Kingston SD card; I've tried formatting it several times to no avail. I'm using an aux cable from my phone to the line in soldered to the audio board and headphones on the out jack.

I'd appreciate any input or thoughts

Thanks!
 

Attachments

  • nsgv47K.jpg
    nsgv47K.jpg
    59.6 KB · Views: 38
QMHL9tb.jpg


4QNRcwb.png


Here are some pictures of the setup. It reads all of the inputs fine but doesn't seem like it's writing anything to the SD card. With the the code to time SD writes uncommented I don't see anything on the serial monitor. I'm not sure why it wouldn't be writing to the SD card.

I'm using an 8GB Kingston SD card; I've tried formatting it several times to no avail. I'm using an aux cable from my phone to the line in soldered to the audio board and headphones on the out jack.

I'd appreciate any input or thoughts

Thanks!

Well after reading this post: https://forum.arduino.cc/t/record-audio-and-store-it-on-an-sd-card/261054/2

It seems like that example sketch may only run on Teensy 3.1.

Out of curiosity does anyone know why? Could it be adapted to 3.2?

Thanks
 
Yes, that example works on Teensy 3.2 and all higher (3.5, 3.6, 4.0, 4.1), assuming your SD card is fast enough. Pretty much all modern cards are.

When that "only runs on Teensy 3.1" message was written in 2014, Teensy 3.2 did not yet exist.
 
Yes, that example works on Teensy 3.2 and all higher (3.5, 3.6, 4.0, 4.1), assuming your SD card is fast enough. Pretty much all modern cards are.

When that "only runs on Teensy 3.1" message was written in 2014, Teensy 3.2 did not yet exist.

Ah gotcha, that makes sense. Dang I thought I figured out the reason why my setup isn't working haha.

I purchased a new 32GB SanDisk ultra micro SD and still had the same results. It doesn't seem like it's actually writing to the SD because I don't see the SD write times in the serial monitor.

My only other thought is to try some other sketches to see if there is possibly a problem with my teensy/audio shield. I really can't think of any other reason why this wouldn't be working.

Back to the drawing board I guess.

Thanks for the response and all the contributions to Teensy Paul!
 
Well I ended up getting it working; after some troubleshooting I determined that it wasn't creating a file on the SD card so the recording queue never started. I poked around and found this thread: https://forum.pjrc.com/threads/5492...-SD-card-not-working-Unable-to-find-partition

I didn't have any shorts but after removing the Teensy from the breadboard it created the file and started recording. I put it back on the breadboard afterward and it still worked so I'm puzzled why it wouldn't have worked earlier. Hopefully this can help someone else if they're having strange issues with SD cards not creating/writing files properly

The issue I've been running into now is that the audio playback is sped up. Is this just a feature of it being a .raw file? From what I read online it seems like it may be due to the sampling frequency. I tried changing my speaker/headphone out on my laptop so that it was mono 16b 44.1kHz but it is still sped up when recorded and played back from the Teensy. Anyone have any ideas on this?
 
Last edited:
Back
Top