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: mbed SDFileSystem NeoStrip PinDetect
main.cpp
00001 #include "mbed.h" 00002 #include "PinDetect.h" 00003 #include "NeoStrip.h" 00004 #include "SDFileSystem.h" 00005 #include "wave_player.h" 00006 #include "rtos.h" 00007 #include <string> 00008 #include <vector> 00009 00010 # define MAX_FILE 30 00011 00012 #define N 40 00013 NeoStrip strip(p21, N); 00014 00015 DigitalOut myled(LED1); 00016 00017 DigitalIn b2(p29, PullUp); 00018 Serial pc(USBTX, USBRX); 00019 SDFileSystem sd(p5, p6, p7, p8, "sd"); 00020 Ticker sampletick; 00021 AnalogOut speaker(p18); // Speaker (pin) 00022 wave_player waver(&speaker); 00023 Serial bt(p28, p27); // Bluetooth 00024 DigitalOut mute(p29); // mute pin (low for shutdown) 00025 00026 PwmOut spk(p24); 00027 00028 Thread thread1; 00029 Thread thread2; 00030 Thread thread3; 00031 Mutex sd_mtx; 00032 volatile int src = 1; // 0 for Mic, 1 for SD card 00033 00034 vector<string> filenames; // list of files in sd card 00035 volatile int cur_song = 1; 00036 00037 void read_file_names(char *dir) { 00038 DIR *dp; 00039 struct dirent *dirp; 00040 dp = opendir(dir); 00041 while ((dirp = readdir(dp)) != NULL) { 00042 filenames.push_back(string(dirp->d_name)); 00043 } 00044 closedir(dp); 00045 } 00046 00047 class microphone 00048 { 00049 public : 00050 microphone(PinName pin); 00051 float read(); 00052 operator float (); 00053 private : 00054 AnalogIn _pin; 00055 }; 00056 microphone::microphone (PinName pin): 00057 _pin(pin) 00058 { 00059 } 00060 float microphone::read() 00061 { 00062 return _pin.read(); 00063 } 00064 inline microphone::operator float () 00065 { 00066 return _pin.read(); 00067 } 00068 00069 microphone mymicrophone(p16); 00070 00071 uint8_t r = (uint8_t)0; 00072 uint8_t g = (uint8_t)128; 00073 uint8_t b = (uint8_t)0; 00074 00075 int red, green, blue; 00076 00077 // fancy function to make rainbow colors on LEDs 00078 int hueToRGB(float h) 00079 { 00080 float r, g, b; 00081 if (h > 360) 00082 h -= 360; 00083 if (h < 0) 00084 h += 360; 00085 int i = (int)(h / 60.0); 00086 float f = (h / 60.0) - i; 00087 float q = 1 - f; 00088 00089 switch (i % 6) 00090 { 00091 case 0: r = 1; g = f; b = 0; break; 00092 case 1: r = q; g = 1; b = 0; break; 00093 case 2: r = 0; g = 1; b = f; break; 00094 case 3: r = 0; g = q; b = 1; break; 00095 case 4: r = f; g = 0; b = 1; break; 00096 case 5: r = 1; g = 0; b = q; break; 00097 default: r = 0; g = 0; b = 0; break; 00098 } 00099 00100 // scale to integers and return the packed value 00101 uint8_t R = (uint8_t)(r * 255); 00102 uint8_t G = (uint8_t)(g * 255); 00103 uint8_t B = (uint8_t)(b * 255); 00104 00105 return (R << 16) | (G << 8) | B; 00106 } 00107 00108 // convert float values to LED otuput for soundtest array 00109 void float2LED(float value){ 00110 float fnumLED = abs((value - 0.5)/3.3)*100; // can mess with this scaling for better LED output 00111 int numLED = (int)fnumLED; 00112 if (numLED > 8) numLED = 8; 00113 00114 static float dh = 360.0 / 5; 00115 static float x = 0; 00116 00117 for(int i = 0; i < numLED; i++){ 00118 int c = hueToRGB((dh * i) - x); 00119 strip.setPixel(i, c); 00120 strip.setPixel(i + 8, c); 00121 strip.setPixel(i + 16, c); 00122 strip.setPixel(i + 24, c); 00123 strip.setPixel(i + 32, c); 00124 } 00125 for(int i = numLED; i < 8; i++){ 00126 strip.setPixel(i, 0x000000); 00127 strip.setPixel(i + 8, 0x000000); 00128 strip.setPixel(i + 16, 0x000000); 00129 strip.setPixel(i + 24, 0x000000); 00130 strip.setPixel(i + 32, 0x000000); 00131 } 00132 x += 1; 00133 if (x > 360) 00134 x = 0; 00135 } 00136 00137 // same thing but for the mic 00138 void mic2LED(int mic){ 00139 static float dh = 360.0 / 5; 00140 static float x = 0; 00141 00142 int numLED = 0; 00143 if(mic == 0) numLED = 0; 00144 else if(mic == 1) numLED = 1; 00145 else if(mic == 2) numLED = 2; 00146 else if(mic == 3) numLED = 3; 00147 else if(mic == 4) numLED = 4; 00148 else if(mic == 5) numLED = 5; 00149 else if(mic == 6) numLED = 6; 00150 else if(mic == 7) numLED = 7; 00151 else if(mic == 8) numLED = 8; 00152 00153 for(int i = 0; i < numLED; i++){ 00154 int c = hueToRGB((dh * i) - x); 00155 strip.setPixel(i, c); 00156 strip.setPixel(i + 8, c); 00157 strip.setPixel(i + 16, c); 00158 strip.setPixel(i + 24, c); 00159 strip.setPixel(i + 32, c); 00160 } 00161 for(int i = numLED; i < 8; i++){ 00162 strip.setPixel(i, 0x000000); 00163 strip.setPixel(i + 8, 0x000000); 00164 strip.setPixel(i + 16, 0x000000); 00165 strip.setPixel(i + 24, 0x000000); 00166 strip.setPixel(i + 32, 0x000000); 00167 } 00168 x += 1; 00169 if (x > 360) 00170 x = 0; 00171 } 00172 00173 00174 void sound_thread() { 00175 FILE *wave_file; 00176 printf("\n\n\nHello, wave world!\n"); 00177 string songstr = "/sd/songs/" + filenames[cur_song]; 00178 printf("%s", songstr.c_str()); 00179 wave_file=fopen(songstr.c_str(),"r"); 00180 printf("file opened\n"); 00181 waver.play(wave_file); 00182 fclose(wave_file); 00183 Thread::yield(); 00184 } 00185 00186 unsigned short max_range = 0xFFFF; 00187 // function that calls above functions 00188 void patternSound(){ 00189 //for(int i = 0; i < 60; i++){ 00190 float sample; 00191 float average = 0.67/3.3;//initial DC bias level 00192 00193 int buffer[20]; 00194 00195 while(1){ 00196 if (src) { 00197 // this part works for DAC PCM output // 00198 float test = (float)waver.dac_data/max_range; 00199 pc.printf("--%f", abs((test - 0.5)/3.3)); 00200 float2LED(test); 00201 strip.write(); 00202 } 00203 //------------------------------------// 00204 else { 00205 //microphone setup // 00206 int centervalue; 00207 for(int i = 0; i < 20; i++){ 00208 sample = mymicrophone; 00209 //subtract 0.67V DC bias - but it varies quite a bit after loud or long sounds 00210 average = 0.9999*average + 0.0001*sample;//try to slowly auto adjust the DC bias level 00211 speaker = 0.5 +((sample - average)*33.0);//scale up to 0.0 to 1.0 for speaker output 00212 00213 int micvalue = int(abs((sample - average)*300.0)); 00214 //pc.printf("-%d-", micvalue); //scale to around 15 for LEDs 00215 00216 if(i == 1){ 00217 centervalue = micvalue; 00218 } 00219 buffer[i] = micvalue; 00220 if(i > 10){ 00221 if(micvalue == buffer[1] && micvalue == buffer[2] && micvalue == buffer[3] && 00222 micvalue == buffer[4] && micvalue == buffer[5] && micvalue == buffer[6] && 00223 micvalue == buffer[7] && micvalue == buffer[8] && micvalue == buffer[9]){ 00224 centervalue = buffer[1]; 00225 } 00226 } 00227 int offset = micvalue-centervalue; 00228 mic2LED(2+offset); 00229 wait(1.0/4000.0); 00230 } 00231 strip.write(); 00232 Thread::wait(10); 00233 } 00234 } 00235 } 00236 00237 void bt_thread() { 00238 char bnum = 0; 00239 char bhit = 0; 00240 while(1) { 00241 if (bt.readable()) { 00242 if (bt.getc()=='!') { 00243 if (bt.getc()=='B') { //button data 00244 bnum = bt.getc(); //button number 00245 bhit = bt.getc(); //1 = hit, 0 = release 00246 if (bhit == '1') { 00247 switch (bnum) { 00248 case '1': // Button 1 for play/pause 00249 if (src) { 00250 if (waver.get_play_state() == 1) { 00251 waver.set_play_state(0); 00252 thread2.terminate(); 00253 mute = 0; 00254 } else if (waver.get_play_state() == 0) { 00255 waver.set_play_state(1); 00256 thread2.start(sound_thread); 00257 mute = 1; 00258 } 00259 } 00260 break; 00261 case '2': // Button 2 for mute/unmute 00262 mute = !mute; 00263 break; 00264 case '3': // Button 3 to switch between mic/sd 00265 if (sd_mtx.trylock()) { 00266 sd_mtx.lock(); 00267 src = src ? 0 : 1; 00268 if (src) { 00269 waver.set_play_state(1); 00270 thread2.start(sound_thread); 00271 mute = 1; 00272 } else { 00273 waver.set_play_state(0); 00274 while (thread2.get_state() == Thread::Running) { 00275 Thread::yield(); 00276 } 00277 thread2.terminate(); 00278 mute = 0; 00279 } 00280 sd_mtx.unlock(); 00281 Thread::wait(100); 00282 } 00283 break; 00284 case '7': // Left arrow for previous 00285 if (sd_mtx.trylock() && src) { 00286 sd_mtx.lock(); 00287 waver.set_play_state(0); 00288 if (cur_song > 0) { 00289 --cur_song; 00290 } 00291 while (thread2.get_state() == Thread::Running) { 00292 Thread::yield(); 00293 } 00294 thread2.terminate(); 00295 thread2.start(sound_thread); 00296 waver.set_play_state(1); 00297 sd_mtx.unlock(); 00298 } 00299 break; 00300 case '8': // Right arrow for skip 00301 if (sd_mtx.trylock() && src) { 00302 sd_mtx.lock(); 00303 waver.set_play_state(0); 00304 if (cur_song < filenames.size() - 1) { 00305 ++cur_song; 00306 } 00307 while (thread2.get_state() == Thread::Running) { 00308 Thread::yield(); 00309 } 00310 thread2.terminate(); 00311 thread2.start(sound_thread); 00312 waver.set_play_state(1); 00313 sd_mtx.unlock(); 00314 } 00315 break; 00316 default: 00317 break; 00318 } 00319 } 00320 } 00321 } 00322 } 00323 Thread::wait(100); 00324 } 00325 } 00326 00327 int main() { 00328 read_file_names("/sd/songs"); 00329 00330 strip.setBrightness(0.05); 00331 00332 mute = 1; 00333 00334 thread1.start(bt_thread); 00335 thread2.start(sound_thread); 00336 thread3.start(patternSound); 00337 00338 while(1){ 00339 myled = !myled; 00340 Thread::wait(100); 00341 } 00342 } 00343
Generated on Thu Jul 14 2022 18:24:45 by
1.7.2