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
SpectrumDisplay.cpp
00001 //------------------------------------------------------- 00002 // Class for display spectrum 00003 // Copyright (c) 2014 MIKAMI, Naoki, 2014/12/28 00004 //------------------------------------------------------- 00005 00006 #include "SpectrumDisplay.hpp" 00007 00008 namespace Mikami 00009 { 00010 SpectrumDisplay::SpectrumDisplay( 00011 SeeedStudioTFTv2* lcd, 00012 int nFft, int x0, int y0, 00013 float db1, int bin, float maxDb, int fs) 00014 : N_FFT_(nFft), X0_(x0), Y0_(y0), 00015 DB1_(db1), BIN_(bin), MAX_DB_(maxDb), FS_(fs), 00016 lcd_(lcd) 00017 { 00018 lcd_->background(Navy); 00019 lcd_->foreground(White); 00020 lcd_->cls(); 00021 lcd_->set_orientation(1); 00022 lcd_->set_font((uint8_t*) Arial12x12); 00023 lcd_->locate(86,3); 00024 lcd_->printf("Spectrum Analyzer"); 00025 00026 AxisX(); 00027 AxisY(); 00028 } 00029 00030 void SpectrumDisplay::BarChart(float db[], float offset) 00031 { 00032 for (int n=1; n<=N_FFT_/2; n++) 00033 { 00034 float h = ((db[n] + offset) >= 0)? db[n] + offset : 0; 00035 if (h > MAX_DB_) h = MAX_DB_; 00036 int y = Y0_ - (int)(h*DB1_); 00037 lcd_->line(X0_+n, Y0_-1, X0_+n, y, Cyan); 00038 lcd_->line(X0_+n, y-1, X0_+n, Y0_-(int)(MAX_DB_*DB1_), Navy); 00039 } 00040 lcd_->line(X0_, Y0_, X0_+BIN_*N_FFT_/2, Y0_, Yellow); 00041 } 00042 00043 void SpectrumDisplay::LineChart(float db[], float offset) 00044 { 00045 lcd_->fillrect(X0_+1, Y0_-(int)(MAX_DB_*DB1_), 00046 X0_+N_FFT_*BIN_/2, Y0_-1, Navy); 00047 00048 float db1 = ((db[1] + offset) > 0)? db[1] + offset : 0; 00049 int y1 = Y0_ - (int)(db1*DB1_); 00050 for (int n=1; n<N_FFT_/2; n++) 00051 { 00052 float db2 = ((db[n+1] + offset) > 0)? db[n+1] + offset : 0; 00053 if (db2 > MAX_DB_) db2 = MAX_DB_; 00054 int y2 = Y0_ - (int)(db2*DB1_); 00055 lcd_->line(X0_+n, y1, X0_+n+1, y2, Cyan); 00056 y1 = y2; 00057 } 00058 lcd_->line(X0_, Y0_, X0_+BIN_*N_FFT_/2, Y0_, Yellow); 00059 } 00060 00061 void SpectrumDisplay::DisplayVolume(float volume) 00062 { 00063 const int X_POS = 305; 00064 const float TH = 0.85f; 00065 if (volume < TH) // volume < 85 % 00066 { 00067 lcd_->fillrect(X_POS, Y0_-DB1_*MAX_DB_, X_POS+5, Y0_, Navy); 00068 lcd_->fillrect(X_POS, Y0_-DB1_*MAX_DB_*volume, 00069 X_POS+5, Y0_, Cyan); 00070 } 00071 else // volume >= 85 % 00072 { 00073 lcd_->fillrect(X_POS, Y0_-DB1_*MAX_DB_, X_POS+5, Y0_, Navy); 00074 lcd_->fillrect(X_POS, Y0_-DB1_*MAX_DB_*volume, 00075 X_POS+5, Y0_-DB1_*MAX_DB_*TH, Red); 00076 lcd_->fillrect(X_POS, Y0_-DB1_*MAX_DB_*TH, X_POS+5, Y0_, Cyan); 00077 } 00078 } 00079 00080 // x-axis 00081 void SpectrumDisplay::AxisX() 00082 { 00083 lcd_->line(X0_, Y0_, X0_+BIN_*N_FFT_/2, Y0_, Yellow); 00084 float dx = BIN_*(N_FFT_*1000.0f)/(float)FS_; 00085 for (int n=0; n<=5; n++) 00086 { 00087 int xTick = X0_ + (int)(dx*n + 0.5f); 00088 lcd_->locate(xTick-4, Y0_+10); 00089 lcd_->printf("%d", n); 00090 lcd_->line(xTick, Y0_, xTick, Y0_+5, Yellow); 00091 } 00092 lcd_->locate(110, Y0_+24); 00093 lcd_->printf("Frequency [kHz]"); 00094 } 00095 00096 // y-axis 00097 void SpectrumDisplay::AxisY() 00098 { 00099 lcd_->line(X0_, Y0_+5, X0_, Y0_-(int)(MAX_DB_*DB1_), Yellow); 00100 for (int n=0; n<=(int)MAX_DB_; n+=20) 00101 { 00102 int yTick = Y0_-(int)(DB1_*n); 00103 lcd_->locate(X0_-22, yTick-5); 00104 lcd_->printf("%2d", n); 00105 lcd_->line(X0_-5, yTick, X0_, yTick, Yellow); 00106 } 00107 lcd_->locate(X0_-27, Y0_-(int)(DB1_*MAX_DB_)-18); 00108 lcd_->printf("[dB]"); 00109 } 00110 }
Generated on Wed Jul 13 2022 10:14:59 by 1.7.2