Greetings, Arduino community. Long time lurker, first time caller.
I've spent several days studying FAQ and self-help resources.
I can make this 'work' with one sound file, but it fails when I try to implement a second file.
It's an older Arduino Duemilanove with the ATmega168 with an Adafruit Wave Shield.
5 years ago I made a door chime with a normally open switch. Switch contact is made when the door opens. I knew the code had flaws.
New location, I want to implement changes. I want to add a "door closed" sound and add support for multiple doors. (switches)
The old program had an asterisk pointer for the array (deprecated). I thought I had dealt with that, but maybe misunderstood.
I've had to omit lines of code to stay within the forum post limit.
/
Input pin is assumed to connect to a normally open switch HIGH. When door opens, the switch makes contact LOW.
*/
#include <FatReader.h>
#include <SdReader.h>
#include <avr/pgmspace.h>
#include "WaveUtil.h"
#include "WaveHC.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 filesystem on the card
FatReader f; // This holds the information for the file we're play
WaveHC wave; // This is the only wave (audio) object, since we will only play one at a time
int debounce = 100; //Used to debounce the switch
int playopen = 0; //flag used to keep the sound from playing more than once
int playclosed = 0; //flag used to keep the sound from playing more than once
char const switch_1_contact_made_sound[] = "open_1.wav";
char const switch_1_contact_lost_sound[] = "close_1.wav";
// char const switch_2_contact_made_sound[] = "open_2.wav";
// char const switch_2_contact_lost_sound[] = "close_2.wav";
void setup()
{
// set up serial port
Serial.begin(9600);
putstring_nl("WaveHC with 6 buttons");
putstring("Free RAM: "); // This can help with debugging, running out of RAM is bad
Serial.println(freeRam()); // if this is under 150 bytes it may spell trouble!
// 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(13, OUTPUT); //I don't know what this is for, but it has a wire soldered on it, so leaving it alone
pinMode(19, INPUT); //Connected to Door 1 reed switch
//pinMode(18, INPUT); //Connected to Door 2 reed switch
// enable pull-up resistors on switch pins (analog inputs which are 14 thru 19)
digitalWrite(19, HIGH);
digitalWrite(18, HIGH);
//Add more pins if we want to implement more trigger methods. Like a trip wire, or a pushbutton, whatever.
// if (!card.init(true)) { //play with 4 MHz spi if 8MHz isn't working for you
if (!card.init())
{ //play with 8 MHz spi (default faster!)
putstring_nl("Card init. failed!"); // Something went wrong, lets print out why
sdErrorCheck();
while(1); // then 'halt' - do nothing!
}
// Lets tell the user about what we found
putstring("Using partition ");
Serial.print(part, DEC);
putstring(", type is FAT");
Serial.println(vol.fatType(),DEC); // FAT16 or FAT32?
// Try to open the root directory
if (!root.openRoot(vol))
{
putstring_nl("Can't open root dir!"); // Something went wrong,
while(1); // then 'halt' - do nothing!
}
// Whew! We got past the tough parts.
putstring_nl("Ready!");
}
void loop()
{
check_switch(); //Go decide if the switch is closed or open (LOW or HIGH)
}
void check_switch()
{
int door_1_switch_currently;
int door_1_switch_previously;
//We're going to read the value of the pin, pause a moment, then read it again.
// 1.) HIGH first time, HIGH second time means door is open
// 2.) LOW first time, LOW second time means door is closed
door_1_switch_currently = digitalRead(19); //Read the state of door switch 1
door_1_switch_previously = door_1_switch_currently; //Set the two values equal to each other. What 'was' becomes what 'is'
delay(debounce); //wait a little bit for the switch to settle
door_1_switch_currently = digitalRead(19); //Read the switch again
//The switch has been read, now do something based on the observation
//1.) The door just opened, so play the open sound
if(door_1_switch_currently == HIGH && door_1_switch_previously == HIGH && playopen == 0) //Door switch 1 is in contact (door is open)
{
playopen = 1; //Set the flag so we play it only once
playclosed = 0; //Reset the closed flag so that sound can play when this door closes
putstring_nl("Playing open sound for door 1.");
playcomplete(switch_1_contact_made_sound); //play the door 1 open sound
}
//2.) The door has just closed, so play the closed sound
if(door_1_switch_currently == LOW && door_1_switch_previously == LOW && playclosed == 0) //Door switch 1 is not in contact (door is closed)
{
playclosed = 1; //Set the flag so we play it only once
playopen = 0; //Reset the open flag so that sound can play when this door opens
// playcomplete(switch_1_contact_lost_sound); //play the door closed sound
}
} //This bracket closes void check_switch function
// Plays a full file from beginning to end with no pause.
void playcomplete(char filename[])
{
// call our helper to find and play this name
playfile(filename);
}
void playfile(char filename[])
{
// see if the wave object is currently doing something
if (wave.isplaying)
{ // already playing something, so stop it!
wave.stop(); // stop it
}
// look in the root directory and open the file
if (!f.open(root, filename))
{
putstring("Couldn't open file ");
Serial.print(filename);
return;
}
// OK read the file and turn it into a wave object
if (!wave.create(f))
{
putstring_nl("Not a valid WAV");
return;
}
// ok time to play! start playback
wave.play();
}
I get these compiler warnings:
In function 'void check_switch()':
153:47: warning: invalid conversion from 'const char*' to 'char*' [-fpermissive]
playcomplete(switch_1_contact_made_sound); //play the door 1 open sound
^
172:6: note: initializing argument 1 of 'void playcomplete(char*)'
void playcomplete(char filename[])
the sound plays and the serial monitor outputs this:
WaveHC with 6 buttons
Free RAM: 119
Using partition 1, type is FAT16
Ready!
Playing open sound for door 1. <this one happens at boot>
Playing open sound for door 1.
Playing open sound for door 1.
If I un-comment the line to play the door closed sound,
playcomplete(switch_1_contact_lost_sound); //play the door closed sound
then strange things happen. There are additional compiler warnings and this is output.
<snip>
Ready!
Playing open sound for door 1. <this happens at boot, but no sound>
WaWWWWWWWWWWWWWWWWWWWWWWWWW <ad infinitum>
I am completely lost.
I don't understand the warnings about invalid conversion from const char* to char* I declared it as a constant because the FAQs seemed to advise this.
What is the compiler telling me with the note about initializing argument?
My suspicion is that the file name isn't being properly passed to void playcomplete and rather than arriving as text it is arriving as a memory address or overwriting the variable with random memory bytes.
I think I lack enough understanding about how the programming language passes and receives the array arguments from one function to another.
Can you point me in the right direction?