inital commit

Dependencies:   mbed wave_player mbed-rtos 4DGL-uLCD-SE SDFileSystem2 PinDetect MMA8452

Committer:
lfink6
Date:
Wed Dec 15 17:17:26 2021 +0000
Revision:
11:1a47726ac72a
Parent:
10:5bd6abd66d12
Rev final;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
lfink6 11:1a47726ac72a 1 /**
lfink6 11:1a47726ac72a 2 * @file main.cpp
lfink6 11:1a47726ac72a 3 * @authors Christopher Rothmann (chrisrothmann@gatech.edu) & Luke Fink (lfink6@gatech.edu)
lfink6 11:1a47726ac72a 4 * @brief C++ Code to create an MP3 player from an mBED
lfink6 11:1a47726ac72a 5 * @version 1.0
lfink6 11:1a47726ac72a 6 * @date 2021-12-13
lfink6 11:1a47726ac72a 7 *
lfink6 11:1a47726ac72a 8 * @copyright Copyright (c) 2021
lfink6 11:1a47726ac72a 9 **/
lfink6 11:1a47726ac72a 10
lfink6 11:1a47726ac72a 11
lfink6 11:1a47726ac72a 12 // Define included libraries; all libraries below must be compiled together
lfink6 11:1a47726ac72a 13 // Note: Some libraries have been updated to work with this code. Ensure all libraries
lfink6 11:1a47726ac72a 14 // are the correct by using those included in this github
4180_1 1:5b8e223e983d 15 #include "mbed.h"
4180_1 2:c2afd0c426af 16 #include "rtos.h"
4180_1 1:5b8e223e983d 17 #include "SDFileSystem.h"
lfink6 3:8a1fd3450cb5 18 #include "uLCD_4DGL.h"
4180_1 1:5b8e223e983d 19 #include "wave_player.h"
lfink6 11:1a47726ac72a 20 #include "MMA8452.h"
lfink6 3:8a1fd3450cb5 21 #include "PinDetect.h"
lfink6 3:8a1fd3450cb5 22 #include <string>
lfink6 3:8a1fd3450cb5 23 #include <vector>
4180_1 1:5b8e223e983d 24
lfink6 11:1a47726ac72a 25 // Defining mBED inputs & outputs
4180_1 1:5b8e223e983d 26
lfink6 11:1a47726ac72a 27 // mBED LED Outputs for Audiovisualizer/Testing & Diagnostics
lfink6 11:1a47726ac72a 28 DigitalOut led1(LED1);
lfink6 11:1a47726ac72a 29 DigitalOut led2(LED2);
lfink6 11:1a47726ac72a 30 DigitalOut led3(LED3);
lfink6 11:1a47726ac72a 31 DigitalOut led4(LED4);
lfink6 3:8a1fd3450cb5 32
lfink6 11:1a47726ac72a 33 // Pushbuttons for MP3 Player Controls
lfink6 11:1a47726ac72a 34 PinDetect prev(p21);
lfink6 11:1a47726ac72a 35 PinDetect next(p22);
lfink6 11:1a47726ac72a 36 PinDetect shuffle(p23);
lfink6 11:1a47726ac72a 37 PinDetect play(p24);
4180_1 1:5b8e223e983d 38
lfink6 11:1a47726ac72a 39 // Serial & Analog Inputs & Ouputs for Data Communication
lfink6 11:1a47726ac72a 40 RawSerial blueTooth(p28,p27);
lfink6 11:1a47726ac72a 41 Serial pc(USBTX, USBRX);
lfink6 11:1a47726ac72a 42 SDFileSystem sd(p5, p6, p7, p12, "sd");
lfink6 11:1a47726ac72a 43 uLCD_4DGL uLCD(p13,p14,p11);
lfink6 11:1a47726ac72a 44 MMA8452 acc(p9, p10, 100000);
4180_1 1:5b8e223e983d 45 AnalogOut DACout(p18);
lfink6 11:1a47726ac72a 46 wave_player waver(&DACout);
4180_1 1:5b8e223e983d 47
lfink6 11:1a47726ac72a 48
lfink6 11:1a47726ac72a 49 // Defining Internal Global Variables
lfink6 6:6315ecdd0b47 50 bool playing = false;
lfink6 11:1a47726ac72a 51 int currentSong = 0;
lfink6 11:1a47726ac72a 52 int songCount = 0;
lfink6 11:1a47726ac72a 53 vector<string> songList;
lfink6 11:1a47726ac72a 54 unsigned short max_range = 0xFFFF;
lfink6 11:1a47726ac72a 55
lfink6 11:1a47726ac72a 56 // Defining Functions
lfink6 3:8a1fd3450cb5 57
lfink6 11:1a47726ac72a 58 /**
lfink6 11:1a47726ac72a 59 * @brief Increments integer variable currentSong by one, while circling back to first song at end of list
lfink6 11:1a47726ac72a 60 * @details Function is called both when "next song" pushbutton pressed or bluetooth command is sent;
lfink6 11:1a47726ac72a 61 * LED1 switches value when called for diagnostics & testing
lfink6 11:1a47726ac72a 62 **/
lfink6 11:1a47726ac72a 63 void nextSong()
lfink6 3:8a1fd3450cb5 64 {
lfink6 11:1a47726ac72a 65 //led1 = !led1;
lfink6 11:1a47726ac72a 66 if (currentSong == songCount - 1)
lfink6 3:8a1fd3450cb5 67 {
lfink6 11:1a47726ac72a 68 currentSong = 0;
lfink6 6:6315ecdd0b47 69 }
lfink6 6:6315ecdd0b47 70 else
lfink6 6:6315ecdd0b47 71 {
lfink6 11:1a47726ac72a 72 currentSong++;
lfink6 6:6315ecdd0b47 73 }
lfink6 3:8a1fd3450cb5 74 }
lfink6 11:1a47726ac72a 75
lfink6 11:1a47726ac72a 76 /**
lfink6 11:1a47726ac72a 77 * @brief Increments integer variable currentSong by minus one, while circling back to last song at zero
lfink6 11:1a47726ac72a 78 * @details Function is called both when "previous song" pushbutton pressed or bluetooth command is sent;
lfink6 11:1a47726ac72a 79 * LED2 switches value when called for diagnostics & testing
lfink6 11:1a47726ac72a 80 **/
lfink6 11:1a47726ac72a 81 void prevSong()
lfink6 3:8a1fd3450cb5 82 {
lfink6 11:1a47726ac72a 83 //led2 = !led2;
lfink6 11:1a47726ac72a 84 if (currentSong == 0)
lfink6 3:8a1fd3450cb5 85 {
lfink6 11:1a47726ac72a 86 currentSong = songCount - 1;
lfink6 3:8a1fd3450cb5 87 }
lfink6 3:8a1fd3450cb5 88 else
lfink6 3:8a1fd3450cb5 89 {
lfink6 11:1a47726ac72a 90 currentSong--;
lfink6 3:8a1fd3450cb5 91 }
lfink6 3:8a1fd3450cb5 92 }
lfink6 11:1a47726ac72a 93
lfink6 9:08886cc06a5d 94
lfink6 11:1a47726ac72a 95 /**
lfink6 11:1a47726ac72a 96 * @brief Switches boolean variable playing
lfink6 11:1a47726ac72a 97 * @details Function is called both when "pause/play" pushbutton pressed or bluetooth command is sent;
lfink6 11:1a47726ac72a 98 * LED3 switches value when called for diagnostics & testing
lfink6 11:1a47726ac72a 99 **/
lfink6 11:1a47726ac72a 100 void playSong()
lfink6 3:8a1fd3450cb5 101 {
lfink6 11:1a47726ac72a 102 //led3 = !led3;
lfink6 11:1a47726ac72a 103 playing = !playing;
lfink6 3:8a1fd3450cb5 104 }
lfink6 3:8a1fd3450cb5 105
lfink6 11:1a47726ac72a 106 /**
lfink6 11:1a47726ac72a 107 * @brief Generates random integer within song list range to assign integer variable currentSong
lfink6 11:1a47726ac72a 108 * @details Function is called both when "shuffle song" pushbutton pressed or bluetooth command is sent;
lfink6 11:1a47726ac72a 109 * function seeds a true random value through the noise present on the 5th decimal place of an
lfink6 11:1a47726ac72a 110 * accelerometer's input values;
lfink6 11:1a47726ac72a 111 * LED4 switches value when called for diagnostics & testing
lfink6 11:1a47726ac72a 112 **/
lfink6 11:1a47726ac72a 113 void shuffleSong()
4180_1 1:5b8e223e983d 114 {
lfink6 11:1a47726ac72a 115 //led4 = !led4;
lfink6 11:1a47726ac72a 116 double x, y, z;
lfink6 11:1a47726ac72a 117 acc.readXYZGravity(&x,&y,&z);
lfink6 11:1a47726ac72a 118 currentSong = int(100000 * (x + y + z)) % songCount;
lfink6 11:1a47726ac72a 119 }
lfink6 11:1a47726ac72a 120
lfink6 11:1a47726ac72a 121 // Defining Threads
lfink6 11:1a47726ac72a 122
lfink6 11:1a47726ac72a 123 /**
lfink6 11:1a47726ac72a 124 * @brief Updates LCD screen according to user input & selections
lfink6 11:1a47726ac72a 125 * @details First configures LCD screen layout & songlist, then continously checks for changes in global variables
lfink6 11:1a47726ac72a 126 * integer currentSong & boolean playing to update LCD screen accordingly. No updates made if no changes found.
lfink6 11:1a47726ac72a 127 * All LCD communications occur strictly in this thread.
lfink6 11:1a47726ac72a 128 * @param *arguments Input arguments to thread used for RTOS thread library. Not needed to understand thread code.
lfink6 11:1a47726ac72a 129 */
lfink6 11:1a47726ac72a 130 void LCDThread(void const *argument)
lfink6 11:1a47726ac72a 131 {
lfink6 11:1a47726ac72a 132 // Configure LCD screen
lfink6 3:8a1fd3450cb5 133 uLCD.cls();
lfink6 3:8a1fd3450cb5 134 uLCD.baudrate(3000000);
lfink6 3:8a1fd3450cb5 135 uLCD.background_color(BLACK);
lfink6 11:1a47726ac72a 136 uLCD.color(WHITE);
lfink6 3:8a1fd3450cb5 137 uLCD.text_width(1);
lfink6 11:1a47726ac72a 138 uLCD.text_height(1);
lfink6 11:1a47726ac72a 139
lfink6 11:1a47726ac72a 140 // Print Song List to LCD Screen
lfink6 11:1a47726ac72a 141 uLCD.locate(0,0);
lfink6 11:1a47726ac72a 142 uLCD.printf("Song List: ");
lfink6 11:1a47726ac72a 143 uLCD.locate(0,1);
lfink6 11:1a47726ac72a 144 uLCD.printf("->");
lfink6 11:1a47726ac72a 145 for(int i = 0; i < songCount; i++)
lfink6 11:1a47726ac72a 146 {
lfink6 11:1a47726ac72a 147 uLCD.locate(3,i+1);
lfink6 11:1a47726ac72a 148 uLCD.printf("%s\n\r", songList[i].substr(0,songList[i].find(".wav")));
lfink6 11:1a47726ac72a 149 }
lfink6 11:1a47726ac72a 150
lfink6 11:1a47726ac72a 151 // Print "NOW PLAYING: " & "STATUS: " feature; initialize to first song on SD card & paused
lfink6 11:1a47726ac72a 152 uLCD.locate(0,12);
lfink6 11:1a47726ac72a 153 uLCD.printf("NOW PLAYING:");
lfink6 11:1a47726ac72a 154 uLCD.locate(0,13);
lfink6 11:1a47726ac72a 155 uLCD.printf("%s", songList[currentSong].substr(0,songList[currentSong].find(".wav")));
lfink6 11:1a47726ac72a 156 uLCD.locate(0,14);
lfink6 11:1a47726ac72a 157 uLCD.printf("STATUS: PAUSED");
lfink6 11:1a47726ac72a 158
lfink6 11:1a47726ac72a 159 // Initialize internal thread variables to check for changes to external global variables
lfink6 11:1a47726ac72a 160 bool prevPlayLCD = false;
lfink6 11:1a47726ac72a 161 int previousSongLCD = 0;
lfink6 11:1a47726ac72a 162
lfink6 11:1a47726ac72a 163 // Thread while loop to continously check for changes and update screen accordingly
lfink6 11:1a47726ac72a 164 while (true)
lfink6 11:1a47726ac72a 165 {
lfink6 11:1a47726ac72a 166 // Check if new song has been selected
lfink6 11:1a47726ac72a 167 if (previousSongLCD != currentSong)
lfink6 11:1a47726ac72a 168 {
lfink6 11:1a47726ac72a 169 // Update "NOW PLAYING: " feature
lfink6 11:1a47726ac72a 170 uLCD.locate(0,12);
lfink6 11:1a47726ac72a 171 uLCD.printf("NOW PLAYING:");
lfink6 11:1a47726ac72a 172 uLCD.locate(0,13);
lfink6 11:1a47726ac72a 173 uLCD.printf("%s ", songList[currentSong].substr(0,songList[currentSong].find(".wav")));
lfink6 11:1a47726ac72a 174 // Update "->" feature
lfink6 11:1a47726ac72a 175 uLCD.locate(0, previousSongLCD + 1);
lfink6 11:1a47726ac72a 176 uLCD.printf(" ");
lfink6 11:1a47726ac72a 177 uLCD.locate(0, currentSong + 1);
lfink6 11:1a47726ac72a 178 uLCD.printf("->");
lfink6 11:1a47726ac72a 179 // Set internal change check to currentSong
lfink6 11:1a47726ac72a 180 previousSongLCD = currentSong;
lfink6 11:1a47726ac72a 181 }
lfink6 11:1a47726ac72a 182 //Check if change to play/pause status
lfink6 11:1a47726ac72a 183 if (prevPlayLCD != playing)
lfink6 11:1a47726ac72a 184 {
lfink6 11:1a47726ac72a 185 // Update "STATUS: " feature
lfink6 11:1a47726ac72a 186 uLCD.locate(0,14);
lfink6 11:1a47726ac72a 187 if (playing)
lfink6 11:1a47726ac72a 188 {
lfink6 11:1a47726ac72a 189 uLCD.printf("STATUS: PLAYING");
lfink6 11:1a47726ac72a 190 }
lfink6 11:1a47726ac72a 191 else
lfink6 11:1a47726ac72a 192 {
lfink6 11:1a47726ac72a 193 uLCD.printf("STATUS: PAUSED ");
lfink6 11:1a47726ac72a 194 }
lfink6 11:1a47726ac72a 195 // Set internal change check to playing
lfink6 11:1a47726ac72a 196 prevPlayLCD = playing;
lfink6 11:1a47726ac72a 197 }
lfink6 11:1a47726ac72a 198 Thread::wait(50);
lfink6 3:8a1fd3450cb5 199 }
lfink6 11:1a47726ac72a 200 }
lfink6 11:1a47726ac72a 201
lfink6 11:1a47726ac72a 202 /**
lfink6 11:1a47726ac72a 203 * @brief Updates phone screen to latest currentSong playing, sends phone commands to mBED, all over BlueTooth
lfink6 11:1a47726ac72a 204 * @details See commenting in thread for step-by-step approach
lfink6 11:1a47726ac72a 205 * All BlueTooth communications occur strictly in this thread
lfink6 11:1a47726ac72a 206 * BlueTooth Control Pad Module Controls: 1 = Pause/Play, 2 = Next Song, 3 = Previous Song, 4 = Shuffle Song
lfink6 11:1a47726ac72a 207 * @param *arguments Input arguments to thread used for RTOS thread library. Not needed to understand thread code.
lfink6 11:1a47726ac72a 208 */
lfink6 11:1a47726ac72a 209 void BluetoothThread(void const *argument)
lfink6 11:1a47726ac72a 210 {
lfink6 11:1a47726ac72a 211 // Initialize internal thread variable to check for changes to external global variables
lfink6 11:1a47726ac72a 212 int previousSongBLE = 0;
lfink6 11:1a47726ac72a 213 // Thread while look to continously check for BlueTooth commands and update currentSong on phone
lfink6 11:1a47726ac72a 214 while (true)
lfink6 11:1a47726ac72a 215 {
lfink6 11:1a47726ac72a 216 // Update currentSong on phone
lfink6 11:1a47726ac72a 217 if (blueTooth.writeable())
lfink6 11:1a47726ac72a 218 {
lfink6 11:1a47726ac72a 219 // Check if new song has been selected
lfink6 11:1a47726ac72a 220 if (previousSongBLE != currentSong)
lfink6 11:1a47726ac72a 221 {
lfink6 11:1a47726ac72a 222 // Send currentSong name over BlueTooth
lfink6 11:1a47726ac72a 223 string str = "Current Song: ";
lfink6 11:1a47726ac72a 224 for (int i = 0; i < 14; i++)
lfink6 11:1a47726ac72a 225 {
lfink6 11:1a47726ac72a 226 blueTooth.putc(str[i]);
lfink6 11:1a47726ac72a 227 }
lfink6 11:1a47726ac72a 228 for (int i = 0; i < songList[currentSong].size() - 4; i++)
lfink6 11:1a47726ac72a 229 {
lfink6 11:1a47726ac72a 230 blueTooth.putc(songList[currentSong][i]);
lfink6 11:1a47726ac72a 231 }
lfink6 11:1a47726ac72a 232 blueTooth.putc('\n');
lfink6 11:1a47726ac72a 233 previousSongBLE = currentSong;
lfink6 11:1a47726ac72a 234 }
lfink6 11:1a47726ac72a 235
lfink6 11:1a47726ac72a 236 }
lfink6 11:1a47726ac72a 237 // Read in commands from BlueTooth module
lfink6 11:1a47726ac72a 238 if (blueTooth.readable())
lfink6 11:1a47726ac72a 239 {
lfink6 11:1a47726ac72a 240 // Check for '!B' to be compatible with "Control Pad" Module serial output
lfink6 11:1a47726ac72a 241 if (blueTooth.getc()=='!')
lfink6 11:1a47726ac72a 242 {
lfink6 11:1a47726ac72a 243 if (blueTooth.getc()=='B')
lfink6 11:1a47726ac72a 244 {
lfink6 11:1a47726ac72a 245 // Check which command was hit
lfink6 11:1a47726ac72a 246 char bnum = blueTooth.getc();
lfink6 11:1a47726ac72a 247 // Ensure mBED only updates on release, not hit
lfink6 11:1a47726ac72a 248 char bhit = blueTooth.getc();
lfink6 11:1a47726ac72a 249 if (bhit == '0')
lfink6 11:1a47726ac72a 250 {
lfink6 11:1a47726ac72a 251 switch (bnum)
lfink6 11:1a47726ac72a 252 {
lfink6 11:1a47726ac72a 253 case '1':
lfink6 11:1a47726ac72a 254 playSong();
lfink6 11:1a47726ac72a 255 break;
lfink6 11:1a47726ac72a 256
lfink6 11:1a47726ac72a 257 case '2':
lfink6 11:1a47726ac72a 258 nextSong();
lfink6 11:1a47726ac72a 259 break;
lfink6 11:1a47726ac72a 260
lfink6 11:1a47726ac72a 261 case '3':
lfink6 11:1a47726ac72a 262 prevSong();
lfink6 11:1a47726ac72a 263 break;
lfink6 11:1a47726ac72a 264
lfink6 11:1a47726ac72a 265 case '4':
lfink6 11:1a47726ac72a 266 shuffleSong();
lfink6 11:1a47726ac72a 267 break;
lfink6 11:1a47726ac72a 268
lfink6 11:1a47726ac72a 269 default:
lfink6 11:1a47726ac72a 270 break;
lfink6 11:1a47726ac72a 271 }
lfink6 11:1a47726ac72a 272 }
lfink6 11:1a47726ac72a 273 }
lfink6 11:1a47726ac72a 274 }
lfink6 11:1a47726ac72a 275 }
lfink6 11:1a47726ac72a 276 Thread::wait(50);
lfink6 11:1a47726ac72a 277 }
lfink6 11:1a47726ac72a 278 }
lfink6 11:1a47726ac72a 279
lfink6 11:1a47726ac72a 280 /**
lfink6 11:1a47726ac72a 281 * @brief Updates Mbed LEDs to show current volume level
lfink6 11:1a47726ac72a 282 * @details Read and scales analogOut level, then sets leds to show the level in 4 tiers.
lfink6 11:1a47726ac72a 283 * @param *arguments Input arguments to thread used for RTOS thread library. Not needed to understand thread code.
lfink6 11:1a47726ac72a 284 */
lfink6 11:1a47726ac72a 285 void AudioVisualizerThread(void const *argument)
lfink6 11:1a47726ac72a 286 {
lfink6 11:1a47726ac72a 287 while(1)
lfink6 11:1a47726ac72a 288 {
lfink6 11:1a47726ac72a 289 if(playing)
lfink6 11:1a47726ac72a 290 {
lfink6 11:1a47726ac72a 291 float level = (DACout.read() - 0.25f) * 3.3f;
lfink6 11:1a47726ac72a 292 if(level<0.825)
lfink6 11:1a47726ac72a 293 {
lfink6 11:1a47726ac72a 294 led1=true;
lfink6 11:1a47726ac72a 295 led2=led3=led4=false;
lfink6 11:1a47726ac72a 296 }
lfink6 11:1a47726ac72a 297 else if(level>0.825&&level<1.65)
lfink6 11:1a47726ac72a 298 {
lfink6 11:1a47726ac72a 299 led1=led2=true;
lfink6 11:1a47726ac72a 300 led3=led4=false;
lfink6 11:1a47726ac72a 301 }
lfink6 11:1a47726ac72a 302 else if(level>1.65&&level<2.47)
lfink6 11:1a47726ac72a 303 {
lfink6 11:1a47726ac72a 304 led1=led2=led3=true;
lfink6 11:1a47726ac72a 305 led4=false;
lfink6 11:1a47726ac72a 306 }
lfink6 11:1a47726ac72a 307 else if(level>2.47)
lfink6 11:1a47726ac72a 308 {
lfink6 11:1a47726ac72a 309 led1=led2=led3=led4=true;
lfink6 11:1a47726ac72a 310 }
lfink6 11:1a47726ac72a 311 Thread::wait(50);
lfink6 11:1a47726ac72a 312 }
lfink6 11:1a47726ac72a 313 }
lfink6 11:1a47726ac72a 314 }
lfink6 11:1a47726ac72a 315
lfink6 11:1a47726ac72a 316 // Button Interupt Functions
lfink6 11:1a47726ac72a 317
lfink6 11:1a47726ac72a 318 /**
lfink6 11:1a47726ac72a 319 * @brief runs nextSong() function on pushbotton hit. Attached using PinDetect.
lfink6 11:1a47726ac72a 320 **/
lfink6 11:1a47726ac72a 321 void nextInt()
lfink6 11:1a47726ac72a 322 {
lfink6 11:1a47726ac72a 323 nextSong();
lfink6 11:1a47726ac72a 324 }
lfink6 11:1a47726ac72a 325
lfink6 11:1a47726ac72a 326 /**
lfink6 11:1a47726ac72a 327 * @brief runs prevSong() function on pushbotton hit. Attached using PinDetect.
lfink6 11:1a47726ac72a 328 **/
lfink6 11:1a47726ac72a 329 void prevInt()
lfink6 11:1a47726ac72a 330 {
lfink6 11:1a47726ac72a 331 prevSong();
lfink6 11:1a47726ac72a 332 }
lfink6 11:1a47726ac72a 333
lfink6 11:1a47726ac72a 334 /**
lfink6 11:1a47726ac72a 335 * @brief runs playSong() function on pushbotton hit. Attached using PinDetect.
lfink6 11:1a47726ac72a 336 **/
lfink6 11:1a47726ac72a 337 void playInt()
lfink6 11:1a47726ac72a 338 {
lfink6 11:1a47726ac72a 339 playSong();
lfink6 11:1a47726ac72a 340 }
lfink6 11:1a47726ac72a 341
lfink6 11:1a47726ac72a 342 /**
lfink6 11:1a47726ac72a 343 * @brief runs shuffleSong() function on pushbotton hit. Attached using PinDetect.
lfink6 11:1a47726ac72a 344 **/
lfink6 11:1a47726ac72a 345 void shuffleInt()
lfink6 11:1a47726ac72a 346 {
lfink6 11:1a47726ac72a 347 shuffleSong();
lfink6 11:1a47726ac72a 348 }
lfink6 11:1a47726ac72a 349
lfink6 11:1a47726ac72a 350 /**
lfink6 11:1a47726ac72a 351 * @brief Program main routine.
lfink6 11:1a47726ac72a 352 * @return int No return expected.
lfink6 11:1a47726ac72a 353 */
lfink6 11:1a47726ac72a 354 int main()
lfink6 11:1a47726ac72a 355 {
lfink6 11:1a47726ac72a 356 // Attach & configure interupts to pushbuttons
lfink6 11:1a47726ac72a 357 next.mode(PullUp);
lfink6 11:1a47726ac72a 358 prev.mode(PullUp);
lfink6 11:1a47726ac72a 359 play.mode(PullUp);
lfink6 11:1a47726ac72a 360 shuffle.mode(PullUp);
lfink6 11:1a47726ac72a 361 next.attach_deasserted(&nextInt);
lfink6 11:1a47726ac72a 362 prev.attach_deasserted(&prevInt);
lfink6 11:1a47726ac72a 363 play.attach_deasserted(&playInt);
lfink6 11:1a47726ac72a 364 shuffle.attach_deasserted(&shuffleInt);
lfink6 11:1a47726ac72a 365 next.setSampleFrequency();
lfink6 11:1a47726ac72a 366 prev.setSampleFrequency();
lfink6 11:1a47726ac72a 367 play.setSampleFrequency();
lfink6 11:1a47726ac72a 368 shuffle.setSampleFrequency();
lfink6 11:1a47726ac72a 369 // Wait 10 milliseconds to ensure functions are attached
lfink6 11:1a47726ac72a 370 Thread::wait(10);
lfink6 3:8a1fd3450cb5 371
lfink6 11:1a47726ac72a 372 // Extract file list from SD Card, place in vector<string> songList
lfink6 3:8a1fd3450cb5 373 DIR *dp;
lfink6 3:8a1fd3450cb5 374 struct dirent *dirp;
lfink6 3:8a1fd3450cb5 375 dp = opendir("/sd/myMusic");
lfink6 3:8a1fd3450cb5 376 if(dp !=NULL)
lfink6 3:8a1fd3450cb5 377 {
lfink6 3:8a1fd3450cb5 378 while ((dirp = readdir(dp)) != NULL) {
lfink6 3:8a1fd3450cb5 379 songList.push_back(string(dirp->d_name));
lfink6 11:1a47726ac72a 380 songCount++;
lfink6 3:8a1fd3450cb5 381 }
lfink6 3:8a1fd3450cb5 382 }
lfink6 11:1a47726ac72a 383 // Wait 10 miliseconds to ensure SD card communication complete
lfink6 11:1a47726ac72a 384 Thread::wait(10);
lfink6 3:8a1fd3450cb5 385
lfink6 11:1a47726ac72a 386 // Start LCD & BlueTooth Thread
lfink6 3:8a1fd3450cb5 387 Thread thread1(LCDThread);
lfink6 11:1a47726ac72a 388 Thread thread2(BluetoothThread);
lfink6 11:1a47726ac72a 389 Thread thread3(AudioVisualizerThread);
lfink6 11:1a47726ac72a 390
lfink6 11:1a47726ac72a 391 // Main while loop:
lfink6 11:1a47726ac72a 392 // Main loop is now considered the Speaker Thread, playing/pausing current song
lfink6 11:1a47726ac72a 393 // based on changes in global varaibles boolean playing & integer currentSong
lfink6 11:1a47726ac72a 394 while (true)
lfink6 11:1a47726ac72a 395 {
lfink6 11:1a47726ac72a 396 // Read in selected file
lfink6 11:1a47726ac72a 397 FILE *wave_file;
lfink6 11:1a47726ac72a 398 string selectedSong= "/sd/myMusic/" + songList[currentSong];
lfink6 11:1a47726ac72a 399 const char* song = selectedSong.c_str();
lfink6 11:1a47726ac72a 400 wave_file=fopen(song,"r");
lfink6 11:1a47726ac72a 401 if(wave_file==NULL)
lfink6 11:1a47726ac72a 402 {
lfink6 11:1a47726ac72a 403 uLCD.locate(0,12);
lfink6 11:1a47726ac72a 404 uLCD.printf("file open error!");
lfink6 11:1a47726ac72a 405 }
lfink6 11:1a47726ac72a 406 // Wait 10 miliseconds to ensure file properly loaded
lfink6 11:1a47726ac72a 407 Thread::wait(10);
lfink6 11:1a47726ac72a 408 // Play file; stop/play feature built into waver library
lfink6 11:1a47726ac72a 409 waver.play(wave_file);
lfink6 11:1a47726ac72a 410 // Close file
lfink6 11:1a47726ac72a 411 fclose(wave_file);
lfink6 11:1a47726ac72a 412 // Reset playing variable so song does not repeat
lfink6 11:1a47726ac72a 413 playing = false;
lfink6 3:8a1fd3450cb5 414 }
4180_1 1:5b8e223e983d 415 }