Reads in audio signal on ADC, performs FFT and displays spectrum on Nokia 5110 LCD display.

Dependencies:   N5110 mbed

Revision:
2:8da22b498051
Parent:
1:7c6c1f98b8f5
Child:
3:0df6485bc3ec
--- a/main.cpp	Tue Jul 22 15:42:39 2014 +0000
+++ b/main.cpp	Tue Jul 22 17:52:59 2014 +0000
@@ -9,6 +9,7 @@
 void printSpectrum();
 void printSamples();
 void ledBarGraph();
+void rgbDance();
 void lcdEqualiser();
 int calcPeakFrequency();
 
@@ -19,8 +20,12 @@
 //    VCC,SCE,RST,D/C,MOSI,SCLK,LED
 N5110 lcd(p7,p8,p9,p10,p11,p13,p21);
 
+PwmOut red(p23);  // RGB LEDs (same connections as app board)
+PwmOut green(p24);
+PwmOut blue(p25);
+
 #define BUF_LEN 1024
-#define SAMP_FREQ 10000
+#define SAMP_FREQ 30000
 
 short samples[BUF_LEN];  // store the values read from ADC
 short mx[BUF_LEN*2]; // input data 16 bit, 4 byte aligned  x0r,x0i,x1r,x1i,....
@@ -36,7 +41,12 @@
     lcd.printString("Audio FFT",14,0);
     lcd.printString("Analyser",20,1);
     lcd.printString("Craig A. Evans",0,4);
+
     serial.baud(115200);
+
+    red.period(1e-4); // 10 kHz period for starters
+    // setting one PWM channel sets them all as they share the same frequency
+
     leds = 15;
     wait(2.0);   // short pause to allow coupling capacitor to charge
     leds = 0;
@@ -44,17 +54,19 @@
 
     while(1) {
 
+        //red = 1.0,green=1.0,blue=1.0;
+
         updateSamples();  // read in new analog values
-        ledBarGraph();    // display amplitude bar graph on LEDs from sample values
         doFFT();          // calc FFT
+        ledBarGraph();    // display amplitude bar graph on LEDs from sample values
         lcdEqualiser();   // plot spectrum on LCD
-
+        rgbDance();
         //printSpectrum();
         //printSamples();
         //int tone = calcPeakFrequency();  // calculate peak frequcny and send over serial for debug
         //serial.printf("f = %u\n",tone);
 
-        wait_ms(100);  // update display 100 ms
+        wait_ms(10);  // update display 100 ms
 
     }
 }
@@ -66,7 +78,7 @@
         rms+= samples[i]*samples[i];
     }
     // calc the sum of the squares
-    
+
     rms/=BUF_LEN;     // get the mean
     rms = sqrt(rms);  // and root to get the RMS
     rms/= 16384.0;  // scale according to 16-bit signed maximum value
@@ -152,7 +164,7 @@
     for (int i=0; i<BUF_LEN; i+=2) {  // loop through spectrum and look for maximum value
         if (spectrum[j] > max) {
             max = spectrum[j];
-            frequency = int(SAMP_FREQ/BUF_LEN/2*i);  
+            frequency = int(SAMP_FREQ/BUF_LEN/2*i);
         }
         j++;
     }
@@ -193,4 +205,59 @@
     }
     lcd.refresh();
 
+}
+
+void rgbDance()
+{
+
+    // spectrum has BUF_LEN/2 values = 512
+    // split into 3 bins for R, G and B gives 170 bins per colour
+
+    float ledColour[3];
+    float total = 0.0;
+
+
+
+    for (int i=0; i<60; i++) {
+        ledColour[0] += spectrum[i];  // sum the 6 values in the spectrum
+    }
+    total += ledColour[0];
+    for (int i=60; i<200; i++) {
+        ledColour[1] += spectrum[i];  // sum the 6 values in the spectrum
+    }
+    total += ledColour[1];
+    for (int i=200; i<512; i++) {
+        ledColour[2] += spectrum[i];  // sum the 6 values in the spectrum
+    }
+    total += ledColour[2];
+
+    float r = ledColour[0]/total;
+    float g = ledColour[1]/total;
+    float b = ledColour[2]/total;
+
+    serial.printf("RGB = %f , %f , %f (%f)\n",r,g,b,r+g+b);
+
+    r = 1.0 - r;   // common anode, smaller value is brighter
+    g = 1.0 - g;   // bigger value is duller
+    b = 1.0 - b;
+
+    if (r > 1.0)
+        r = 1.0;
+    else if (r < 0.0)
+        r = 0.0;
+
+    if (g > 1.0)
+        g = 1.0;
+    else if (g < 0.0)
+        g = 0.0;
+
+    if (b > 1.0)
+        b = 1.0;
+    else if (b < 0.0)
+        b = 0.0;
+
+    red.write(r);  // set duty cycles
+    green.write(g);
+    blue.write(b);
+
 }
\ No newline at end of file