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

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 //--------------------------------------------------------------
00002 // Spectrum analyzer
00003 //      input               PC_3
00004 //      sampling frquency   10 kHz
00005 //      window              Hamming window
00006 //      number of data      240 points
00007 //      number of FFT       512 points
00008 //      preemphasis         1st-order difference
00009 //
00010 // Touch pannel
00011 //      upper ---- left:   update display
00012 //                 right:  freeze display
00013 //      lower ---- left:   bar chart of FFT
00014 //                 center: line chart of FFT
00015 //                 right:  line chart of linear prediction
00016 // When you touch the touch pannel, PZT speaker connected PB_1
00017 // sounds "pi" generated using PWM object.
00018 //
00019 // 2015/07/25, Copyright (c) 2015 MIKAMI, Naoki
00020 //--------------------------------------------------------------
00021 
00022 #include "ADC_Interrupt.hpp"    // for ADC using interrupt
00023 #include "FFT_Analysis.hpp"
00024 #include "SpectrumDisplay.hpp"
00025 #include "LPC_Analysis.hpp"
00026 
00027 using namespace Mikami;
00028 
00029 const int N_FFT_ = 512;     // number of date for FFT
00030 const int N_DATA_ = 240;    // number of data to be analyzed 
00031 
00032 const int X0_ = 36;         // Origin for x axis
00033 const int Y0_ = 200;        // Origin for y axis
00034 const float DB1_ = 2.8f;    // Pixels for 1 dB
00035 const int BIN_ = 1;         // Pixels per bin
00036 const int MAX_DB_ = 60;     // Maximum dB
00037 
00038 const int FS_ = 10000;      // Sampling frequency: 10 kHz
00039 
00040 // Pointer of object for using Seeed Studio 2.8" TFT Touch Shield V2.0
00041 SeeedStudioTFTv2* lcd_;
00042 
00043 ADC_Intr adc_(PC_3, FS_);   // for external mic connected with PC3
00044 PeakHolder mag_(0.9998f);   // for input volume
00045 FftAnalyzer fft_(N_DATA_, N_FFT_);
00046 LpcAnalyzer lpc_(N_DATA_, 16, N_FFT_);
00047 
00048 float volume_ = 0;
00049 float bufIn_[N_DATA_];      // Buffer for input signal
00050 volatile bool analysisOk_;
00051 
00052 PwmOut sound_(PB_1);
00053 Timeout off_;
00054 
00055 void IsrTimeout() { sound_.write(0); }
00056 
00057 // Interrupt service routine for ADC
00058 void AdcIsr()
00059 {
00060     static int count = 0;   // counter of input buffer
00061 
00062     bufIn_[count] = adc_.Read(); // Read from PC_3
00063     volume_ = mag_.Execute(fabs(bufIn_[count]));
00064 
00065     if (++count >= N_DATA_)
00066     {
00067         count = 0;
00068         analysisOk_ = true;      // This permits to FFT analysis
00069     }
00070 }
00071 
00072 int main()
00073 {
00074     lcd_ = new SeeedStudioTFTv2 (A3, A1, A2, A0,   // X+, X-, Y+, Y-
00075                                  D11, D12, D13,    // MOSI, MISO, SCLK
00076                                  D5, D6, D7, D4);  // CS_TFT, DC_TFT, BL_TFT, CS_SD
00077 
00078     SpectrumDisplay disp(lcd_, N_FFT_, X0_, Y0_,
00079                          DB1_, BIN_, MAX_DB_, FS_);
00080 
00081     analysisOk_ = false;
00082     adc_.SetIntrVec(AdcIsr);    // Assign ISR for ADC interrupt
00083     sound_.period_us((int)(1.0e6f/4000.0f));
00084 
00085 
00086     int touchBefore = 0;
00087     int touchNow = 0;
00088 //    bool runBefore = true;
00089     bool update = true;
00090     float xn[N_DATA_];      // data to be analyzed
00091     float db[N_FFT_/2+1];   // Log powerspectrum
00092 
00093 //    Timer tim;
00094     while (true)
00095         if (analysisOk_)
00096         {
00097             // Sampled signals to working area
00098             for (int n=0; n<N_DATA_; n++)
00099                 xn[n] = bufIn_[n];
00100 
00101 //            tim.reset();
00102             // Read touched Position
00103             NVIC_DisableIRQ(ADC_IRQn);
00104             point pos;      // Touched position
00105 
00106 //            tim.start();
00107             lcd_->getPixel(pos);
00108 //            tim.stop();
00109 
00110             adc_.Select1stChannel();
00111             NVIC_ClearPendingIRQ(ADC_IRQn);
00112             NVIC_EnableIRQ(ADC_IRQn);
00113 //            printf("Execution time: %d micro seconds\r\n", tim.read_us());
00114 
00115             // Display log spectrum
00116             float offset = 30;
00117             
00118             // Sound "pi" 0.1 seconds
00119             if ( (pos.x != 320) && (pos.y !=0) )
00120             {
00121                 sound_.write(0.5f);
00122                 off_.attach(&IsrTimeout, 0.1f);
00123             }
00124             
00125             // If touched upper, update: left, freeze: right
00126             if (pos.y > 120)
00127             {
00128                 if (pos.x <160) update = false;
00129                 else            update = true;
00130             }
00131             
00132             if (update)
00133             {
00134                 printf("\r\n%d, %d", pos.x, pos.y);
00135                 if ( (pos.x != 320) && (pos.y != 0)
00136                                     && (pos.y < 120) )    // Touched lower?
00137                 {
00138                     if (pos.x < 107) touchNow = 2;
00139                     else if (pos.x < 213) touchNow = 1;
00140                         else              touchNow = 0;
00141 
00142                     if (touchNow != touchBefore) touchBefore = touchNow;
00143                 }
00144 
00145                 // Spectrum analysis
00146                 if (touchNow < 2) fft_.Execute(xn, db);
00147                 else              lpc_.Execute(xn, db);
00148 
00149                 if (touchNow == 0) disp.BarChart(db, offset);
00150                 else               disp.LineChart(db, offset);
00151 
00152                 disp.DisplayVolume(volume_);    // Display volume of input
00153             }
00154 
00155             wait(0.1f);
00156             analysisOk_ = false;
00157         }
00158 }
00159 
00160