Hello,
I am having trouble coding with the Adafruit Wave Shield. Everything works fine, I can read data from the SD card and I can select a file to play with some buttons.
What I am trying to do is to be able to press a button and the shield should play the next song (or the previous one with another button). I spend a lot of time working with the examples given on the Adafruit website. They are very helpfull but I'm still stuck because my C language skills are not that good.
To be able to play the next song I thought it would be interesting to store in a Array of String (pointers in C ?) all the files on the SD card. When I start playing a song I can save it in a variable and I would know with the help of the Array of Strings which song to play next.
Here is the example code given by Adafruit that could help me build this Array of String :
void lsR(FatReader &d)
{
int8_t r; // indicates the level of recursion
while ((r = d.readDir(dirBuf)) > 0) { // read the next file in the directory
// skip subdirs . and ..
if (dirBuf.name[0] == '.')
continue;
for (uint8_t i = 0; i < dirLevel; i++)
Serial.print(' '); // this is for prettyprinting, put spaces in front
printEntryName(dirBuf); // print the name of the file we just found
Serial.println(); // and a new line
if (DIR_IS_SUBDIR(dirBuf)) { // we will recurse on any direcory
FatReader s; // make a new directory object to hold information
dirLevel += 2; // indent 2 spaces for future prints
if (s.open(vol, dirBuf))
lsR(s); // list all the files in this directory now!
dirLevel -=2; // remove the extra indentation
}
}
sdErrorCheck(); // are we doign OK?
}
Here is the code I have that I'm using in my project. I'm capturing the pressed button with a 4 Channels RF Remote Module, the Arduino shield used in the project is an Arduino Mega 2560. With the free space left on it, I dont think that adding elements dynamically to an Array of String should be an issue. Anyway, if there is another solution to this problem I would be glad to take it.
#include <Servo.h>
#include <WaveHC.h>
#include <WaveUtil.h>
// PIN set-up for all components
const byte DISTANCE_TRIGGER_PIN = 36;
const byte DISTANCE_ECHO_PIN = 37;
const byte SERVO_PIN = 6;
const byte REMOTE_A_PIN = 26;
const byte REMOTE_B_PIN = 25;
const byte REMOTE_C_PIN = 24;
const byte REMOTE_D_PIN = 27;
//Servo motors parameters
Servo servo;
const byte startPosition = 0;
const int SERVO_MAX = 2000;
const int SERVO_MIN = 1023;
int servoPosition = 0;
int capture = 0;
//Distance parameters
const unsigned long MEASURE_TIMEOUT = 25000UL; // 25ms = ~8m à 340m/s
const float SOUND_SPEED = 340.0 / 1000;
int CAPTURE_INTERVAL = 10;
float captureArray[10];
//Remote buttons
byte buttons[] = {REMOTE_A_PIN, REMOTE_B_PIN, REMOTE_C_PIN, REMOTE_D_PIN};
#define NUMBUTTONS sizeof(buttons)
volatile byte pressed[NUMBUTTONS], justpressed[NUMBUTTONS], justreleased[NUMBUTTONS];
//Wave shield parameters
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
WaveHC wave; // This is the only wave (audio) object, since we will only play one at a time
uint8_t dirLevel; // indent level for file/dir names (for prettyprinting)
dir_t dirBuf; // buffer for directory reads
FatReader f; // This holds the information for the file we're play
void setup() {
Serial.begin(9600);
//Distance configuration
pinMode(DISTANCE_TRIGGER_PIN, OUTPUT);
digitalWrite(DISTANCE_TRIGGER_PIN, LOW); // La broche TRIGGER doit être à LOW au repos
pinMode(DISTANCE_ECHO_PIN, INPUT);
//Servo configuration
servo.write(startPosition);
servo.attach(SERVO_PIN);
delay(1500);
//Wave shield configuration
card.init();
card.partialBlockRead(true);
uint8_t part;
for (part = 0; part < 5; part++) { // we have up to 5 slots to look in
if (vol.init(card, part))
break; // we found one, lets bail
}
root.openRoot(vol);
//Timer2 Overflow Interrupt Enable
TCCR2A = 0;
TCCR2B = 1<<CS22 | 1<<CS21 | 1<<CS20;
TIMSK2 |= 1<<TOIE2;
}
void lsR(FatReader &d)
{
// what to do ?
}
SIGNAL(TIMER2_OVF_vect) {
check_switches();
}
void loop() {
if (justpressed[0]) {
justpressed[0] = 0;
// here should be the code to play the next song
}
else if (justpressed[1]) {
justpressed[1] = 0;
// here should be the code to play the previous song
}
else if (justpressed[2]) {
justpressed[2] = 0;
playfile("TEST3.WAV");
}
else if (justpressed[3]) {
justpressed[3] = 0;
playfile("TEST4.WAV");
}
}
void controlServoWithDistance() {
digitalWrite(DISTANCE_TRIGGER_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(DISTANCE_TRIGGER_PIN, LOW);
long measure = pulseIn(DISTANCE_ECHO_PIN, HIGH, MEASURE_TIMEOUT);
float distance_mm = measure / 2.0 * SOUND_SPEED;
if(capture < CAPTURE_INTERVAL) {
captureArray[capture] = distance_mm;
capture = capture +1;
} else {
float moyenne = getMoyenne();
useServo(moyenne);
capture = 0;
}
delay(20);
}
void goUp(int servoMilliSeconds) {
servo.write(servoMilliSeconds);
delay(10);
}
void goDown(){
servo.write(SERVO_MIN);
delay(1000);
}
void printDistance(float distance_mm) {
if(distance_mm != 0) {
/* Affiche les résultats en mm, cm et m */
Serial.print(F("Distance: "));
Serial.print(distance_mm);
Serial.print(F("mm ("));
Serial.print(distance_mm / 10.0, 2);
Serial.print(F("cm, "));
Serial.print(distance_mm / 1000.0, 2);
Serial.println(F("m)"));
} else {
Serial.println("0");
}
}
float getMoyenne(){
float sum = 0;
for (int index = 0; index < 10; index++){
sum = sum + captureArray[index];
}
float result = sum/10;
return result;
}
void useServo(float distance_mm) {
printDistance(distance_mm);
if (distance_mm <80) {
Serial.print(F("servoPosition: "));
Serial.println(servoPosition);
if(servoPosition != 6) {
goUp(SERVO_MIN + (servoPosition*200) + 200);
servoPosition = servoPosition +1;
} else {
goDown();
servoPosition = 0;
}
} else {
if(servoPosition != 0){
goDown();
servoPosition = 0;
}
}
}
void check_switches() {
static byte previousstate[NUMBUTTONS];
static byte currentstate[NUMBUTTONS];
byte index;
for (index = 0; index < NUMBUTTONS; index++) {
currentstate[index] = digitalRead(buttons[index]); // read the button
if (currentstate[index] == previousstate[index]) {
if ((pressed[index] == LOW) && (currentstate[index] == LOW)) {
// just pressed
justpressed[index] = 1;
}
else if ((pressed[index] == HIGH) && (currentstate[index] == HIGH)) {
// just released
justreleased[index] = 1;
}
pressed[index] = !currentstate[index]; // remember, digital HIGH means NOT pressed
}
//Serial.println(pressed[index], DEC);
previousstate[index] = currentstate[index]; // keep a running tally of the buttons
}
}
void playfile(char *name) {
if (wave.isplaying) {
wave.stop();
}
// look in the root directory and open the file
f.open(root, name);
// OK read the file and turn it into a wave object
wave.create(f);
// ok time to play! start playback
wave.play();
}