![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
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
Diff: main.cpp
- Revision:
- 0:c5b026c2d07e
diff -r 000000000000 -r c5b026c2d07e main.cpp --- /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; + } +} + +