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

Committer:
MikamiUitOpen
Date:
Sun Jul 26 02:48:23 2015 +0000
Revision:
0:c5b026c2d07e
1

Who changed what in which revision?

UserRevisionLine numberNew contents of line
MikamiUitOpen 0:c5b026c2d07e 1 //--------------------------------------------------------------
MikamiUitOpen 0:c5b026c2d07e 2 // Spectrum analyzer
MikamiUitOpen 0:c5b026c2d07e 3 // input PC_3
MikamiUitOpen 0:c5b026c2d07e 4 // sampling frquency 10 kHz
MikamiUitOpen 0:c5b026c2d07e 5 // window Hamming window
MikamiUitOpen 0:c5b026c2d07e 6 // number of data 240 points
MikamiUitOpen 0:c5b026c2d07e 7 // number of FFT 512 points
MikamiUitOpen 0:c5b026c2d07e 8 // preemphasis 1st-order difference
MikamiUitOpen 0:c5b026c2d07e 9 //
MikamiUitOpen 0:c5b026c2d07e 10 // Touch pannel
MikamiUitOpen 0:c5b026c2d07e 11 // upper ---- left: update display
MikamiUitOpen 0:c5b026c2d07e 12 // right: freeze display
MikamiUitOpen 0:c5b026c2d07e 13 // lower ---- left: bar chart of FFT
MikamiUitOpen 0:c5b026c2d07e 14 // center: line chart of FFT
MikamiUitOpen 0:c5b026c2d07e 15 // right: line chart of linear prediction
MikamiUitOpen 0:c5b026c2d07e 16 // When you touch the touch pannel, PZT speaker connected PB_1
MikamiUitOpen 0:c5b026c2d07e 17 // sounds "pi" generated using PWM object.
MikamiUitOpen 0:c5b026c2d07e 18 //
MikamiUitOpen 0:c5b026c2d07e 19 // 2015/07/25, Copyright (c) 2015 MIKAMI, Naoki
MikamiUitOpen 0:c5b026c2d07e 20 //--------------------------------------------------------------
MikamiUitOpen 0:c5b026c2d07e 21
MikamiUitOpen 0:c5b026c2d07e 22 #include "ADC_Interrupt.hpp" // for ADC using interrupt
MikamiUitOpen 0:c5b026c2d07e 23 #include "FFT_Analysis.hpp"
MikamiUitOpen 0:c5b026c2d07e 24 #include "SpectrumDisplay.hpp"
MikamiUitOpen 0:c5b026c2d07e 25 #include "LPC_Analysis.hpp"
MikamiUitOpen 0:c5b026c2d07e 26
MikamiUitOpen 0:c5b026c2d07e 27 using namespace Mikami;
MikamiUitOpen 0:c5b026c2d07e 28
MikamiUitOpen 0:c5b026c2d07e 29 const int N_FFT_ = 512; // number of date for FFT
MikamiUitOpen 0:c5b026c2d07e 30 const int N_DATA_ = 240; // number of data to be analyzed
MikamiUitOpen 0:c5b026c2d07e 31
MikamiUitOpen 0:c5b026c2d07e 32 const int X0_ = 36; // Origin for x axis
MikamiUitOpen 0:c5b026c2d07e 33 const int Y0_ = 200; // Origin for y axis
MikamiUitOpen 0:c5b026c2d07e 34 const float DB1_ = 2.8f; // Pixels for 1 dB
MikamiUitOpen 0:c5b026c2d07e 35 const int BIN_ = 1; // Pixels per bin
MikamiUitOpen 0:c5b026c2d07e 36 const int MAX_DB_ = 60; // Maximum dB
MikamiUitOpen 0:c5b026c2d07e 37
MikamiUitOpen 0:c5b026c2d07e 38 const int FS_ = 10000; // Sampling frequency: 10 kHz
MikamiUitOpen 0:c5b026c2d07e 39
MikamiUitOpen 0:c5b026c2d07e 40 // Pointer of object for using Seeed Studio 2.8" TFT Touch Shield V2.0
MikamiUitOpen 0:c5b026c2d07e 41 SeeedStudioTFTv2* lcd_;
MikamiUitOpen 0:c5b026c2d07e 42
MikamiUitOpen 0:c5b026c2d07e 43 ADC_Intr adc_(PC_3, FS_); // for external mic connected with PC3
MikamiUitOpen 0:c5b026c2d07e 44 PeakHolder mag_(0.9998f); // for input volume
MikamiUitOpen 0:c5b026c2d07e 45 FftAnalyzer fft_(N_DATA_, N_FFT_);
MikamiUitOpen 0:c5b026c2d07e 46 LpcAnalyzer lpc_(N_DATA_, 16, N_FFT_);
MikamiUitOpen 0:c5b026c2d07e 47
MikamiUitOpen 0:c5b026c2d07e 48 float volume_ = 0;
MikamiUitOpen 0:c5b026c2d07e 49 float bufIn_[N_DATA_]; // Buffer for input signal
MikamiUitOpen 0:c5b026c2d07e 50 volatile bool analysisOk_;
MikamiUitOpen 0:c5b026c2d07e 51
MikamiUitOpen 0:c5b026c2d07e 52 PwmOut sound_(PB_1);
MikamiUitOpen 0:c5b026c2d07e 53 Timeout off_;
MikamiUitOpen 0:c5b026c2d07e 54
MikamiUitOpen 0:c5b026c2d07e 55 void IsrTimeout() { sound_.write(0); }
MikamiUitOpen 0:c5b026c2d07e 56
MikamiUitOpen 0:c5b026c2d07e 57 // Interrupt service routine for ADC
MikamiUitOpen 0:c5b026c2d07e 58 void AdcIsr()
MikamiUitOpen 0:c5b026c2d07e 59 {
MikamiUitOpen 0:c5b026c2d07e 60 static int count = 0; // counter of input buffer
MikamiUitOpen 0:c5b026c2d07e 61
MikamiUitOpen 0:c5b026c2d07e 62 bufIn_[count] = adc_.Read(); // Read from PC_3
MikamiUitOpen 0:c5b026c2d07e 63 volume_ = mag_.Execute(fabs(bufIn_[count]));
MikamiUitOpen 0:c5b026c2d07e 64
MikamiUitOpen 0:c5b026c2d07e 65 if (++count >= N_DATA_)
MikamiUitOpen 0:c5b026c2d07e 66 {
MikamiUitOpen 0:c5b026c2d07e 67 count = 0;
MikamiUitOpen 0:c5b026c2d07e 68 analysisOk_ = true; // This permits to FFT analysis
MikamiUitOpen 0:c5b026c2d07e 69 }
MikamiUitOpen 0:c5b026c2d07e 70 }
MikamiUitOpen 0:c5b026c2d07e 71
MikamiUitOpen 0:c5b026c2d07e 72 int main()
MikamiUitOpen 0:c5b026c2d07e 73 {
MikamiUitOpen 0:c5b026c2d07e 74 lcd_ = new SeeedStudioTFTv2 (A3, A1, A2, A0, // X+, X-, Y+, Y-
MikamiUitOpen 0:c5b026c2d07e 75 D11, D12, D13, // MOSI, MISO, SCLK
MikamiUitOpen 0:c5b026c2d07e 76 D5, D6, D7, D4); // CS_TFT, DC_TFT, BL_TFT, CS_SD
MikamiUitOpen 0:c5b026c2d07e 77
MikamiUitOpen 0:c5b026c2d07e 78 SpectrumDisplay disp(lcd_, N_FFT_, X0_, Y0_,
MikamiUitOpen 0:c5b026c2d07e 79 DB1_, BIN_, MAX_DB_, FS_);
MikamiUitOpen 0:c5b026c2d07e 80
MikamiUitOpen 0:c5b026c2d07e 81 analysisOk_ = false;
MikamiUitOpen 0:c5b026c2d07e 82 adc_.SetIntrVec(AdcIsr); // Assign ISR for ADC interrupt
MikamiUitOpen 0:c5b026c2d07e 83 sound_.period_us((int)(1.0e6f/4000.0f));
MikamiUitOpen 0:c5b026c2d07e 84
MikamiUitOpen 0:c5b026c2d07e 85
MikamiUitOpen 0:c5b026c2d07e 86 int touchBefore = 0;
MikamiUitOpen 0:c5b026c2d07e 87 int touchNow = 0;
MikamiUitOpen 0:c5b026c2d07e 88 // bool runBefore = true;
MikamiUitOpen 0:c5b026c2d07e 89 bool update = true;
MikamiUitOpen 0:c5b026c2d07e 90 float xn[N_DATA_]; // data to be analyzed
MikamiUitOpen 0:c5b026c2d07e 91 float db[N_FFT_/2+1]; // Log powerspectrum
MikamiUitOpen 0:c5b026c2d07e 92
MikamiUitOpen 0:c5b026c2d07e 93 // Timer tim;
MikamiUitOpen 0:c5b026c2d07e 94 while (true)
MikamiUitOpen 0:c5b026c2d07e 95 if (analysisOk_)
MikamiUitOpen 0:c5b026c2d07e 96 {
MikamiUitOpen 0:c5b026c2d07e 97 // Sampled signals to working area
MikamiUitOpen 0:c5b026c2d07e 98 for (int n=0; n<N_DATA_; n++)
MikamiUitOpen 0:c5b026c2d07e 99 xn[n] = bufIn_[n];
MikamiUitOpen 0:c5b026c2d07e 100
MikamiUitOpen 0:c5b026c2d07e 101 // tim.reset();
MikamiUitOpen 0:c5b026c2d07e 102 // Read touched Position
MikamiUitOpen 0:c5b026c2d07e 103 NVIC_DisableIRQ(ADC_IRQn);
MikamiUitOpen 0:c5b026c2d07e 104 point pos; // Touched position
MikamiUitOpen 0:c5b026c2d07e 105
MikamiUitOpen 0:c5b026c2d07e 106 // tim.start();
MikamiUitOpen 0:c5b026c2d07e 107 lcd_->getPixel(pos);
MikamiUitOpen 0:c5b026c2d07e 108 // tim.stop();
MikamiUitOpen 0:c5b026c2d07e 109
MikamiUitOpen 0:c5b026c2d07e 110 adc_.Select1stChannel();
MikamiUitOpen 0:c5b026c2d07e 111 NVIC_ClearPendingIRQ(ADC_IRQn);
MikamiUitOpen 0:c5b026c2d07e 112 NVIC_EnableIRQ(ADC_IRQn);
MikamiUitOpen 0:c5b026c2d07e 113 // printf("Execution time: %d micro seconds\r\n", tim.read_us());
MikamiUitOpen 0:c5b026c2d07e 114
MikamiUitOpen 0:c5b026c2d07e 115 // Display log spectrum
MikamiUitOpen 0:c5b026c2d07e 116 float offset = 30;
MikamiUitOpen 0:c5b026c2d07e 117
MikamiUitOpen 0:c5b026c2d07e 118 // Sound "pi" 0.1 seconds
MikamiUitOpen 0:c5b026c2d07e 119 if ( (pos.x != 320) && (pos.y !=0) )
MikamiUitOpen 0:c5b026c2d07e 120 {
MikamiUitOpen 0:c5b026c2d07e 121 sound_.write(0.5f);
MikamiUitOpen 0:c5b026c2d07e 122 off_.attach(&IsrTimeout, 0.1f);
MikamiUitOpen 0:c5b026c2d07e 123 }
MikamiUitOpen 0:c5b026c2d07e 124
MikamiUitOpen 0:c5b026c2d07e 125 // If touched upper, update: left, freeze: right
MikamiUitOpen 0:c5b026c2d07e 126 if (pos.y > 120)
MikamiUitOpen 0:c5b026c2d07e 127 {
MikamiUitOpen 0:c5b026c2d07e 128 if (pos.x <160) update = false;
MikamiUitOpen 0:c5b026c2d07e 129 else update = true;
MikamiUitOpen 0:c5b026c2d07e 130 }
MikamiUitOpen 0:c5b026c2d07e 131
MikamiUitOpen 0:c5b026c2d07e 132 if (update)
MikamiUitOpen 0:c5b026c2d07e 133 {
MikamiUitOpen 0:c5b026c2d07e 134 printf("\r\n%d, %d", pos.x, pos.y);
MikamiUitOpen 0:c5b026c2d07e 135 if ( (pos.x != 320) && (pos.y != 0)
MikamiUitOpen 0:c5b026c2d07e 136 && (pos.y < 120) ) // Touched lower?
MikamiUitOpen 0:c5b026c2d07e 137 {
MikamiUitOpen 0:c5b026c2d07e 138 if (pos.x < 107) touchNow = 2;
MikamiUitOpen 0:c5b026c2d07e 139 else if (pos.x < 213) touchNow = 1;
MikamiUitOpen 0:c5b026c2d07e 140 else touchNow = 0;
MikamiUitOpen 0:c5b026c2d07e 141
MikamiUitOpen 0:c5b026c2d07e 142 if (touchNow != touchBefore) touchBefore = touchNow;
MikamiUitOpen 0:c5b026c2d07e 143 }
MikamiUitOpen 0:c5b026c2d07e 144
MikamiUitOpen 0:c5b026c2d07e 145 // Spectrum analysis
MikamiUitOpen 0:c5b026c2d07e 146 if (touchNow < 2) fft_.Execute(xn, db);
MikamiUitOpen 0:c5b026c2d07e 147 else lpc_.Execute(xn, db);
MikamiUitOpen 0:c5b026c2d07e 148
MikamiUitOpen 0:c5b026c2d07e 149 if (touchNow == 0) disp.BarChart(db, offset);
MikamiUitOpen 0:c5b026c2d07e 150 else disp.LineChart(db, offset);
MikamiUitOpen 0:c5b026c2d07e 151
MikamiUitOpen 0:c5b026c2d07e 152 disp.DisplayVolume(volume_); // Display volume of input
MikamiUitOpen 0:c5b026c2d07e 153 }
MikamiUitOpen 0:c5b026c2d07e 154
MikamiUitOpen 0:c5b026c2d07e 155 wait(0.1f);
MikamiUitOpen 0:c5b026c2d07e 156 analysisOk_ = false;
MikamiUitOpen 0:c5b026c2d07e 157 }
MikamiUitOpen 0:c5b026c2d07e 158 }
MikamiUitOpen 0:c5b026c2d07e 159
MikamiUitOpen 0:c5b026c2d07e 160