Collin Rusch / Mbed 2 deprecated 4180_Tuner

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

Revision:
2:86aa2287412d
Parent:
0:fc5acbf5061c
diff -r c5772cef09bc -r 86aa2287412d main.cpp
--- a/main.cpp	Fri Oct 23 18:39:14 2015 +0000
+++ b/main.cpp	Sun Apr 28 20:46:45 2019 +0000
@@ -1,14 +1,188 @@
 #include "mbed.h"
 #include "MAX4466.h"
-Serial pc (USBTX, USBRX);
+#include "FFT.h"
+#include "rtos.h"
+#include "uLCD_4DGL.h"
+#include "PinDetect.h"
+#include <string>
+#include <math.h>
 
 
-MAX4466 mic(p20);
+PinDetect pb1(p6);
+PinDetect pb2(p7);
+PinDetect pb3(p8);
+PinDetect pb4(p9);
+DigitalIn pb5 (p10);
+MAX4466 mic(p15);
+PwmOut speaker(p21);
+uLCD_4DGL uLCD(p28,p27,p30);
+Timer tim;
+
+#define MAX_NOTE 11
+#define MAX_OCT 8
+std::string notes[] = {"C","C#/Db","D","D#/Eb","E","F","F#/Gb","G","G#/Ab","A","A#/Bb","B"};
+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};
+
+volatile float readfreq = 0.00;
+volatile int octave = 0;
+volatile int indx = 0;
+
+void pb1_note_down(void) {
+    if(!pb1) {
+        indx -= 1;
+        if (indx < 0) {
+            indx = MAX_NOTE; 
+        }
+    }
+}
+
+void pb2_note_up (void) {
+    if(!pb2) {
+        indx += 1;
+        if (indx > MAX_NOTE) {
+            indx = 0; 
+        }
+    }
+}
+
+void pb3_oct_down (void) {
+   if(!pb3) {
+        octave -= 1;
+        if (octave < 0) {
+            octave = MAX_OCT; 
+        }
+    }
+}
 
-int main()
-{
-    while (1) {
-        mic.volume_indicator();
-        pc.printf("\n\r Level is %f", mic.sound_level());
+void pb4_oct_up (void) {
+   if(!pb4) {
+        octave += 1;
+        if (octave > MAX_OCT) {
+            octave = 0; 
+        }
+    }
+}
+//Plays speaker at desired frequency selected by user
+void playspeaker(void const *arguments) {
+   while (1) {
+        speaker.period(1.0/(notefreqs[indx] * pow(2.0f,octave)));
+        speaker = 0.0;
+        while(!pb5) {
+            speaker = 0.5;
+        }
+        speaker = 0.0;
+        Thread::wait(100);
+    }
+}
+//Print frequencies of notes, detected freq, and circle display graphic to LCD
+void ulcd(void const *arguments) {
+    int cx;
+    int old_i = 0;
+    int old_oct= 0;
+    int i;
+    int oct;
+    while(1) {
+        i = indx;
+        oct = octave;
+        if (old_oct != oct) {
+            old_oct = oct;
+            uLCD.locate(1,7);
+            uLCD.printf("           ");
+        }
+        if (old_i != i) {
+            old_i = i;
+            uLCD.locate(1,7);
+            uLCD.printf("           ");
+            uLCD.locate(1,3);
+            uLCD.printf("           ");
+        }
+        uLCD.locate(1,3);
+        uLCD.printf("%s%D", notes[i], oct);
+        uLCD.locate(1,7);
+        uLCD.printf("%.2f Hz.", notefreqs[i] * pow(2.0f,oct));
+        uLCD.locate(1,14);
+        uLCD.printf("%.2f Hz.", readfreq);
+        uLCD.filled_circle(108, cx, 5, BLACK);
+        if (readfreq <= (notefreqs[i] * pow(2.0f,oct))+ 5 && readfreq >= (notefreqs[i] * pow(2.0f,oct)) - 5) {
+            cx = 64;
+            uLCD.line(88, 64, 128, 64, GREEN);
+            uLCD.filled_circle(108, cx, 5, GREEN);
+        } else {
+            cx = 64 + (notefreqs[i] * pow(2.0f,oct)) - readfreq;
+            if (cx < 0) {
+                cx = 0; 
+            } else if (cx > 128) {
+                cx = 128;    
+            }
+            uLCD.line(88, 64, 128, 64, RED);
+            uLCD.filled_circle(108, cx, 5, RED);
+        }
+        Thread::wait(10);
     }
+}
+
+int main() {
+    //set up pindetect
+    pb1.mode(PullUp);
+    pb2.mode(PullUp);
+    pb3.mode(PullUp);
+    pb4.mode(PullUp);
+    pb5.mode(PullUp);
+    wait(0.01);
+    pb1.attach_deasserted(&pb1_note_down);
+    pb2.attach_deasserted(&pb2_note_up);
+    pb3.attach_deasserted(&pb3_oct_down);
+    pb4.attach_deasserted(&pb4_oct_up);
+    pb1.setSampleFrequency();
+    pb2.setSampleFrequency();
+    pb3.setSampleFrequency();
+    pb4.setSampleFrequency();
+    //set intial lcd values
+    uLCD.background_color(BLACK);
+    uLCD.baudrate(3000000);
+    uLCD.line(88, 0, 88, 128, WHITE);
+    uLCD.color(WHITE);
+    uLCD.locate(1,1);
+    uLCD.printf("Note:");
+    uLCD.locate(1,5);
+    uLCD.printf("Note Freq:");
+    uLCD.locate(1,12);
+    uLCD.printf("Read Freq:");
+    //launch threads
+    Thread ulcd_thread(&ulcd);
+    Thread speaker_thread(&playspeaker);
+    //set up main thread
+    int samples = 1024;
+    float arr [samples+1];
+    arr[0] = 0;
+    float max = 0;
+    float loc = 0;
+    float freq;
+    osThreadSetPriority(osThreadGetId(), osPriorityHigh);
+    //Loop and constantly be finding frequency of signal
+    while (1) { 
+        tim.reset();
+        tim.start();
+        for (int i = 1; i<=samples; i++){
+            arr[i] = mic.instantlevel(); //Sample microphone at ~4 Khz
+            wait(.00025);
+            }
+        tim.stop();
+        freq = samples/tim.read(); 
+        //Turn sampled array into its fourier transform
+        vRealFFT(arr,samples); 
+        
+        //Loop through and find most apparent frequency of sampled signal 
+        for(int i = 2; i<=samples; i++){ 
+            arr[i] *= arr[i];
+            if(max<arr[i]){
+                loc = freq/samples * i/2; //determine frequency by using sample rate,index in array
+                max = arr[i];
+                }
+            }
+        readfreq = loc; 
+        max=0;
+        wait(0.25);
+        Thread::wait(100);
+    }  
 }
\ No newline at end of file