+//some good Arduino example code: http://www.hauntforum.com/showpost.php?p=849581&postcount=24
+#include <SoftwareSerial.h>
+const int SET_VOLUME = 0x15;
+//pins D0 and D1 are reserved for hard serial RX/TX (respectively)
+const int BUSY = 16; //16, (A2) busy signal from MP3 player when playing a track
+const int dialTone = 0x01;
+const int busyTone = 0x25;
+SoftwareSerial mp3Serial = SoftwareSerial (A0, A1); // binds a serial port instance to pins 14 & 15 for RX/TX respectively [A0 and A1]
+ pinMode(ringer, INPUT_PULLUP); // sets the digital pin 2 as input
+ pinMode(BUSY, INPUT_PULLUP); // sets the digital pin 2 as input
+ pinMode(R1, OUTPUT); // sets the digital pin 4 as an output
+ digitalWrite(R1, HIGH);
+ pinMode(R2, OUTPUT); // sets the digital pin 5 as an output
+ digitalWrite(R2, HIGH);
+ pinMode(R3, OUTPUT); // sets the digital pin 6 as an output
+ digitalWrite(R3, HIGH);
+ pinMode(R4, OUTPUT); // sets the digital pin 7 as an output
+ digitalWrite(R4, HIGH);
+ digitalWrite(LED, LOW);
+ pinMode(C1, INPUT_PULLUP); // sets the digital pin 8 as input
+ pinMode(C2, INPUT_PULLUP); // sets the digital pin 9 as input
+ pinMode(C3, INPUT_PULLUP); // sets the digital pin 10 as input
+ pinMode(C4, INPUT_PULLUP); // sets the digital pin 11 as input
+ //Setting up the software serial port
+ //setup serial port of 9600baud
+ Serial.begin(9600, SERIAL_8N1); // opens serial port, sets data rate to 9600 bps with 8-N-1
+ //delay( 3000 ); // power-up safety delay
+ Serial.write("Starting app\n");
+ int keypadPressed = 0xFF;
+ for(int i = 0; i < 4; i++)
+ digitalWrite(R1, HIGH);
+ digitalWrite(R2, HIGH);
+ digitalWrite(R3, HIGH);
+ digitalWrite(R4, HIGH);
+ while(!digitalRead(C1)){}
+ else if (!digitalRead(C2))
+ while(!digitalRead(C2)){}
+ else if (!digitalRead(C3))
+ while(!digitalRead(C3)){}
+ while(!digitalRead(C1)){}
+ else if (!digitalRead(C2))
+ while(!digitalRead(C2)){}
+ else if (!digitalRead(C3))
+ while(!digitalRead(C3)){}
+ while(!digitalRead(C1)){}
+ else if (!digitalRead(C2))
+ while(!digitalRead(C2)){}
+ else if (!digitalRead(C3))
+ while(!digitalRead(C3)){}
+ while(!digitalRead(C1)){}
+ else if (!digitalRead(C2))
+ while(!digitalRead(C2)){}
+ else if (!digitalRead(C3))
+ while(!digitalRead(C3)){}
+ else if (!digitalRead(C4))
+ while(!digitalRead(C4)){}
+ digitalWrite(R1, HIGH);
+ digitalWrite(R2, HIGH);
+ digitalWrite(R3, HIGH);
+ digitalWrite(R4, HIGH);
+ if(keypadPressed != 0xFF)
+ int buttonPressed = 0xFF;
+ //while the phone is hung up
+ while(!digitalRead(ringer))
+ //At this point, someone has picked up the phone
+ digitalWrite(LED, HIGH);
+ //while the phone is off the hook
+ while(digitalRead(ringer))
+ buttonPressed = pollKeypad();
+ if(buttonPressed != 0xFF)
+ playAudioClip(buttonPressed);
+ //while an audio track is playing AND the ringer is off the hook
+ while(digitalRead(BUSY) && digitalRead(ringer))
+ //if the ringer is hung up but we are still playing audio hang
+ //it up else, it means the audio is done, so play the busy tone
+ //while the ringer is off the hook, just wait
+ while(digitalRead(ringer))
+ //the ringer has been hung up
+ //just in case, stop the audio
+ digitalWrite(LED, LOW);
+ while(mp3Serial.available() == 0){}
+ Serial.print("return code from 0xF1 of ");
+ Serial.println(mp3Serial.read());
+ //toggle MP3 player until option to repeat single track is setup (as opposed to all tracks)
+ while(mp3Serial.available() == 0){}
+ singleMode = mp3Serial.read();
+ while(mp3Serial.available() == 0){}
+ singleMode = mp3Serial.read();
+ // Queries number of tracks on SD card and returns number, which is printed to serial monitor
+ while(mp3Serial.available() == 0){}
+ Serial.print("Total of ");
+ Serial.print(mp3Serial.read());
+ Serial.println(" tracks found on SD Card");
+ // Send Vol+ command to get current volume return message.
+ while(mp3Serial.available() == 0){}
+ volumeLevel = mp3Serial.read();
+ Serial.println("The volume started at: ");
+ Serial.println(volumeLevel);
+ // NOTE: the hex value is automatically converted to ASCII by serial, so 0x1E will read as "30"
+ if(volumeLevel == SET_VOLUME)
+ // if the return message is the SET_VOLUME, it's at the perferred value
+ Serial.println("Preferred volume set.");
+ else if(volumeLevel < SET_VOLUME)
+ // If the volume is lower than preferred, start the volume increase loop
+ for(int v = volumeLevel; v <= SET_VOLUME; v = v + 1)
+ while(mp3Serial.available() == 0){}
+ volumeLevel = mp3Serial.read();
+ Serial.println("Volume adjusted up to preferred level.");
+ // If the volume is higher than preferred, start the volume decrease loop
+ for(int v = volumeLevel; v >= SET_VOLUME; v = v - 1)
+ while(mp3Serial.available() == 0){}
+ Serial.println("Volume adjusted down to preferred level.");
+// This function stops all audio
+ Serial.println("Stopping audio");
+ while(mp3Serial.available() == 0){}
+// This function plays the dial tone
+ //Set MP3 to continue to play when track is done
+ while(mp3Serial.available() == 0){}
+ if(mp3Serial.read() == 0x00)
+ while(mp3Serial.available() == 0){}
+ //Send command to play dial tone track
+ mp3Serial.write(dialTone);
+ while(mp3Serial.available() == 0){}
+ Serial.print("Now playing dial tone track ");
+ Serial.println(dialTone);
+// This function plays the busy signal
+ //Set MP3 to continue to play when track is done
+ while(mp3Serial.available() == 0){}
+ if(mp3Serial.read() == 0x00)
+ while(mp3Serial.available() == 0){}
+ //Send command to play busy track
+ mp3Serial.write(busyTone);
+ while(mp3Serial.available() == 0){}
+ Serial.print("Now playing busy tone track ");
+ Serial.println(busyTone);
+void playAudioClip(int fileNum)
+ //Set MP3 to not play on repeat mode
+ while(mp3Serial.available() == 0){delay(10);}
+ incomingSerial = mp3Serial.read();
+ while(incomingSerial != 0x00)
+ while(mp3Serial.available() == 0){delay(10);}
+ incomingSerial = mp3Serial.read();
+ //Send command to play the track
+ mp3Serial.write(fileNum);
+ while(mp3Serial.available() == 0){}
+ Serial.print("Now playing track ");
+ Serial.println(fileNum);