Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: 4DGL-uLCD-SE PinDetect SDFileSystem Speaker mbed wave_player
Fork of Project_MP by
Diff: main.cpp
- Revision:
- 3:ecf799cef1db
- Parent:
- 2:54dcfef5c648
diff -r 54dcfef5c648 -r ecf799cef1db main.cpp
--- a/main.cpp Wed Dec 06 08:51:00 2017 +0000
+++ b/main.cpp Wed Dec 13 05:30:52 2017 +0000
@@ -7,138 +7,675 @@
#include <vector>
#include <string>
+Serial pc(USBTX, USBRX);
+Serial esp(p28, p27); // tx, rx
+DigitalOut reset(p26);
+
//Set up LEDs
DigitalOut myled(LED1);
DigitalOut myled2(LED2);
DigitalOut myled3(LED3);
DigitalOut myled4(LED4);
+AnalogIn seed(p16);
+Timer t;
+
+int count,ended,timeout;
+char buf[2024];
+char snd[1024];
+
+char ssid[32] = "Mbednode"; // enter WiFi router ssid inside the quotes
+char pwd [32] = "Hello"; // enter WiFi router password inside the quotes
+
using namespace std;
SDFileSystem sd(p5, p6, p7, p8, "sd"); //SD card
uLCD_4DGL uLCD(p9,p10,p11);
DigitalIn sdDetect(p17); // Set up a pin for SD Card Detect
-PinDetect pb1(p21); // pb forup shift
-PinDetect pb2(p22); // pb fordown shift
-PinDetect pb3(p23); // pb for pause
-
-
-
-
AnalogOut DACout(p18); //set up speaker
wave_player waver(&DACout); //set up wave player library
int pos = 0; // index of the song
+int currentSongIndex = -1;
int vol = 0;
-bool playing = false; //variable for pause/play since we only have 1 pb for that
-vector<string> filenames; //filenames are stored in a vector string
-void read_file_names(char *dir) // function that reads in file names from sd cards
+bool playing = false; //variable for pause/play
+vector<string> song_names; //filenames are stored in a vector string
+vector<string> artist_names; //filenames are stored in a vector string
+string fname;
+FILE *wave_file;
+
+void SendCMD(),getreply(),ESPconfig(),ESPsetbaudrate();
+
+/* implementation of strcmp that ignores cases */
+int strcmpi(char *s1, char *s2)
+{
+ int i;
+ for (i = 0; s1[i] && s2[i]; ++i)
+ {
+ /* If characters are same or inverting the
+ 6th bit makes them same */
+ if (s1[i] == s2[i] || (s1[i] ^ 32) == s2[i])
+ continue;
+ else
+ break;
+ }
+
+ /* Compare the last (or first mismatching in
+ case of not same) characters */
+ if (s1[i] == s2[i])
+ return 0;
+
+ // Set the 6th bit in both, then compare
+ if ((s1[i] | 32) < (s2[i] | 32))
+ return -1;
+ return 1;
+}
+
+void read_file_names(char *dir, vector<string> &filenames) // function that reads in file names from sd cards
{
DIR *dp;
struct dirent *dirp;
dp = opendir(dir);
//read all directory and file names in current directory into filename vector
+ if(dp == NULL){
+ return;
+ }
+ if((dirp = readdir(dp)) != NULL) {
+ filenames.clear();
+ filenames.push_back(string(dirp->d_name));
+ }
+
while((dirp = readdir(dp)) != NULL) {
filenames.push_back(string(dirp->d_name));
}
}
-//interrupt handler for pb1
-void pb1_hit_callback (void)
-{
- // it checks for the total number of songs in the sd card..then increments the index until it reaches the last one, then resets to 0
- int l = filenames.size();
- if (pos < (l-1)) {
- pos++;
- } else if (pos == (l-1)) {
- pos = 0;
- }
- string songname = filenames[pos];
- unsigned index = songname.find(".wav");
- songname = songname.substr(0,index);
- uLCD.cls();
- uLCD.printf(songname.c_str()); //it clears screen and then sets the new index song in the uLCD display
-}
-//interrupt handler for pb2
-void pb2_hit_callback (void)
+
+char pcCommand[1024] = "";
+char espCommand[1024] = "";
+string testIt = "";
+bool flag = false;
+bool espflag = false;
+
+int espcnt = -1;
+
+ void dev_recv()
{
- //does opposite of pb1..moves the index down..from 2nd song to 1st song via changing the index number and then calling in the vector
- int l = filenames.size();
- if (pos > 0) {
- pos--;
- } else if (pos == 0 ) {
- pos = l-1;
+ while(esp.readable()) {
+
+ if(espcnt == -1) {
+ espcnt++;
+ esp.getc();
+ } else {
+ espCommand[espcnt] = esp.getc();
+ espcnt++;
+
+ if(espCommand[espcnt-1] == 34) {
+ playing = 0;
+ espflag = true;
+ }
+ }
}
- string songname = filenames[pos];
- unsigned index = songname.find(".wav");
- songname = songname.substr(0,index);
- uLCD.cls();
- uLCD.printf(songname.c_str());
+
}
-//interrupt handler for 3rd pushbutton
-void pb3_hit_callback (void)
+
+int cnt = -1;
+
+void pc_recv()
{
- //this interrupt handler changes the play to pause mode or vice versa
- //this is done using the boolean playing
- if (playing == false) {
- playing = true;
- } else if (playing == true) {
- uLCD.cls();
- playing = false;
- string songname = filenames[pos];
- unsigned index = songname.find(".wav");
- songname = songname.substr(0,index);
- uLCD.printf(songname.c_str());
+ while(pc.readable()) {
+
+ if(cnt == -1) {
+ cnt++;
+ pc.getc();
+ } else {
+ pcCommand[cnt] = pc.getc();
+ cnt++;
+
+ if(pcCommand[cnt-1] == 34) {
+ playing = 0;
+ flag = true;
+ }
+ }
}
}
+string song = "";
+string artist = "";
-int main()
+void executeCommand(char command[])
{
+
+ uLCD.printf("Command: %s\n", command);
+
+ char parsedCommand[20][20];
+ int finalCommand = 0;
+ song = "";
+ int i,j,ctr;
+
+ j=0; ctr=0;
+ for(i=0;i<=(strlen(command));i++)
+ {
+ // if space or NULL found, assign NULL into parsedCommand[ctr]
+ if(command[i]==' '||command[i]=='\0')
+ {
+ parsedCommand[ctr][j]='\0';
+ ctr++; //for next word
+ j=0; //for next word, init index to 0
+ }
+ else
+ {
+ parsedCommand[ctr][j]=command[i];
+ j++;
+ }
+ }
+
+ if(strcmp (parsedCommand[0],"play") == 0) {
+ finalCommand = 1;
+ }else if(strcmp (parsedCommand[0],"stop") == 0) {
+ finalCommand = 0;
+ }else if(strcmp (parsedCommand[0],"playnext") == 0) {
+ finalCommand = 2;
+ }else if(strcmp (parsedCommand[0],"playback") == 0) {
+ finalCommand = 3;
+ }
+
+
+ int ii = 2;
+ int songLength = 0;
+ int artistLength = 0;
+
+
+ if(strcmp (parsedCommand[0],"play") == 0) {
+ ctr--;
+ artist = "";
+ if(strcmp (parsedCommand[1],"song") == 0) {
+ while((ii <= ctr) && (strcmp (parsedCommand[ii],"artist") != 0)){
+ string songstr(parsedCommand[ii]);
+ songLength++;
+ if(ii == ctr || (strcmp (parsedCommand[ii+1],"artist") == 0)){
+ song = song + songstr;
+ }else{
+ song = song + songstr + " ";
+ }
+ ii++;
+ }
+ if(strcmp (parsedCommand[ii],"artist") == 0) {
+
+ ii++;
+ while(ii <= ctr) {
+ string artiststr(parsedCommand[ii]);
+ artistLength++;
+ if(ii == ctr) {
+ artist = artist + artiststr;
+ } else {
+ artist = artist + artiststr + " ";
+ }
+ ii++;
+ }
+ }
+ }else if(strcmp (parsedCommand[1],"artist") == 0) {
+
+ while(ii <= ctr){
+ string artiststr(parsedCommand[ii]);
+ artistLength++;
+ if(ii == ctr) {
+ artist = artist + artiststr;
+ } else {
+ artist = artist + artiststr + " ";
+ }
+ ii++;
+ }
+ }
+ }
+
sdDetect.mode(PullUp);
wait(.1);
//wait after pulling up the sd card,
- // read file names into vector of strings
- pb1.mode(PullUp);
- pb2.mode(PullUp);
- pb3.mode(PullUp);
- //pb4.mode(PullUp);
- // Delay for initial pullup to take effect
- wait(.01);
- // Setup Interrupt callback functions for a pb hit
- pb1.attach_deasserted(&pb1_hit_callback);
- pb2.attach_deasserted(&pb2_hit_callback);
- pb3.attach_deasserted(&pb3_hit_callback);
-
- // Start sampling pb inputs using interrupts
- pb1.setSampleFrequency();
- pb2.setSampleFrequency();
- pb3.setSampleFrequency();
uLCD.cls();
//detects whethere there is a SD card or not.. if not then it prints and informs the user
- while(sdDetect ==0) {
+ while(sdDetect == 0) {
uLCD.locate(0,0);
uLCD.printf("Insert SD Card");
wait(.5);
}
- uLCD.cls();
+ uLCD.cls();
+
wait(.5);
sd.disk_initialize();
- read_file_names("/sd/");
+
+
+ switch(finalCommand) {
+
+ case 0: // stop
+ {
+ fclose(wave_file);
+ uLCD.cls();
+ playing = false;
+ pc.printf("Case 0: Stop !");
+ break;
+ }
+ case 1: // play song
+ {
+ read_file_names("/sd/wave", artist_names);
+
+ if((strcmp (artist.c_str(), "") == 0) && (strcmp (song.c_str(), "") != 0)) { // no artist, but song name
+
+ int search = 1;
+ int artistCounter = 0;
+ artist = "";
+ while(search){
+ fname = "/sd/wave/" + artist_names[artistCounter] + "/" + song + ".wav";
+ wave_file = fopen(fname.c_str(),"r");
+ if(wave_file != NULL){
+ search = 0;
+ fclose(wave_file);
+ string artistDirectory = "/sd/wave/" + artist_names[artistCounter];
+ char *charArtistDirectory = new char[artistDirectory.length() + 1];
+ strcpy(charArtistDirectory, artistDirectory.c_str());
+ read_file_names(charArtistDirectory, song_names);
+ artist = artist_names[artistCounter];
+ delete [] charArtistDirectory;
+ playing = true;
+ }else{
+ artistCounter++;
+ }
+ if(artistCounter >= artist_names.size()){
+ uLCD.printf("Song not found");
+ break;
+ }
+ }
+
+ } else if((strcmp (artist.c_str(), "") == 0) && (strcmp (song.c_str(), "") == 0)) { // no artist, no song name. Plays random song
+
+ artist = "";
+ int seedVal = seed * 1000;
+ srand(seedVal);
+ int artistIndex = rand() % artist_names.size();
+ string artistDirectory = "/sd/wave/" + artist_names[artistIndex];
+ char *charArtistDirectory = new char[artistDirectory.length() + 1];
+ strcpy(charArtistDirectory, artistDirectory.c_str());
+ read_file_names(charArtistDirectory, song_names);
+ delete [] charArtistDirectory;
+ int songIndex = rand() % song_names.size();
+ fname = artistDirectory + "/" + song_names[songIndex];
+ song = song_names[songIndex].substr(0 ,((song_names[songIndex]).length() - 4));
+ artist = artist_names[artistIndex];
+ playing = true;
+
+ }else if((strcmp (artist.c_str(), "") != 0) && (strcmp (song.c_str(), "") == 0)){ //no song name but artist
+ string artistDirectory = "/sd/wave/" + artist;
+ char *charArtistDirectory = new char[artistDirectory.length() + 1];
+ strcpy(charArtistDirectory, artistDirectory.c_str());
+ read_file_names(charArtistDirectory, song_names);
+ delete [] charArtistDirectory;
+ fname = artistDirectory + "/" + song_names[0];
+ song = song_names[0].substr(0, ((song_names[0]).length() - 4));
+ wave_file = fopen(fname.c_str(),"r");
+ playing = true;
+ if(wave_file == NULL){
+ uLCD.printf("Artist not found");
+ playing = false;
+ }
+ fclose(wave_file);
+ }else{ // song name and artist
+ fname = "/sd/wave/" + artist + "/" + song + ".wav";
+ wave_file = fopen(fname.c_str(),"r");
+ playing = true;
+ if(wave_file == NULL){
+ uLCD.printf("Song not found");
+ playing = false;
+ }
+ fclose(wave_file);
+ }
+
+ int entering = 1;
+
+ while(playing == true){
+ uLCD.cls();
+ uLCD.printf("Now playing ");
+ uLCD.printf("\n%s\n%s\n", song.c_str(), artist.c_str());
+
+ if(entering == 1) {
+ entering = 0;
+ string songWav = song + ".wav";
+ char *songNameChar = new char[songWav.length() + 1];
+ strcpy(songNameChar, songWav.c_str());
+ for(int index=0; index<song_names.size(); index++) {
+ char *songNameChar2 = new char[song_names[index].length() + 1];
+ strcpy(songNameChar2, song_names[index].c_str());
+ if(strcmpi(songNameChar, songNameChar2) == 0) {
+ currentSongIndex = index;
+ delete [] songNameChar2;
+ break;
+ }
+ delete [] songNameChar2;
+ }
+ delete [] songNameChar;
+ }
+ wave_file = fopen(fname.c_str(),"r");
+ waver.play(wave_file);
+ fclose(wave_file);
+ if(!flag && !espflag){
+ if (currentSongIndex < (song_names.size()-1)) {
+ currentSongIndex++;
+ } else if (currentSongIndex == (song_names.size()-1)) {
+ currentSongIndex = 0;
+ }
+ song = song_names[currentSongIndex].substr(0, ((song_names[currentSongIndex]).length() - 4));
+ fname = "/sd/wave/" + artist + "/" + song + ".wav";
+ }
+ }
+
+ // fclose(wave_file);
+
+ pc.printf("Case 1: Play !");
+ break;
+ }
+ case 2: // play next
+ {
+
+ if(currentSongIndex != -1){
+ currentSongIndex++;
+ playing = true;
+ song = song_names[currentSongIndex].substr(0, ((song_names[currentSongIndex]).length() - 4));
+ fname = "/sd/wave/" + artist + "/" + song + ".wav";
+ }else{
+ uLCD.printf("No song playing");
+ }
+
+ while(playing == true){
+ uLCD.cls();
+ uLCD.printf("Now playing ");
+ uLCD.printf("\n%s\n%s\n", song.c_str(), artist.c_str());
+
+
+ wave_file = fopen(fname.c_str(),"r");
+ waver.play(wave_file);
+ fclose(wave_file);
+ if(!flag && !espflag){
+ if (currentSongIndex < (song_names.size()-1)) {
+ currentSongIndex++;
+ } else if (currentSongIndex == (song_names.size()-1)) {
+ currentSongIndex = 0;
+ }
+ song = song_names[currentSongIndex].substr(0, ((song_names[currentSongIndex]).length() - 4));
+ fname = "/sd/wave/" + artist + "/" + song + ".wav";
+ }
+
+ }
+
+ pc.printf("Case 2: Play Next!");
+ break;
+ }
+ case 3: // play back
+ {
+ if(currentSongIndex != -1){
+ if (currentSongIndex > 0) {
+ currentSongIndex--;
+ } else if (currentSongIndex == 0) {
+ currentSongIndex = (song_names.size()-1);
+ }
+ playing = true;
+ song = song_names[currentSongIndex].substr(0, ((song_names[currentSongIndex]).length() - 4));
+ fname = "/sd/wave/" + artist + "/" + song + ".wav";
+ }else{
+ uLCD.printf("No song playing");
+ }
+
+ while(playing == true){
+ uLCD.cls();
+ uLCD.printf("Now playing ");
+ uLCD.printf("\n%s\n%s\n", song.c_str(), artist.c_str());
+
+
+ wave_file = fopen(fname.c_str(),"r");
+ waver.play(wave_file);
+ fclose(wave_file);
+ if(!flag && !espflag){
+ if (currentSongIndex < (song_names.size()-1)) {
+ currentSongIndex++;
+ } else if (currentSongIndex == (song_names.size()-1)) {
+ currentSongIndex = 0;
+ }
+ song = song_names[currentSongIndex].substr(0, ((song_names[currentSongIndex]).length() - 4));
+ fname = "/sd/wave/" + artist + "/" + song + ".wav";
+ }
+ }
+ pc.printf("Case 3: Play Previous!");
+ break;
+ }
+ default: // stop
+ {
+ pc.printf("DEFAULT");
+ break;
+ }
+ }
+
+ }
+
+int main(){
+
+ reset=0; //hardware reset for 8266
+ pc.baud(9600); // set what you want here depending on your terminal program speed
+ pc.printf("\f\n\r-------------ESP8266 Hardware Reset-------------\n\r");
+ wait(0.5);
+ reset=1;
+ timeout=2;
+ getreply();
+ esp.baud(9600);
+ ESPconfig(); //****************** include Config to set the ESP8266 configuration ***********************
+
+ pc.baud(9600);
+ char oldCommand[1024];
+ pc.attach(&pc_recv, Serial::RxIrq);
+ esp.attach(&dev_recv, Serial::RxIrq);
+
while(1) {
- //while pb3 is low, then we can start playing the song
- while(playing == true) { //we have 2 while loops..one while loop makes sure the music player is always on, the other one is for the song
- string songname = filenames[pos];
- string a = "/sd/";
- string fname = a + songname; //retrieves the file name
- FILE *wave_file;
- uLCD.locate(0,4);
- uLCD.printf("Now Playing");
- wave_file = fopen(fname.c_str(),"r"); //opens the music file
- waver.play(wave_file); //plays the music file
- fclose(wave_file);
+
+ if(flag){
+ memset(oldCommand, '\0', 1024);
+ pcCommand[cnt-1] = '\0';
+ pc.printf("pcCommand: %s", pcCommand);
+ strncpy(oldCommand, pcCommand, sizeof(pcCommand));
+ flag = false;
+ espflag = false;
+ memset(pcCommand, '\0', sizeof(pcCommand));
+ memset(espCommand, '\0', sizeof(espCommand));
+ cnt = -1;
+ espcnt = -1;
+ executeCommand(oldCommand);
+ }
+
+ if(espflag){
+ memset(oldCommand, '\0', 1024);
+ espCommand[espcnt-1] = '\0';
+ for(int j = espcnt; j > 0; j--){
+ if(espCommand[j] == 34){
+ espCommand[j] = '\0';
+ break;
+ }
+ }
+ pc.printf("espCommand: %s", espCommand);
+ strncpy(oldCommand, espCommand, sizeof(espCommand));
+ espflag = false;
+ flag = false;
+ memset(espCommand, '\0', sizeof(espCommand));
+ memset(pcCommand, '\0', sizeof(pcCommand));
+ cnt = -1;
+ espcnt = -1;
+ executeCommand(oldCommand);
+ }
+
+ }
+
+}
+
+void ESPsetbaudrate()
+{
+ strcpy(snd, "AT+CIOBAUD=9600\r\n"); // change the numeric value to the required baudrate
+ SendCMD();
+}
+
+// +++++++++++++++++++++++++++++++++ This is for ESP8266 config only, run this once to set up the ESP8266 +++++++++++++++
+void ESPconfig()
+{
+
+ wait(5);
+ pc.printf("\f---------- Starting ESP Config ----------\r\n\n");
+ strcpy(snd,".\r\n.\r\n");
+ SendCMD();
+ wait(1);
+ pc.printf("---------- Reset & get Firmware ----------\r\n");
+ strcpy(snd,"node.restart()\r\n");
+ SendCMD();
+ timeout=5;
+ getreply();
+ pc.printf(buf);
+
+ wait(2);
+
+ pc.printf("\n---------- Get Version ----------\r\n");
+ strcpy(snd,"print(node.info())\r\n");
+ SendCMD();
+ timeout=4;
+ getreply();
+ pc.printf(buf);
+
+ wait(3);
+
+ // set CWMODE to 1=Station,2=AP,3=BOTH, default mode 1 (Station)
+ pc.printf("\n---------- Setting Mode ----------\r\n");
+ strcpy(snd, "wifi.setmode(wifi.STATION)\r\n");
+ SendCMD();
+ timeout=4;
+ getreply();
+ pc.printf(buf);
+
+ wait(2);
+
+
+
+ pc.printf("\n---------- Listing Access Points ----------\r\n");
+ strcpy(snd, "function listap(t)\r\n");
+ SendCMD();
+ wait(1);
+ strcpy(snd, "for k,v in pairs(t) do\r\n");
+ SendCMD();
+ wait(1);
+ strcpy(snd, "print(k..\" : \"..v)\r\n");
+ SendCMD();
+ wait(1);
+ strcpy(snd, "end\r\n");
+ SendCMD();
+ wait(1);
+ strcpy(snd, "end\r\n");
+ SendCMD();
+ wait(1);
+ strcpy(snd, "wifi.sta.getap(listap)\r\n");
+ SendCMD();
+ wait(1);
+ timeout=15;
+ getreply();
+ pc.printf(buf);
+
+ wait(2);
+
+ pc.printf("\n---------- Connecting to AP ----------\r\n");
+ pc.printf("ssid = %s pwd = %s\r\n",ssid,pwd);
+ strcpy(snd, "wifi.sta.config(\"");
+ strcat(snd, ssid);
+ strcat(snd, "\",\"");
+ strcat(snd, pwd);
+ strcat(snd, "\")\r\n");
+ SendCMD();
+ timeout=10;
+ getreply();
+ pc.printf(buf);
+
+ wait(5);
+
+ pc.printf("\n---------- Get IP's ----------\r\n");
+ strcpy(snd, "print(wifi.sta.getip())\r\n");
+ SendCMD();
+ timeout=3;
+ getreply();
+ pc.printf(buf);
+
+ wait(1);
+
+ pc.printf("\n---------- Get Connection Status ----------\r\n");
+ strcpy(snd, "print(wifi.sta.status())\r\n");
+ SendCMD();
+ timeout=5;
+ getreply();
+ pc.printf(buf);
+
+ pc.printf("\n\n\n If you get a valid (non zero) IP, ESP8266 has been set up.\r\n");
+ pc.printf(" Run this if you want to reconfig the ESP8266 at any time.\r\n");
+ pc.printf(" It saves the SSID and password settings internally\r\n");
+ wait(10);
+
+
+ pc.printf("\n---------- Setting up http server ----------\r\n");
+ strcpy(snd, "srv=net.createServer(net.TCP)\r\n");
+ SendCMD();
+ wait(1);
+
+ strcpy(snd, "srv:listen(80,function(conn)\r\n");
+ SendCMD();
+ wait(1);
+
+ strcpy(snd, "conn:on(\"receive\",function(conn,payload)\r\n");
+ SendCMD();
+ wait(1);
+
+ strcpy(snd, "print(payload)");
+ SendCMD();
+ wait(1);
+
+ strcpy(snd, "end)\r\n");
+ SendCMD();
+ wait(1);
+
+ strcpy(snd, "conn:on(\"sent\",function(conn) conn:close() end)\r\n");
+ SendCMD();
+ wait(1);
+
+ strcpy(snd, "end)\r\n");
+ SendCMD();
+ wait(1);
+
+ timeout=17;
+ getreply();
+ pc.printf(buf);
+ pc.printf("\r\nDONE");
+}
+
+void SendCMD()
+{
+ esp.printf("%s", snd);
+}
+
+void getreply()
+{
+ memset(buf, '\0', sizeof(buf));
+ t.start();
+ ended=0;
+ count=0;
+ while(!ended) {
+ if(esp.readable()) {
+ buf[count] = esp.getc();
+ count++;
+ }
+ if(t.read() > timeout) {
+ ended = 1;
+ t.stop();
+ t.reset();
}
}
}
+
+
