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
main.cpp
- Committer:
- MikamiUitOpen
- Date:
- 2015-07-26
- Revision:
- 0:c5b026c2d07e
File content as of revision 0:c5b026c2d07e:
//-------------------------------------------------------------- // 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; } }