Arduino Audio Shield 01
From TheBeard Science Project Wiki
(Redirected from Arduino Wave Shield 01)
I bought the Adafruit Wave Shield and thought it would be a funny first project to have an entrance theme play every time I get home from work. I created a compilation of audio clips from the TV show Seinfeld and made them play at random when my front door opens.
Components
- Adafruit Wave Shield v1.1 (source)
- Arduino Uno R3 (source)
- AUX speaker adapter (dollar store)
- Cheap door alarm (dollar store)
- SD Card
- USB power adapter
- Cat-5 cable
File Downloads
| Filename | Description | Size | Modified | Link |
|---|---|---|---|---|
|
arduino_wave1.zip |
Arduino code including WaveHC library. | 31KB | 12/29/2018 | |
|
seinfeld_audio.zip |
Audio clips used in this project. | 7.9MB | 12/29/2018 |
Additional Notes
The files need to be in WAV format (16 bit/sample, 22050 Hz sample rate).
The SD car needs to be formatted with a FAT32 file system.
Links
- Wave Shield Assembly Instructions (link)
Gallery
Code
Here is the Arduino code. Requires the WaveHC library.
#include "WaveUtil.h"
#include "WaveHC.h"
// Pin that triggers audio
int inpin = 13;
// Delay before audio plays after trigger
int playDelay = 1500;
SdReader card;
FatVolume vol;
FatReader root;
WaveHC wave;
uint8_t dirLevel;
dir_t dirBuf;
int btnState = 0;
int fileCount = 0;
bool reset = false;
void setup() {
Serial.begin(9600);
Serial.println("\nStart");
// Set the output pins for the DAC control
// This pins are defined in the library
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(inpin, INPUT);
if (!card.init())
{
Serial.println("Card init. failed!");
while(1); // Halt
}
// Enable optimize read
// Some cards may timeout. Disable if you're having problems
card.partialBlockRead(true);
// Look for a FAT partition
uint8_t part;
for (part = 0; part < 5; part++)
{
if (vol.init(card, part))
{
break;
}
}
if (part == 5)
{
Serial.println("No valid FAT partition!");
while(1); // Halt
}
Serial.print("Using partition ");
Serial.print(part, DEC);
Serial.print(", type is FAT");
Serial.println(vol.fatType(),DEC);
// Try to open the root directory
if (!root.openRoot(vol))
{
Serial.println("Can't open root dir!");
while(1); // Halt
}
// Print the file names
Serial.println("Files found:");
dirLevel = 0;
lsR(root);
// Seed the random number generator by reading an analog pin
randomSeed(analogRead(A0));
// Count the number of files
root.rewind();
fileCount = countFiles(root);
Serial.print("File count: ");
Serial.println(fileCount);
}
void loop() {
btnState = digitalRead(inpin);
if (btnState == HIGH)
{
Serial.println("Door Closed; wait");
reset = true;
delay(200);
while (reset == true)
{
btnState = digitalRead(inpin);
if (btnState == LOW)
{
Serial.println("Door Open; play and wait");
delay(playDelay);
root.rewind();
playRandom(root, fileCount);
Serial.println();
reset = false;
delay(500);
break;
}
else
{
continue;
}
}
}
}
/*
* Play a random file
*/
void playRandom(FatReader &dir, int fileCount)
{
FatReader file;
int playFile = random(1, fileCount);
int fileIter = 1;
// Read every file in the directory one at a time
while (dir.readDir(dirBuf) > 0)
{
// skip . and .. directories
if (dirBuf.name[0] == '.')
{
continue;
}
if (fileIter < playFile)
{
fileIter++;
continue;
}
if (!file.open(vol, dirBuf))
{
Serial.println("file.open failed");
while(1); // Halt
}
Serial.print("Playing ");
printEntryName(dirBuf);
if (!wave.create(file))
{
Serial.print(" Not a valid WAV");
}
else
{
// playing occurs in interrupts
wave.play();
while (wave.isplaying)
{
putstring(".");
delay(100);
}
if (wave.errors)
{
Serial.println(wave.errors);
}
}
break;
}
}
/*
* Count files on the SD card
*/
int countFiles(FatReader &dir)
{
int fileCount = 0;
FatReader file;
while (dir.readDir(dirBuf) > 0)
{
if (dirBuf.name[0] == '.' || !file.open(vol, dirBuf))
{
continue;
}
fileCount++;
}
return fileCount;
}
/*
* List files recursively
*/
void lsR(FatReader &d)
{
// indicates the level of recursion
int8_t r;
while ((r = d.readDir(dirBuf)) > 0)
{
// skip subdirs . and ..
if (dirBuf.name[0] == '.')
{
continue;
}
for (uint8_t i = 0; i < dirLevel; i++)
{
Serial.print(' ');
}
printEntryName(dirBuf);
Serial.println();
// Recurse on any direcory
if (DIR_IS_SUBDIR(dirBuf))
{
FatReader s;
dirLevel += 2;
if (s.open(vol, dirBuf))
{
lsR(s);
}
dirLevel -=2;
}
}
}