Real-time spectrum analyzer for ST Nucleo F401RE using Seeed Studio 2.8'' TFT Touch Shield V2.0.

Dependencies:   SeeedStudioTFTv2 UITDSP_ADDA UIT_FFT_Real mbed

Revision:
0:c5b026c2d07e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sun Jul 26 02:48:23 2015 +0000
@@ -0,0 +1,160 @@
+//--------------------------------------------------------------
+// Spectrum analyzer
+//      input               PC_3
+//      sampling frquency   10 kHz
+//      window              Hamming window
+//      number of data      240 points
+//      number of FFT       512 points
+//      preemphasis         1st-order difference
+//
+// Touch pannel
+//      upper ---- left:   update display
+//                 right:  freeze display
+//      lower ---- left:   bar chart of FFT
+//                 center: line chart of FFT
+//                 right:  line chart of linear prediction
+// When you touch the touch pannel, PZT speaker connected PB_1
+// sounds "pi" generated using PWM object.
+//
+// 2015/07/25, Copyright (c) 2015 MIKAMI, Naoki
+//--------------------------------------------------------------
+
+#include "ADC_Interrupt.hpp"    // for ADC using interrupt
+#include "FFT_Analysis.hpp"
+#include "SpectrumDisplay.hpp"
+#include "LPC_Analysis.hpp"
+
+using namespace Mikami;
+
+const int N_FFT_ = 512;     // number of date for FFT
+const int N_DATA_ = 240;    // number of data to be analyzed 
+
+const int X0_ = 36;         // Origin for x axis
+const int Y0_ = 200;        // Origin for y axis
+const float DB1_ = 2.8f;    // Pixels for 1 dB
+const int BIN_ = 1;         // Pixels per bin
+const int MAX_DB_ = 60;     // Maximum dB
+
+const int FS_ = 10000;      // Sampling frequency: 10 kHz
+
+// Pointer of object for using Seeed Studio 2.8" TFT Touch Shield V2.0
+SeeedStudioTFTv2* lcd_;
+
+ADC_Intr adc_(PC_3, FS_);   // for external mic connected with PC3
+PeakHolder mag_(0.9998f);   // for input volume
+FftAnalyzer fft_(N_DATA_, N_FFT_);
+LpcAnalyzer lpc_(N_DATA_, 16, N_FFT_);
+
+float volume_ = 0;
+float bufIn_[N_DATA_];      // Buffer for input signal
+volatile bool analysisOk_;
+
+PwmOut sound_(PB_1);
+Timeout off_;
+
+void IsrTimeout() { sound_.write(0); }
+
+// Interrupt service routine for ADC
+void AdcIsr()
+{
+    static int count = 0;   // counter of input buffer
+
+    bufIn_[count] = adc_.Read(); // Read from PC_3
+    volume_ = mag_.Execute(fabs(bufIn_[count]));
+
+    if (++count >= N_DATA_)
+    {
+        count = 0;
+        analysisOk_ = true;      // This permits to FFT analysis
+    }
+}
+
+int main()
+{
+    lcd_ = new SeeedStudioTFTv2 (A3, A1, A2, A0,   // X+, X-, Y+, Y-
+                                 D11, D12, D13,    // MOSI, MISO, SCLK
+                                 D5, D6, D7, D4);  // CS_TFT, DC_TFT, BL_TFT, CS_SD
+
+    SpectrumDisplay disp(lcd_, N_FFT_, X0_, Y0_,
+                         DB1_, BIN_, MAX_DB_, FS_);
+
+    analysisOk_ = false;
+    adc_.SetIntrVec(AdcIsr);    // Assign ISR for ADC interrupt
+    sound_.period_us((int)(1.0e6f/4000.0f));
+
+
+    int touchBefore = 0;
+    int touchNow = 0;
+//    bool runBefore = true;
+    bool update = true;
+    float xn[N_DATA_];      // data to be analyzed
+    float db[N_FFT_/2+1];   // Log powerspectrum
+
+//    Timer tim;
+    while (true)
+        if (analysisOk_)
+        {
+            // Sampled signals to working area
+            for (int n=0; n<N_DATA_; n++)
+                xn[n] = bufIn_[n];
+
+//            tim.reset();
+            // Read touched Position
+            NVIC_DisableIRQ(ADC_IRQn);
+            point pos;      // Touched position
+
+//            tim.start();
+            lcd_->getPixel(pos);
+//            tim.stop();
+
+            adc_.Select1stChannel();
+            NVIC_ClearPendingIRQ(ADC_IRQn);
+            NVIC_EnableIRQ(ADC_IRQn);
+//            printf("Execution time: %d micro seconds\r\n", tim.read_us());
+
+            // Display log spectrum
+            float offset = 30;
+            
+            // Sound "pi" 0.1 seconds
+            if ( (pos.x != 320) && (pos.y !=0) )
+            {
+                sound_.write(0.5f);
+                off_.attach(&IsrTimeout, 0.1f);
+            }
+            
+            // If touched upper, update: left, freeze: right
+            if (pos.y > 120)
+            {
+                if (pos.x <160) update = false;
+                else            update = true;
+            }
+            
+            if (update)
+            {
+                printf("\r\n%d, %d", pos.x, pos.y);
+                if ( (pos.x != 320) && (pos.y != 0)
+                                    && (pos.y < 120) )    // Touched lower?
+                {
+                    if (pos.x < 107) touchNow = 2;
+                    else if (pos.x < 213) touchNow = 1;
+                        else              touchNow = 0;
+
+                    if (touchNow != touchBefore) touchBefore = touchNow;
+                }
+
+                // Spectrum analysis
+                if (touchNow < 2) fft_.Execute(xn, db);
+                else              lpc_.Execute(xn, db);
+
+                if (touchNow == 0) disp.BarChart(db, offset);
+                else               disp.LineChart(db, offset);
+
+                disp.DisplayVolume(volume_);    // Display volume of input
+            }
+
+            wait(0.1f);
+            analysisOk_ = false;
+        }
+}
+
+