I used to have no problems playing audio off the waveshield + diecimila. i.e. It could play different audio files off of the card and have audio re-triggered etc.
Then I hooked it up to another arduino via I2C and initially had it play a preset filename based on receiving a specific single character command. This worked as well.
Now I have it reading in the filename and this is where I am getting crashes.
It will play the audio file once and then it needs to be restarted.
Any idea what is wrong?
Here are the code pieces:
filename variable:
char audiofilename[12];
My I2C receive function:
/ function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(int howMany)
{
char command;
byte i=0;
while (true)
{
if (Wire.available())
{
command = Wire.receive();
break; // exit the loop when the sentinel arrives
}
}
switch (command)
{
case PLAY_AUDIO:
memset(audiofilename, 0, sizeof(audiofilename));
while (true)
{
if (Wire.available())
{
byte c = Wire.receive();
audiofilename[i++] = c;
if (c == 0) break; // exit the loop when the sentinel arrives
}
}
busy = 1;
//playcomplete(audiofilename);
playFile(audiofilename);
busy = 0;
break;
// print the integer
}
}
playback functions:
void playcomplete(char *name)
{
playFile(name);
while (wave.isplaying);
card.close_file(f);
}
void playFile(char *name)
{
// stop any file already playing
if (wave.isplaying) {
wave.stop();
}
// close file if open
if (f) {
card.close_file(f);
}
// play specified file
f = card.open_file(name);
if (f && wave.create(f)) {
wave.play();
}
}
When the arduino starts up, it can play audio files no problem (I have it play a startup sound).
But later when I call the functions I have the problems.
If I call 'playcomplete" it will only play a tiny chunk of the audio and then freeze.
if I call playFile it will play the whole thing and then freeze.
Do I need to declare "audiofilename" as being volatile?
Can anyone see anything wrong???
There are non stop problems. The wonder if it is something to do with including the Wiring.h library?
I will further debug by returning to the original sample code and no I2C connections just to confirm there is nothing wrong with the hardware.
I will also try re-formatting the SD card, using a different one and trying other programs to convert the files (I used sound forge and I saw a note somewhere else that said they had issues with the SF conversions in comparison to using audacity).
Here is my current code, if anyone can see anything suspicious I would be very appreciative!
#include <avr/pgmspace.h>
#include <AF_Wave.h>
#include <Wire.h>
#include "util.h"
#include "wave.h"
//Commands received via I2C
#define PLAY_AUDIO 'P'
#define TERMINATING_CHARACTER 0
#define AUDIO_FILENAME_SIZE 13
#define AUDIO_BOARD_I2C_ADDRESS 3
volatile byte busy = 0;
AF_Wave card;
File f;
Wavefile wave;
char audiofilename[13]; //buffer for filename received via I2C
void setup()
{
// Set AudioShield Pins
for (byte i = 2; i <= 5; ++i)
{
pinMode(i, OUTPUT);
}
// open memory card
if (!card.init_card())
{
putstring_nl("Card init failed!"); return;
}
if (!card.open_partition())
{
putstring_nl("No partition!"); return;
}
if (!card.open_filesys())
{
putstring_nl("Couldn't open filesys"); return;
}
if (!card.open_rootdir())
{
putstring_nl("Couldn't open dir"); return;
}
//delay(10);
playcomplete("R2D2.WAV");
Wire.begin(AUDIO_BOARD_I2C_ADDRESS); // join i2c bus with address
Wire.onReceive(receiveEvent); // register event
Wire.onRequest(requestEvent);
}
void loop()
{
}
// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(int howMany)
{
char command;
byte i=0;
while (true)
{
if (Wire.available())
{
command = Wire.receive();
break; // exit the loop when the sentinel arrives
}
}
switch (command)
{
case PLAY_AUDIO:
memset(audiofilename, 0, sizeof(audiofilename));
while (true)
{
if (Wire.available())
{
byte c = Wire.receive();
audiofilename[i++] = c;
if (i == AUDIO_FILENAME_SIZE && c != 0) //if the 13th charcter received is not null then the received filename is bigger than allowed
{
audiofilename[i-1] = 0; //replace the last character of the array as null so the array is properly terminated
break;
}
if (c == 0) break; // exit the loop when the sentinel arrives
}
}
busy = 1;
playcomplete(audiofilename);
//playFile(audiofilename);
busy = 0;
break;
}
}
void playcomplete(char *name)
{
playFile(name);
while (wave.isplaying);
card.close_file(f);
}
void playFile(char *name)
{
// stop any file already playing
if (wave.isplaying) {
wave.stop();
}
// close file if open
if (f) {
card.close_file(f);
}
// play specified file
f = card.open_file(name);
if (f && wave.create(f)) {
wave.play();
}
}
/////////////////////////////////////////////////////////////
// Returns a 1 to the master if the audio functions are complete (not busy)
/////////////////////////////////////////////////////////////
void requestEvent()
{
if (busy)
Wire.send(0); // respond with message of 1 byte
else Wire.send(1);
// as expected by master tos ignify command completion
}