Collin Rusch / Mbed 2 deprecated 4180_Tuner

Dependencies:   mbed mbed-rtos 4DGL-uLCD-SE FFT PinDetect MAX4466

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

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 }