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
--- /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;
+ }
+}
+
+