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: SpactrumAnalysisClasses/SpectrumDisplay.cpp
- Revision:
- 0:c5b026c2d07e
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SpactrumAnalysisClasses/SpectrumDisplay.cpp Sun Jul 26 02:48:23 2015 +0000 @@ -0,0 +1,110 @@ +//------------------------------------------------------- +// Class for display spectrum +// Copyright (c) 2014 MIKAMI, Naoki, 2014/12/28 +//------------------------------------------------------- + +#include "SpectrumDisplay.hpp" + +namespace Mikami +{ + SpectrumDisplay::SpectrumDisplay( + SeeedStudioTFTv2* lcd, + int nFft, int x0, int y0, + float db1, int bin, float maxDb, int fs) + : N_FFT_(nFft), X0_(x0), Y0_(y0), + DB1_(db1), BIN_(bin), MAX_DB_(maxDb), FS_(fs), + lcd_(lcd) + { + lcd_->background(Navy); + lcd_->foreground(White); + lcd_->cls(); + lcd_->set_orientation(1); + lcd_->set_font((uint8_t*) Arial12x12); + lcd_->locate(86,3); + lcd_->printf("Spectrum Analyzer"); + + AxisX(); + AxisY(); + } + + void SpectrumDisplay::BarChart(float db[], float offset) + { + for (int n=1; n<=N_FFT_/2; n++) + { + float h = ((db[n] + offset) >= 0)? db[n] + offset : 0; + if (h > MAX_DB_) h = MAX_DB_; + int y = Y0_ - (int)(h*DB1_); + lcd_->line(X0_+n, Y0_-1, X0_+n, y, Cyan); + lcd_->line(X0_+n, y-1, X0_+n, Y0_-(int)(MAX_DB_*DB1_), Navy); + } + lcd_->line(X0_, Y0_, X0_+BIN_*N_FFT_/2, Y0_, Yellow); + } + + void SpectrumDisplay::LineChart(float db[], float offset) + { + lcd_->fillrect(X0_+1, Y0_-(int)(MAX_DB_*DB1_), + X0_+N_FFT_*BIN_/2, Y0_-1, Navy); + + float db1 = ((db[1] + offset) > 0)? db[1] + offset : 0; + int y1 = Y0_ - (int)(db1*DB1_); + for (int n=1; n<N_FFT_/2; n++) + { + float db2 = ((db[n+1] + offset) > 0)? db[n+1] + offset : 0; + if (db2 > MAX_DB_) db2 = MAX_DB_; + int y2 = Y0_ - (int)(db2*DB1_); + lcd_->line(X0_+n, y1, X0_+n+1, y2, Cyan); + y1 = y2; + } + lcd_->line(X0_, Y0_, X0_+BIN_*N_FFT_/2, Y0_, Yellow); + } + + void SpectrumDisplay::DisplayVolume(float volume) + { + const int X_POS = 305; + const float TH = 0.85f; + if (volume < TH) // volume < 85 % + { + lcd_->fillrect(X_POS, Y0_-DB1_*MAX_DB_, X_POS+5, Y0_, Navy); + lcd_->fillrect(X_POS, Y0_-DB1_*MAX_DB_*volume, + X_POS+5, Y0_, Cyan); + } + else // volume >= 85 % + { + lcd_->fillrect(X_POS, Y0_-DB1_*MAX_DB_, X_POS+5, Y0_, Navy); + lcd_->fillrect(X_POS, Y0_-DB1_*MAX_DB_*volume, + X_POS+5, Y0_-DB1_*MAX_DB_*TH, Red); + lcd_->fillrect(X_POS, Y0_-DB1_*MAX_DB_*TH, X_POS+5, Y0_, Cyan); + } + } + + // x-axis + void SpectrumDisplay::AxisX() + { + lcd_->line(X0_, Y0_, X0_+BIN_*N_FFT_/2, Y0_, Yellow); + float dx = BIN_*(N_FFT_*1000.0f)/(float)FS_; + for (int n=0; n<=5; n++) + { + int xTick = X0_ + (int)(dx*n + 0.5f); + lcd_->locate(xTick-4, Y0_+10); + lcd_->printf("%d", n); + lcd_->line(xTick, Y0_, xTick, Y0_+5, Yellow); + } + lcd_->locate(110, Y0_+24); + lcd_->printf("Frequency [kHz]"); + } + + // y-axis + void SpectrumDisplay::AxisY() + { + lcd_->line(X0_, Y0_+5, X0_, Y0_-(int)(MAX_DB_*DB1_), Yellow); + for (int n=0; n<=(int)MAX_DB_; n+=20) + { + int yTick = Y0_-(int)(DB1_*n); + lcd_->locate(X0_-22, yTick-5); + lcd_->printf("%2d", n); + lcd_->line(X0_-5, yTick, X0_, yTick, Yellow); + } + lcd_->locate(X0_-27, Y0_-(int)(DB1_*MAX_DB_)-18); + lcd_->printf("[dB]"); + } +}