Adafruit Wave Shield Kit

After building the Animated Pair of Eyes I wanted to follow up with adding the capability of playing WAV files to my projects. I decided to purchase the Adafruit Wave Shield Kit for only $22 and make it myself.

wav_parts.jpg

From the Adafruit site:

“…A shield for Arduinos…It can play up to 22KHz, 12bit uncompressed audio files of any length. It’s low cost, available as an easy-to-make kit. It has an onboard DAC, filter and op-amp for high quality output. Audio files are read off of an SD/MMC card, which are available at nearly any store. Volume can be controlled with the onboard thumbwheel potentiometer.”

Results

Here is the finished shield after about 20 mins soldering using this excellent Adafruit Tutorial.

wav_top.jpg

This kit is so well designed and the documentation so clear it feels like it put itself together.

wav_bottom.jpg

The Adafruit Wave Shield really is a great kit.

I love LadyAda and her fruit.

Like Massimo Banzi, the creator of the wildly successful Arduino platform, Limor Fried (a.k.a LadyAda) is another great example of a small business owner who is successful being altruistic with her intellectual property. Every weekend LadyAda and some of her staff host an online live show Ask an Engineer which uses video and real-time chat to reach out to the maker community to answer technical questions, share submitted user projects, and unveil new products for sale. By making her excellent designs open source and herself available for feedback -to help others benefit as engineers- she not only encourages new business and growing community but also brand loyalty.

As a consumer, I feel a strong commitment to her brand and favor her products which are of great quality. There are dozens of sites online to order parts at mostly the same prices. They don’t have LadyAda. This combination of high quality and outreach of technical prowess, is very much in the same vein as the original computer and electronic clubs of the last century. “Hey, look what I just made! It works so well I want to share it with you and see how you can use it and how we can make it better together” This sense of community love Adafruit industries maintains instead of the cold bottom line is endearing and something missing from most commerce today.

OK, I am off my soapbox.

Sound test!

I followed the rest of documentation on how to format and install files on the SD card. I already had a 2GB Micro SD card with adapter which I reformatted using the formatter from https://www.sdcard.org/downloads/formatter_3/.

I then poked around using google looking for free wav files from old games and movies. Sure enough there are loads of sites with great clips from Toy Story and other awesome films. All the noises and sounds from games perfect for a device.

Here is a video showing the wav shield playing an assortment of files from the root directory of the SD card.

Codes for the driver

This code originally would alter the pitch of the output of each file. I modified it just to play the files as is. Just download to the Arduino and it reads through all the files in the root directory of the SD card. Very simple for a quick test!

/*
 * 
 * Adafruit SampleRateHC.pde example modified to simply play each wav file in the root of the SD card.
 *
 * 
*/
#include <WaveHC.h>
#include <WaveUtil.h>

SdReader card;    // This object holds the information for the card
FatVolume vol;    // This holds the information for the partition on the card
FatReader root;   // This holds the information for the volumes root directory
FatReader file;   // This object represent the WAV file
WaveHC wave;      // This is the only wave (audio) object, since we will only play one at a time

/*
 * Define macro to put error messages in flash memory
 */
#define error(msg) error_P(PSTR(msg))

//////////////////////////////////// SETUP
void setup() {
  Serial.begin(9600);
  Serial.println("Wave test!");

  // try card.init(true) if errors occur on V1.0 Wave Shield
  if (!card.init()) {
    error("Card init. failed!");
  }
  // enable optimize read - some cards may timeout
  card.partialBlockRead(true);

  if (!vol.init(card)) {
    error("No partition!");
  }
  if (!root.openRoot(vol)) {
    error("Couldn't open root");
  }
  putstring_nl("Files found:");
  root.ls();
}

// forward declarition
void playcomplete(FatReader &file);

//////////////////////////////////// LOOP
void loop() { 
  uint8_t i, r;
  char c, name[15];
  dir_t dir;

  root.rewind();
  // scroll through the files in the directory
  while (root.readDir(dir) > 0) { 
    // only play .WAV files
    if (!strncmp_P((char *)&dir.name[8]. PSTR("WAV"))) continue;

    if (!file.open(vol, dir)){
      putstring("Can't open ");
      printEntryName(dir);
      Serial.println();
      continue;
    }
    putstring("\n\rPlaying "); 
    printEntryName(dir);
    Serial.println();
    playcomplete(file);
    file.close();    
  }
}
/////////////////////////////////// HELPERS
/*
 * print error message and halt
 */
void error_P(const char *str) {
  PgmPrint("Error: ");
  SerialPrint_P(str);
  sdErrorCheck();
  while(1);
}
/*
 * print error message and halt if SD I/O error, great for debugging!
 */
void sdErrorCheck(void) {
  if (!card.errorCode()) return;
  PgmPrint("\r\nSD I/O error: ");
  Serial.print(card.errorCode(), HEX);
  PgmPrint(", ");
  Serial.println(card.errorData(), HEX);
  while(1);
}
int16_t lastpotval = 0;
#define HYSTERESIS 3
/*
 * play file with sample rate changes
 */
void playcomplete(FatReader &file) {
  int16_t potval;
  uint32_t newsamplerate;

   if (!wave.create(file)) {
     putstring_nl(" Not a valid WAV"); return;
   }
   // ok time to play!
   wave.play();

   sdErrorCheck();
}

Leave a comment