MBED Bluetooth Controlled Party Bus

Dependencies:   4DGL-uLCD-SE Motor PinDetect SDFileSystem mbed wave_player

main.cpp

Committer:
jtgt21
Date:
2016-03-14
Revision:
0:36e81c32e784

File content as of revision 0:36e81c32e784:

#include "mbed.h"
#include "PinDetect.h"
#include "SDFileSystem.h"
#include "uLCD_4DGL.h"
#include "wave_player.h"
#include "Motor.h"
#include <vector>
#include <string>
//SDfile
SDFileSystem sd(p5, p6, p7, p8, p9, "sd"); //SD card
//Pushbuttons
PinDetect pbStop(p17);
//LEDS and Bluetooth Serial Pins
BusOut myled(LED1,LED2,LED3,LED4);
Serial blue(p13,p14); //tx, rx

//Motor
Motor m(p21, p22, p23); // pwm, fwd, rev
Motor m2(p26, p25, p24);


//uLCD
uLCD_4DGL uLCD(p28, p27, p29);
//Wave Player
AnalogOut DACout(p18);
wave_player waver(&DACout);
int pbPlays = 1;
//Create Music State
enum musicStateType {START, WAIT, WAIT2, LIST,REVERSE, NEXT, PLAY};
FILE *wave_file;
musicStateType musicState = START;
//Callback Functions
void pbUp_hit_callback (void)
{
    switch (musicState)
    {
    case WAIT:
        musicState = LIST;
        break;
    case WAIT2:   
        musicState = REVERSE;
        break;
    }
}
 
void pbDown_hit_callback (void)
{
    switch (musicState)
    {
    case WAIT:
        musicState = LIST;
        break;
    case WAIT2:
        musicState = NEXT;
        break; 
    }
}

void pbPlay_hit_callback (void)
{
    switch (musicState)
    {
    case WAIT:
        musicState = LIST;
        break;
    case WAIT2:   
        musicState = PLAY;
        break;
    case PLAY:
        pbPlays = 0;
        break;
    }
}

vector<string> filenames; //filenames are stored in a vector string
void read_file_names(char *dir)
{
DIR *dp;
struct dirent *dirp;
dp = opendir(dir);
//read all directory and file names in current directory into filename vector
while((dirp = readdir(dp)) != NULL) {
    filenames.push_back(string(dirp->d_name));
    }
 }

int main()
{
    //Setup for song stop pushbutton
    pbStop.mode(PullUp);
    wait(0.1);
    pbStop.attach_deasserted(&pbPlay_hit_callback);
    pbStop.setSampleFrequency();
    //intialize uLCD
    uLCD.display_control(PORTRAIT);
    uLCD.cls();
    uLCD.baudrate(BAUD_3000000);
    uLCD.background_color(BLACK);
    //initialize variables
    char bnum=0;
    char bhit=0;
    while(sd.SD_inserted() == false) {
      uLCD.cls();
      uLCD.printf("Insert SD Card!\n");
      wait(0.5);
    }
    int i = 0;
    vector<string>::iterator it=filenames.begin();
    vector<string>::iterator ittemp=filenames.begin();  
    //While loop for music state. state is initialized to Start 
    //and waits until a button is pressed to go to the music LIST state.   
    while (1) 
    {   
        switch (musicState)
        {
        case START:
            {
            read_file_names("/sd/myMusic");
            it = filenames.begin();
            ittemp = filenames.begin();
            uLCD.cls();
            uLCD.locate(0,0);
            uLCD.printf("MBED Party Bus!!!\n\n");
            uLCD.printf("Press Key to Start");
            musicState = WAIT;
            break;
            }
        case LIST:
            {
            pbPlays = 1;
            // read file names into vector of strings
            uLCD.cls();
            // print filename strings from vector using an iterator
            for(it = ittemp;it < filenames.end(); it++) 
            {   
            uLCD.printf("%s\n\r", (*it).substr(0, (*it).length()-4).c_str());
                        }
            }
            musicState = WAIT2;
            break;
        //Case for next song in list
        case NEXT:
            {
            if(ittemp == filenames.end())
            {ittemp = filenames.begin();
            musicState = LIST;}
            else
            {ittemp = ittemp++;
            musicState = LIST;}
            break;
            }
        //Case for previous song in list
        case REVERSE:    
            {
                if(ittemp == filenames.begin())
                {ittemp = filenames.begin();
                musicState = LIST;
                }
                else
                {ittemp = ittemp--;
                musicState = LIST;}
                break;
            }
        //Case to play selected song
        case PLAY:
            {
            uLCD.cls();
            uLCD.printf("%s\n\r", (*ittemp).substr(0, (*ittemp).length()-4).c_str());
            uLCD.printf("Now Playing");
            string filename = "/sd/myMusic/";
            filename = filename + (*ittemp);
            //If statements below deteremine which song is playing and what album artwork to show on uLCD screen
            if(filename == "/sd/myMusic/badboys2.wav"){
            uLCD.media_init();
            uLCD.set_sector_address(0x0000, 0x0000);
            uLCD.display_image(0,0);
            }
            if(filename == "/sd/myMusic/Childish_3005.wav"){
            uLCD.media_init();
            uLCD.set_sector_address(0x0000, 0x0041);
            uLCD.display_image(0,0);
            }
            if(filename == "/sd/myMusic/Drake.wav"){
            uLCD.media_init();
            uLCD.set_sector_address(0x0000, 0x0082);
            uLCD.display_image(0,0);
            }
            if(filename == "/sd/myMusic/Chase.wav"){
            uLCD.media_init();
            uLCD.set_sector_address(0x0000, 0x00C3);
            uLCD.display_image(0,0);
            }
            if(filename == "/sd/myMusic/Kanye.wav"){
            uLCD.media_init();
            uLCD.set_sector_address(0x0000, 0x0104);
            uLCD.display_image(0,0);
            }
            //Start up motor for robot. Left motor speed is faster because of weight on shadowbot(Can be changed). 
            m.speed(-0.4); 
            m2.speed(-0.55); 
            wave_file=fopen(filename.c_str(), "r");
            //Play song
            waver.play(wave_file, pbPlays);        
            fclose(wave_file);
            //Turn off robot motors
            m.speed(0);
            m2.speed(0);  
            //Return to music LIST
            musicState = LIST;
            break;
            }
        case WAIT:
            i++;
            //Commands for intial wait. The bluetooth commands for up, down, and right all change the music state to the LIST at startup
            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 '5': //button 5 up arrow
                            if (bhit=='1') {
                                //add hit code here
                            } else {
                                 pbUp_hit_callback();
                            }
                            break;
                        case '6': //button 6 down arrow
                            if (bhit=='1') {
                                //add hit code here
                            } else {
                                pbDown_hit_callback();//add release code here
                            }
                            break;
                        case '8': //button 8 right arrow
                            if (bhit=='1') {
                                //add hit code here
                            } else {
                                pbPlay_hit_callback();//add release code here
                            }
                            break;
                    }
                }
            }} 
            break;
        case WAIT2:
        if (blue.getc()=='!') {
            //Second wait function moves up and down in list with bluetooth commands. Right ble button plays the song here
            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 '5': //button 5 up arrow
                            if (bhit=='1') {
                                //add hit code here
                            } else {
                                 pbUp_hit_callback();
                            }
                            break;
                        case '6': //button 6 down arrow
                            if (bhit=='1') {
                                //add hit code here
                            } else {
                                pbDown_hit_callback();//add release code here
                            }
                            break;
                        case '8': //button 8 right arrow
                            if (bhit=='1') {
                                //add hit code here
                            } else {
                                pbPlay_hit_callback();//add release code here
                            }
                            break;
                    }
                }
            }} 
            i++;
            break;
        }
    }
}