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 mbed-rtos 4DGL-uLCD-SE FFT PinDetect MAX4466
main.cpp
00001 #include "mbed.h" 00002 #include "MAX4466.h" 00003 #include "FFT.h" 00004 #include "rtos.h" 00005 #include "uLCD_4DGL.h" 00006 #include "PinDetect.h" 00007 #include <string> 00008 #include <math.h> 00009 00010 00011 PinDetect pb1(p6); 00012 PinDetect pb2(p7); 00013 PinDetect pb3(p8); 00014 PinDetect pb4(p9); 00015 DigitalIn pb5 (p10); 00016 MAX4466 mic(p15); 00017 PwmOut speaker(p21); 00018 uLCD_4DGL uLCD(p28,p27,p30); 00019 Timer tim; 00020 00021 #define MAX_NOTE 11 00022 #define MAX_OCT 8 00023 std::string notes[] = {"C","C#/Db","D","D#/Eb","E","F","F#/Gb","G","G#/Ab","A","A#/Bb","B"}; 00024 float notefreqs[] = {16.35,17.32,18.35,19.45,20.60,21.93,23.12,24.50,25.96,27.50,29.14,30.87}; 00025 00026 volatile float readfreq = 0.00; 00027 volatile int octave = 0; 00028 volatile int indx = 0; 00029 00030 void pb1_note_down(void) { 00031 if(!pb1) { 00032 indx -= 1; 00033 if (indx < 0) { 00034 indx = MAX_NOTE; 00035 } 00036 } 00037 } 00038 00039 void pb2_note_up (void) { 00040 if(!pb2) { 00041 indx += 1; 00042 if (indx > MAX_NOTE) { 00043 indx = 0; 00044 } 00045 } 00046 } 00047 00048 void pb3_oct_down (void) { 00049 if(!pb3) { 00050 octave -= 1; 00051 if (octave < 0) { 00052 octave = MAX_OCT; 00053 } 00054 } 00055 } 00056 00057 void pb4_oct_up (void) { 00058 if(!pb4) { 00059 octave += 1; 00060 if (octave > MAX_OCT) { 00061 octave = 0; 00062 } 00063 } 00064 } 00065 //Plays speaker at desired frequency selected by user 00066 void playspeaker(void const *arguments) { 00067 while (1) { 00068 speaker.period(1.0/(notefreqs[indx] * pow(2.0f,octave))); 00069 speaker = 0.0; 00070 while(!pb5) { 00071 speaker = 0.5; 00072 } 00073 speaker = 0.0; 00074 Thread::wait(100); 00075 } 00076 } 00077 //Print frequencies of notes, detected freq, and circle display graphic to LCD 00078 void ulcd(void const *arguments) { 00079 int cx; 00080 int old_i = 0; 00081 int old_oct= 0; 00082 int i; 00083 int oct; 00084 while(1) { 00085 i = indx; 00086 oct = octave; 00087 if (old_oct != oct) { 00088 old_oct = oct; 00089 uLCD.locate(1,7); 00090 uLCD.printf(" "); 00091 } 00092 if (old_i != i) { 00093 old_i = i; 00094 uLCD.locate(1,7); 00095 uLCD.printf(" "); 00096 uLCD.locate(1,3); 00097 uLCD.printf(" "); 00098 } 00099 uLCD.locate(1,3); 00100 uLCD.printf("%s%D", notes[i], oct); 00101 uLCD.locate(1,7); 00102 uLCD.printf("%.2f Hz.", notefreqs[i] * pow(2.0f,oct)); 00103 uLCD.locate(1,14); 00104 uLCD.printf("%.2f Hz.", readfreq); 00105 uLCD.filled_circle(108, cx, 5, BLACK); 00106 if (readfreq <= (notefreqs[i] * pow(2.0f,oct))+ 5 && readfreq >= (notefreqs[i] * pow(2.0f,oct)) - 5) { 00107 cx = 64; 00108 uLCD.line(88, 64, 128, 64, GREEN); 00109 uLCD.filled_circle(108, cx, 5, GREEN); 00110 } else { 00111 cx = 64 + (notefreqs[i] * pow(2.0f,oct)) - readfreq; 00112 if (cx < 0) { 00113 cx = 0; 00114 } else if (cx > 128) { 00115 cx = 128; 00116 } 00117 uLCD.line(88, 64, 128, 64, RED); 00118 uLCD.filled_circle(108, cx, 5, RED); 00119 } 00120 Thread::wait(10); 00121 } 00122 } 00123 00124 int main() { 00125 //set up pindetect 00126 pb1.mode(PullUp); 00127 pb2.mode(PullUp); 00128 pb3.mode(PullUp); 00129 pb4.mode(PullUp); 00130 pb5.mode(PullUp); 00131 wait(0.01); 00132 pb1.attach_deasserted(&pb1_note_down); 00133 pb2.attach_deasserted(&pb2_note_up); 00134 pb3.attach_deasserted(&pb3_oct_down); 00135 pb4.attach_deasserted(&pb4_oct_up); 00136 pb1.setSampleFrequency(); 00137 pb2.setSampleFrequency(); 00138 pb3.setSampleFrequency(); 00139 pb4.setSampleFrequency(); 00140 //set intial lcd values 00141 uLCD.background_color(BLACK); 00142 uLCD.baudrate(3000000); 00143 uLCD.line(88, 0, 88, 128, WHITE); 00144 uLCD.color(WHITE); 00145 uLCD.locate(1,1); 00146 uLCD.printf("Note:"); 00147 uLCD.locate(1,5); 00148 uLCD.printf("Note Freq:"); 00149 uLCD.locate(1,12); 00150 uLCD.printf("Read Freq:"); 00151 //launch threads 00152 Thread ulcd_thread(&ulcd); 00153 Thread speaker_thread(&playspeaker); 00154 //set up main thread 00155 int samples = 1024; 00156 float arr [samples+1]; 00157 arr[0] = 0; 00158 float max = 0; 00159 float loc = 0; 00160 float freq; 00161 osThreadSetPriority(osThreadGetId(), osPriorityHigh); 00162 //Loop and constantly be finding frequency of signal 00163 while (1) { 00164 tim.reset(); 00165 tim.start(); 00166 for (int i = 1; i<=samples; i++){ 00167 arr[i] = mic.instantlevel(); //Sample microphone at ~4 Khz 00168 wait(.00025); 00169 } 00170 tim.stop(); 00171 freq = samples/tim.read(); 00172 //Turn sampled array into its fourier transform 00173 vRealFFT(arr,samples); 00174 00175 //Loop through and find most apparent frequency of sampled signal 00176 for(int i = 2; i<=samples; i++){ 00177 arr[i] *= arr[i]; 00178 if(max<arr[i]){ 00179 loc = freq/samples * i/2; //determine frequency by using sample rate,index in array 00180 max = arr[i]; 00181 } 00182 } 00183 readfreq = loc; 00184 max=0; 00185 wait(0.25); 00186 Thread::wait(100); 00187 } 00188 }
Generated on Fri Jul 22 2022 00:29:27 by
1.7.2