MBED Bluetooth Controlled Party Bus

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

Committer:
jtgt21
Date:
Mon Mar 14 17:18:53 2016 +0000
Revision:
0:36e81c32e784
commited

Who changed what in which revision?

UserRevisionLine numberNew contents of line
jtgt21 0:36e81c32e784 1 #include "mbed.h"
jtgt21 0:36e81c32e784 2 #include "PinDetect.h"
jtgt21 0:36e81c32e784 3 #include "SDFileSystem.h"
jtgt21 0:36e81c32e784 4 #include "uLCD_4DGL.h"
jtgt21 0:36e81c32e784 5 #include "wave_player.h"
jtgt21 0:36e81c32e784 6 #include "Motor.h"
jtgt21 0:36e81c32e784 7 #include <vector>
jtgt21 0:36e81c32e784 8 #include <string>
jtgt21 0:36e81c32e784 9 //SDfile
jtgt21 0:36e81c32e784 10 SDFileSystem sd(p5, p6, p7, p8, p9, "sd"); //SD card
jtgt21 0:36e81c32e784 11 //Pushbuttons
jtgt21 0:36e81c32e784 12 PinDetect pbStop(p17);
jtgt21 0:36e81c32e784 13 //LEDS and Bluetooth Serial Pins
jtgt21 0:36e81c32e784 14 BusOut myled(LED1,LED2,LED3,LED4);
jtgt21 0:36e81c32e784 15 Serial blue(p13,p14); //tx, rx
jtgt21 0:36e81c32e784 16
jtgt21 0:36e81c32e784 17 //Motor
jtgt21 0:36e81c32e784 18 Motor m(p21, p22, p23); // pwm, fwd, rev
jtgt21 0:36e81c32e784 19 Motor m2(p26, p25, p24);
jtgt21 0:36e81c32e784 20
jtgt21 0:36e81c32e784 21
jtgt21 0:36e81c32e784 22 //uLCD
jtgt21 0:36e81c32e784 23 uLCD_4DGL uLCD(p28, p27, p29);
jtgt21 0:36e81c32e784 24 //Wave Player
jtgt21 0:36e81c32e784 25 AnalogOut DACout(p18);
jtgt21 0:36e81c32e784 26 wave_player waver(&DACout);
jtgt21 0:36e81c32e784 27 int pbPlays = 1;
jtgt21 0:36e81c32e784 28 //Create Music State
jtgt21 0:36e81c32e784 29 enum musicStateType {START, WAIT, WAIT2, LIST,REVERSE, NEXT, PLAY};
jtgt21 0:36e81c32e784 30 FILE *wave_file;
jtgt21 0:36e81c32e784 31 musicStateType musicState = START;
jtgt21 0:36e81c32e784 32 //Callback Functions
jtgt21 0:36e81c32e784 33 void pbUp_hit_callback (void)
jtgt21 0:36e81c32e784 34 {
jtgt21 0:36e81c32e784 35 switch (musicState)
jtgt21 0:36e81c32e784 36 {
jtgt21 0:36e81c32e784 37 case WAIT:
jtgt21 0:36e81c32e784 38 musicState = LIST;
jtgt21 0:36e81c32e784 39 break;
jtgt21 0:36e81c32e784 40 case WAIT2:
jtgt21 0:36e81c32e784 41 musicState = REVERSE;
jtgt21 0:36e81c32e784 42 break;
jtgt21 0:36e81c32e784 43 }
jtgt21 0:36e81c32e784 44 }
jtgt21 0:36e81c32e784 45
jtgt21 0:36e81c32e784 46 void pbDown_hit_callback (void)
jtgt21 0:36e81c32e784 47 {
jtgt21 0:36e81c32e784 48 switch (musicState)
jtgt21 0:36e81c32e784 49 {
jtgt21 0:36e81c32e784 50 case WAIT:
jtgt21 0:36e81c32e784 51 musicState = LIST;
jtgt21 0:36e81c32e784 52 break;
jtgt21 0:36e81c32e784 53 case WAIT2:
jtgt21 0:36e81c32e784 54 musicState = NEXT;
jtgt21 0:36e81c32e784 55 break;
jtgt21 0:36e81c32e784 56 }
jtgt21 0:36e81c32e784 57 }
jtgt21 0:36e81c32e784 58
jtgt21 0:36e81c32e784 59 void pbPlay_hit_callback (void)
jtgt21 0:36e81c32e784 60 {
jtgt21 0:36e81c32e784 61 switch (musicState)
jtgt21 0:36e81c32e784 62 {
jtgt21 0:36e81c32e784 63 case WAIT:
jtgt21 0:36e81c32e784 64 musicState = LIST;
jtgt21 0:36e81c32e784 65 break;
jtgt21 0:36e81c32e784 66 case WAIT2:
jtgt21 0:36e81c32e784 67 musicState = PLAY;
jtgt21 0:36e81c32e784 68 break;
jtgt21 0:36e81c32e784 69 case PLAY:
jtgt21 0:36e81c32e784 70 pbPlays = 0;
jtgt21 0:36e81c32e784 71 break;
jtgt21 0:36e81c32e784 72 }
jtgt21 0:36e81c32e784 73 }
jtgt21 0:36e81c32e784 74
jtgt21 0:36e81c32e784 75 vector<string> filenames; //filenames are stored in a vector string
jtgt21 0:36e81c32e784 76 void read_file_names(char *dir)
jtgt21 0:36e81c32e784 77 {
jtgt21 0:36e81c32e784 78 DIR *dp;
jtgt21 0:36e81c32e784 79 struct dirent *dirp;
jtgt21 0:36e81c32e784 80 dp = opendir(dir);
jtgt21 0:36e81c32e784 81 //read all directory and file names in current directory into filename vector
jtgt21 0:36e81c32e784 82 while((dirp = readdir(dp)) != NULL) {
jtgt21 0:36e81c32e784 83 filenames.push_back(string(dirp->d_name));
jtgt21 0:36e81c32e784 84 }
jtgt21 0:36e81c32e784 85 }
jtgt21 0:36e81c32e784 86
jtgt21 0:36e81c32e784 87 int main()
jtgt21 0:36e81c32e784 88 {
jtgt21 0:36e81c32e784 89 //Setup for song stop pushbutton
jtgt21 0:36e81c32e784 90 pbStop.mode(PullUp);
jtgt21 0:36e81c32e784 91 wait(0.1);
jtgt21 0:36e81c32e784 92 pbStop.attach_deasserted(&pbPlay_hit_callback);
jtgt21 0:36e81c32e784 93 pbStop.setSampleFrequency();
jtgt21 0:36e81c32e784 94 //intialize uLCD
jtgt21 0:36e81c32e784 95 uLCD.display_control(PORTRAIT);
jtgt21 0:36e81c32e784 96 uLCD.cls();
jtgt21 0:36e81c32e784 97 uLCD.baudrate(BAUD_3000000);
jtgt21 0:36e81c32e784 98 uLCD.background_color(BLACK);
jtgt21 0:36e81c32e784 99 //initialize variables
jtgt21 0:36e81c32e784 100 char bnum=0;
jtgt21 0:36e81c32e784 101 char bhit=0;
jtgt21 0:36e81c32e784 102 while(sd.SD_inserted() == false) {
jtgt21 0:36e81c32e784 103 uLCD.cls();
jtgt21 0:36e81c32e784 104 uLCD.printf("Insert SD Card!\n");
jtgt21 0:36e81c32e784 105 wait(0.5);
jtgt21 0:36e81c32e784 106 }
jtgt21 0:36e81c32e784 107 int i = 0;
jtgt21 0:36e81c32e784 108 vector<string>::iterator it=filenames.begin();
jtgt21 0:36e81c32e784 109 vector<string>::iterator ittemp=filenames.begin();
jtgt21 0:36e81c32e784 110 //While loop for music state. state is initialized to Start
jtgt21 0:36e81c32e784 111 //and waits until a button is pressed to go to the music LIST state.
jtgt21 0:36e81c32e784 112 while (1)
jtgt21 0:36e81c32e784 113 {
jtgt21 0:36e81c32e784 114 switch (musicState)
jtgt21 0:36e81c32e784 115 {
jtgt21 0:36e81c32e784 116 case START:
jtgt21 0:36e81c32e784 117 {
jtgt21 0:36e81c32e784 118 read_file_names("/sd/myMusic");
jtgt21 0:36e81c32e784 119 it = filenames.begin();
jtgt21 0:36e81c32e784 120 ittemp = filenames.begin();
jtgt21 0:36e81c32e784 121 uLCD.cls();
jtgt21 0:36e81c32e784 122 uLCD.locate(0,0);
jtgt21 0:36e81c32e784 123 uLCD.printf("MBED Party Bus!!!\n\n");
jtgt21 0:36e81c32e784 124 uLCD.printf("Press Key to Start");
jtgt21 0:36e81c32e784 125 musicState = WAIT;
jtgt21 0:36e81c32e784 126 break;
jtgt21 0:36e81c32e784 127 }
jtgt21 0:36e81c32e784 128 case LIST:
jtgt21 0:36e81c32e784 129 {
jtgt21 0:36e81c32e784 130 pbPlays = 1;
jtgt21 0:36e81c32e784 131 // read file names into vector of strings
jtgt21 0:36e81c32e784 132 uLCD.cls();
jtgt21 0:36e81c32e784 133 // print filename strings from vector using an iterator
jtgt21 0:36e81c32e784 134 for(it = ittemp;it < filenames.end(); it++)
jtgt21 0:36e81c32e784 135 {
jtgt21 0:36e81c32e784 136 uLCD.printf("%s\n\r", (*it).substr(0, (*it).length()-4).c_str());
jtgt21 0:36e81c32e784 137 }
jtgt21 0:36e81c32e784 138 }
jtgt21 0:36e81c32e784 139 musicState = WAIT2;
jtgt21 0:36e81c32e784 140 break;
jtgt21 0:36e81c32e784 141 //Case for next song in list
jtgt21 0:36e81c32e784 142 case NEXT:
jtgt21 0:36e81c32e784 143 {
jtgt21 0:36e81c32e784 144 if(ittemp == filenames.end())
jtgt21 0:36e81c32e784 145 {ittemp = filenames.begin();
jtgt21 0:36e81c32e784 146 musicState = LIST;}
jtgt21 0:36e81c32e784 147 else
jtgt21 0:36e81c32e784 148 {ittemp = ittemp++;
jtgt21 0:36e81c32e784 149 musicState = LIST;}
jtgt21 0:36e81c32e784 150 break;
jtgt21 0:36e81c32e784 151 }
jtgt21 0:36e81c32e784 152 //Case for previous song in list
jtgt21 0:36e81c32e784 153 case REVERSE:
jtgt21 0:36e81c32e784 154 {
jtgt21 0:36e81c32e784 155 if(ittemp == filenames.begin())
jtgt21 0:36e81c32e784 156 {ittemp = filenames.begin();
jtgt21 0:36e81c32e784 157 musicState = LIST;
jtgt21 0:36e81c32e784 158 }
jtgt21 0:36e81c32e784 159 else
jtgt21 0:36e81c32e784 160 {ittemp = ittemp--;
jtgt21 0:36e81c32e784 161 musicState = LIST;}
jtgt21 0:36e81c32e784 162 break;
jtgt21 0:36e81c32e784 163 }
jtgt21 0:36e81c32e784 164 //Case to play selected song
jtgt21 0:36e81c32e784 165 case PLAY:
jtgt21 0:36e81c32e784 166 {
jtgt21 0:36e81c32e784 167 uLCD.cls();
jtgt21 0:36e81c32e784 168 uLCD.printf("%s\n\r", (*ittemp).substr(0, (*ittemp).length()-4).c_str());
jtgt21 0:36e81c32e784 169 uLCD.printf("Now Playing");
jtgt21 0:36e81c32e784 170 string filename = "/sd/myMusic/";
jtgt21 0:36e81c32e784 171 filename = filename + (*ittemp);
jtgt21 0:36e81c32e784 172 //If statements below deteremine which song is playing and what album artwork to show on uLCD screen
jtgt21 0:36e81c32e784 173 if(filename == "/sd/myMusic/badboys2.wav"){
jtgt21 0:36e81c32e784 174 uLCD.media_init();
jtgt21 0:36e81c32e784 175 uLCD.set_sector_address(0x0000, 0x0000);
jtgt21 0:36e81c32e784 176 uLCD.display_image(0,0);
jtgt21 0:36e81c32e784 177 }
jtgt21 0:36e81c32e784 178 if(filename == "/sd/myMusic/Childish_3005.wav"){
jtgt21 0:36e81c32e784 179 uLCD.media_init();
jtgt21 0:36e81c32e784 180 uLCD.set_sector_address(0x0000, 0x0041);
jtgt21 0:36e81c32e784 181 uLCD.display_image(0,0);
jtgt21 0:36e81c32e784 182 }
jtgt21 0:36e81c32e784 183 if(filename == "/sd/myMusic/Drake.wav"){
jtgt21 0:36e81c32e784 184 uLCD.media_init();
jtgt21 0:36e81c32e784 185 uLCD.set_sector_address(0x0000, 0x0082);
jtgt21 0:36e81c32e784 186 uLCD.display_image(0,0);
jtgt21 0:36e81c32e784 187 }
jtgt21 0:36e81c32e784 188 if(filename == "/sd/myMusic/Chase.wav"){
jtgt21 0:36e81c32e784 189 uLCD.media_init();
jtgt21 0:36e81c32e784 190 uLCD.set_sector_address(0x0000, 0x00C3);
jtgt21 0:36e81c32e784 191 uLCD.display_image(0,0);
jtgt21 0:36e81c32e784 192 }
jtgt21 0:36e81c32e784 193 if(filename == "/sd/myMusic/Kanye.wav"){
jtgt21 0:36e81c32e784 194 uLCD.media_init();
jtgt21 0:36e81c32e784 195 uLCD.set_sector_address(0x0000, 0x0104);
jtgt21 0:36e81c32e784 196 uLCD.display_image(0,0);
jtgt21 0:36e81c32e784 197 }
jtgt21 0:36e81c32e784 198 //Start up motor for robot. Left motor speed is faster because of weight on shadowbot(Can be changed).
jtgt21 0:36e81c32e784 199 m.speed(-0.4);
jtgt21 0:36e81c32e784 200 m2.speed(-0.55);
jtgt21 0:36e81c32e784 201 wave_file=fopen(filename.c_str(), "r");
jtgt21 0:36e81c32e784 202 //Play song
jtgt21 0:36e81c32e784 203 waver.play(wave_file, pbPlays);
jtgt21 0:36e81c32e784 204 fclose(wave_file);
jtgt21 0:36e81c32e784 205 //Turn off robot motors
jtgt21 0:36e81c32e784 206 m.speed(0);
jtgt21 0:36e81c32e784 207 m2.speed(0);
jtgt21 0:36e81c32e784 208 //Return to music LIST
jtgt21 0:36e81c32e784 209 musicState = LIST;
jtgt21 0:36e81c32e784 210 break;
jtgt21 0:36e81c32e784 211 }
jtgt21 0:36e81c32e784 212 case WAIT:
jtgt21 0:36e81c32e784 213 i++;
jtgt21 0:36e81c32e784 214 //Commands for intial wait. The bluetooth commands for up, down, and right all change the music state to the LIST at startup
jtgt21 0:36e81c32e784 215 if (blue.getc()=='!') {
jtgt21 0:36e81c32e784 216 if (blue.getc()=='B') { //button data packet
jtgt21 0:36e81c32e784 217 bnum = blue.getc(); //button number
jtgt21 0:36e81c32e784 218 bhit = blue.getc(); //1=hit, 0=release
jtgt21 0:36e81c32e784 219 if (blue.getc()==char(~('!' + 'B' + bnum + bhit))) { //checksum OK?
jtgt21 0:36e81c32e784 220 myled = bnum - '0'; //current button number will appear on LEDs
jtgt21 0:36e81c32e784 221 switch (bnum) {
jtgt21 0:36e81c32e784 222 case '5': //button 5 up arrow
jtgt21 0:36e81c32e784 223 if (bhit=='1') {
jtgt21 0:36e81c32e784 224 //add hit code here
jtgt21 0:36e81c32e784 225 } else {
jtgt21 0:36e81c32e784 226 pbUp_hit_callback();
jtgt21 0:36e81c32e784 227 }
jtgt21 0:36e81c32e784 228 break;
jtgt21 0:36e81c32e784 229 case '6': //button 6 down arrow
jtgt21 0:36e81c32e784 230 if (bhit=='1') {
jtgt21 0:36e81c32e784 231 //add hit code here
jtgt21 0:36e81c32e784 232 } else {
jtgt21 0:36e81c32e784 233 pbDown_hit_callback();//add release code here
jtgt21 0:36e81c32e784 234 }
jtgt21 0:36e81c32e784 235 break;
jtgt21 0:36e81c32e784 236 case '8': //button 8 right arrow
jtgt21 0:36e81c32e784 237 if (bhit=='1') {
jtgt21 0:36e81c32e784 238 //add hit code here
jtgt21 0:36e81c32e784 239 } else {
jtgt21 0:36e81c32e784 240 pbPlay_hit_callback();//add release code here
jtgt21 0:36e81c32e784 241 }
jtgt21 0:36e81c32e784 242 break;
jtgt21 0:36e81c32e784 243 }
jtgt21 0:36e81c32e784 244 }
jtgt21 0:36e81c32e784 245 }}
jtgt21 0:36e81c32e784 246 break;
jtgt21 0:36e81c32e784 247 case WAIT2:
jtgt21 0:36e81c32e784 248 if (blue.getc()=='!') {
jtgt21 0:36e81c32e784 249 //Second wait function moves up and down in list with bluetooth commands. Right ble button plays the song here
jtgt21 0:36e81c32e784 250 if (blue.getc()=='B') { //button data packet
jtgt21 0:36e81c32e784 251 bnum = blue.getc(); //button number
jtgt21 0:36e81c32e784 252 bhit = blue.getc(); //1=hit, 0=release
jtgt21 0:36e81c32e784 253 if (blue.getc()==char(~('!' + 'B' + bnum + bhit))) { //checksum OK?
jtgt21 0:36e81c32e784 254 myled = bnum - '0'; //current button number will appear on LEDs
jtgt21 0:36e81c32e784 255 switch (bnum) {
jtgt21 0:36e81c32e784 256 case '5': //button 5 up arrow
jtgt21 0:36e81c32e784 257 if (bhit=='1') {
jtgt21 0:36e81c32e784 258 //add hit code here
jtgt21 0:36e81c32e784 259 } else {
jtgt21 0:36e81c32e784 260 pbUp_hit_callback();
jtgt21 0:36e81c32e784 261 }
jtgt21 0:36e81c32e784 262 break;
jtgt21 0:36e81c32e784 263 case '6': //button 6 down arrow
jtgt21 0:36e81c32e784 264 if (bhit=='1') {
jtgt21 0:36e81c32e784 265 //add hit code here
jtgt21 0:36e81c32e784 266 } else {
jtgt21 0:36e81c32e784 267 pbDown_hit_callback();//add release code here
jtgt21 0:36e81c32e784 268 }
jtgt21 0:36e81c32e784 269 break;
jtgt21 0:36e81c32e784 270 case '8': //button 8 right arrow
jtgt21 0:36e81c32e784 271 if (bhit=='1') {
jtgt21 0:36e81c32e784 272 //add hit code here
jtgt21 0:36e81c32e784 273 } else {
jtgt21 0:36e81c32e784 274 pbPlay_hit_callback();//add release code here
jtgt21 0:36e81c32e784 275 }
jtgt21 0:36e81c32e784 276 break;
jtgt21 0:36e81c32e784 277 }
jtgt21 0:36e81c32e784 278 }
jtgt21 0:36e81c32e784 279 }}
jtgt21 0:36e81c32e784 280 i++;
jtgt21 0:36e81c32e784 281 break;
jtgt21 0:36e81c32e784 282 }
jtgt21 0:36e81c32e784 283 }
jtgt21 0:36e81c32e784 284 }
jtgt21 0:36e81c32e784 285