Bluetooth MP3 Player with uLCD, Speaker, and SD card hardware components
Dependencies: 4DGL-uLCD-SE SDFileSystem mbed-rtos mbed
Fork of app-board-RTOS-Threads by
main.cpp
- Committer:
- pwu64
- Date:
- 2017-03-14
- Revision:
- 6:0c55c199443d
- Parent:
- 5:4fb2d9e36571
File content as of revision 6:0c55c199443d:
#include "mbed.h" #include "rtos.h" #include "uLCD_4DGL.h" #include "SDFileSystem.h" #include "wave_player.h" #include <string> #include <vector> /* Hardware Initialization */ Serial blue(p13,p14); BusOut myled(LED1,LED2,LED3,LED4); uLCD_4DGL uLCD(p28, p27, p30); AnalogOut Speaker(p18); SDFileSystem sd(p5, p6, p7, p8, "sd"); wave_player waver(&Speaker); FILE *wave_file; /* Mutexes to make the code thread safe */ Mutex lcd_mutex; Mutex stdio_mutex; Mutex time_mutex; Mutex inx_mutex; Mutex currSong_mutex; Mutex printed_mutex; //Basically will need to go around every if statement. May be usable as a generic mutex for everything/ /* Variables */ bool Menu=1; //1: menu mode 0: play mode vector <string> songList; // vector of songs to index string currSong=""; int startInx=0; // starting index of songs to display on lcd int inxIncrement=2; //4=Full page scroll 1=single song scrolling int songTime; int numSongs; // total # of songs on sd card string dir = "/sd/myMusic/"; // directory of songs on SD card int songsPerPage=4; bool playing = false; bool printed = false; // Thread 1 // Reads in input from bluefruit module // Make sure to be using the Adafruit bluetooth app -> controller -> control pad void thread1(void const *args) { while(1) { char bnum = 0; // number 1-8 char bhit = 0; // number 0 or 1 (release or hit) if(blue.readable()) { stdio_mutex.lock(); // Command come in as !B## if (blue.getc()=='!') { if (blue.getc()=='B') { //button data packet bnum = blue.getc(); //button number bhit = blue.getc(); //1=hit, 0=release if (blue.getc()==char(~('!' + 'B' + bnum + bhit))) { //checksum OK? myled = bnum - '0'; //current button number will appear on LEDs switch (bnum) { case '1': case '2': case '3': case '4': //number button 1-4 if(Menu) { /* Pressing a number button selects the corresponding numbered song and displays the number on the LCD */ currSong_mutex.lock(); currSong = songList[startInx + bnum-'1']; currSong_mutex.unlock(); lcd_mutex.lock(); uLCD.locate(0,15); uLCD.printf("Song selected: %d", bnum - '0'); lcd_mutex.unlock(); } break; case '5': //button 5 up arrow if (bhit=='1') { if(Menu) { /* Page up */ inx_mutex.lock(); startInx -= inxIncrement; startInx = startInx<0?0:startInx; inx_mutex.unlock(); printed_mutex.lock(); printed = false; printed_mutex.unlock(); } break; case '6': //button 6 down arrow if (bhit=='1') { if(Menu) { /* Page down */ inx_mutex.lock(); startInx += inxIncrement; startInx = startInx>songList.size()-songsPerPage?songList.size()-songsPerPage:startInx; inx_mutex.unlock(); printed_mutex.lock(); printed = false; printed_mutex.unlock(); } } break; case '7': //button 7 left arrow // stops the music from playing // does nothing if nothing is playing if (bhit=='1') { if(!Menu) { playing = false; Menu = 1; printed_mutex.lock(); printed =false; printed_mutex.unlock(); } } break; case '8': //button 8 right arrow // change to play menu and play music if (bhit=='1') { if(Menu) { lcd_mutex.lock(); uLCD.cls(); // Draw a playing icon uLCD.circle(60,40,40,GREEN); uLCD.triangle(45,70,45,10,95,40,GREEN); uLCD.locate(0,12); currSong_mutex.lock(); // Display current song playing uLCD.printf("%s playing...",currSong.substr(0,currSong.find(".wav"))); currSong_mutex.unlock(); lcd_mutex.unlock(); playing =true; Menu = 0; } } break; default: break; } } } } stdio_mutex.unlock(); } } Thread::wait(250); // wait .25s } } // Thread 2 // Play the currSong selected from the bluetooth controller // playing is a bool defined in the waveplayer as an extern variable that adds // play/stop functionality void thread2(void const *args) { while(true) { if(!Menu && playing && !(currSong == "")) { time_mutex.lock(); // restart songTime songTime=0; time_mutex.unlock(); string fileBuffer; currSong_mutex.lock(); // concatenate the directory with the song selected fileBuffer = "/sd/myMusic/" + currSong; currSong_mutex.unlock(); // convert to const char* for the wave_file to open const char* songToPlay = fileBuffer.c_str(); wave_file = fopen(songToPlay, "r"); waver.play(wave_file); fclose(wave_file); playing =false; Menu=1; printed_mutex.lock(); printed = false; printed_mutex.unlock(); } Thread::wait(500); // wait 0.5s } } int main() { uLCD.cls(); // Read all files on SD card into a string vector called songList // Make sure to lock appropriate mutexes DIR *dp; struct dirent *dirp; dp = opendir("/sd/myMusic"); numSongs = 0; if (dp != NULL) { lcd_mutex.lock(); stdio_mutex.lock(); while ((dirp = readdir(dp)) != NULL) { songList.push_back(string(dirp->d_name)); //uLCD.printf("\r%s\r\n", string(dirp->d_name)); numSongs++; } lcd_mutex.unlock(); stdio_mutex.unlock(); } else { uLCD.printf("Could not open directory!\n"); } closedir(dp); // Print songsPerPage # onto the LCD screen for (int i = 0; i < songsPerPage; i++) { lcd_mutex.lock(); uLCD.printf("\r%d. %s\r\n\r\n", (i+1), songList[startInx+i].substr(0,songList[startInx + i].find(".wav"))); lcd_mutex.unlock(); } printed = true; // Set bluetooth baudrate blue.baud(9600); // Start threading Thread t1(thread1); // bluetooth Thread t2(thread2); //song songTime=0; // Main thread - counts up songTime and displays the time the song has been // playing on LCD screen while(true) { // main is the next thread if(!Menu) { lcd_mutex.lock(); stdio_mutex.lock(); uLCD.locate(0,15); time_mutex.lock(); uLCD.printf("%d:%02d",songTime/60,songTime%60); songTime++; time_mutex.unlock(); lcd_mutex.unlock(); stdio_mutex.unlock(); } else { printed_mutex.lock(); if(!printed) { lcd_mutex.lock(); uLCD.cls(); for (int i = 0; i < songsPerPage; i++) { // Creates a substring out of the wave file names which takes out the .wav in the title uLCD.printf("\r%d. %s\r\n\r\n", (i+1), songList[startInx+i].substr(0,songList[startInx + i].find(".wav"))); } lcd_mutex.unlock(); printed =true; } printed_mutex.unlock(); } Thread::wait(1000); // Waits 1 second before updating songTime } }