EE Lab 6


Part B. Connect And Test Your Decoder

 

Sine Test Tones: Describe the tone pattern you hear (i.e., high or low, how long, etc.).

 

I hear three, separate, one-second tones with ascending pitches. Between each tone is one second of silence. After the sequence has played, it resets and plays again indefinitely.

Part C. Play Some Music!

 

Tell a member of the teaching team what your song is (or better yet, play it for us).

 

Several songs are loaded onto the SD card. Among them, I see “Absolutely Cuckoo,” “Somewhere Over the Rainbow,” and “Baba Yetu.”

Does this code play all the songs in all the directories of the SD card? If not, which songs does it play? How does it keep from playing the text file?

 

The call to sd_dir_setup() in setup() is responsible for selecting which files to play. The sd_dir_setup function is found in Utilities. In particular, the following code segment checks each file’s extension before deciding whether or not to add it to the song list.

 

// only store mp3 or wav files in eeprom (for now). if you add other file

    // types, you should add their extensions here.

 

    if ((p.name()[i] == 'M' && p.name()[i+1] == 'P' && p.name()[i+2] == '3') ||

        (p.name()[i] == 'W' && p.name()[i+1] == 'A' && p.name()[i+2] == 'V')) {

 

      // store each character of the file name (including the terminate-array

      // character '\0' at position 12) into a byte in the eeprom.

 

      for (char i = 0; i < max_name_len; i++) {

        EEPROM.write(num_songs * max_name_len + i, p.name()[i]);

      }

      num_songs++;

    }

  }

Change the Song (or Simple_MP3_V2) program to save the current volume setting in your EEPROM, then fetch and set that value during initialization. Note that the first max_num_songs * max_name_len (in this case, 520) bytes of the EEPROM are used to store file names, so don't overwrite those. 

 

To store the value of the volume, simply call: EEPROM.write(550, mp3_vol);

To set the volume in the setup, call: Mp3.volume((int)(EEPROM.read(550)));

Note: errors resulting from EEPROM misuse generally take a full clear of the EEPROM and thirty presses of the Arduino reset button in order to resolve. Removing the cast to “int” appears to cause such an error.

Part D. Pause to Learn About Interrupts

 

Draw us a quick sketch of what your circuit looks like.

 

Image online with name “InterruptSketch.”

What are the pros and cons of using this [debouncer] method?

 

From a perusal of the Bouncer code, it is apparent that the library denounces buttons by comparing the time (found using millis()) at the time of the button press to the time of the last button press. If the gap is not larger than the user-defined threshold, the press is not registered. I actually wrote something similar for my own code. While the debouncer library is a viable option, it can be replaced in most cases by a simpler code segment, hence eliminating an unneeded reliability. My code for an interrupt-enabled, debounced button is given below.

 

int ledPin = 9;

int buttonPin=2;

int buttonState;

volatile int state = LOW;

long time=millis();

long lastInterrupt = time;

 

void setup()

{

  Serial.begin(9600);

  delay(1000); //this 1 second delay isn't strictly speaking necessary, but it seems to smooth over the USB serial monitor a bit.

   while (!Serial) {

    ; // wait for serial port to connect. Needed for Leonardo only

  }

  pinMode(ledPin, OUTPUT);

  attachInterrupt(1, blink, FALLING);

}

 

void blink()

{

  time=millis();

  if(time-lastInterrupt>50)

  {

  state = !state;

  Serial.println("blink");

  lastInterrupt=millis();

  }

}

 

void loop()

{

  digitalWrite(ledPin, state);

}

 

Now, take what you learned to make an interrupt driven pause function for your Barebones MP3 player!

 

This is the pertinent method:

 

void blink()

{

  time=millis();

  if(time-lastInterrupt>50)

  {

  state=!state;

  digitalWrite(13, state);

 

  if(current_state==PAUSED)

  {

    current_state=DIR_PLAY;

  }

  else

  {

   current_state=PAUSED;

  }

 

  lastInterrupt=millis();

  }

   Mp3.clear_buffer();

}