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
SpactrumAnalysisClasses/SpectrumDisplay.cpp@0:c5b026c2d07e, 2015-07-26 (annotated)
- Committer:
- MikamiUitOpen
- Date:
- Sun Jul 26 02:48:23 2015 +0000
- Revision:
- 0:c5b026c2d07e
1
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
MikamiUitOpen | 0:c5b026c2d07e | 1 | //------------------------------------------------------- |
MikamiUitOpen | 0:c5b026c2d07e | 2 | // Class for display spectrum |
MikamiUitOpen | 0:c5b026c2d07e | 3 | // Copyright (c) 2014 MIKAMI, Naoki, 2014/12/28 |
MikamiUitOpen | 0:c5b026c2d07e | 4 | //------------------------------------------------------- |
MikamiUitOpen | 0:c5b026c2d07e | 5 | |
MikamiUitOpen | 0:c5b026c2d07e | 6 | #include "SpectrumDisplay.hpp" |
MikamiUitOpen | 0:c5b026c2d07e | 7 | |
MikamiUitOpen | 0:c5b026c2d07e | 8 | namespace Mikami |
MikamiUitOpen | 0:c5b026c2d07e | 9 | { |
MikamiUitOpen | 0:c5b026c2d07e | 10 | SpectrumDisplay::SpectrumDisplay( |
MikamiUitOpen | 0:c5b026c2d07e | 11 | SeeedStudioTFTv2* lcd, |
MikamiUitOpen | 0:c5b026c2d07e | 12 | int nFft, int x0, int y0, |
MikamiUitOpen | 0:c5b026c2d07e | 13 | float db1, int bin, float maxDb, int fs) |
MikamiUitOpen | 0:c5b026c2d07e | 14 | : N_FFT_(nFft), X0_(x0), Y0_(y0), |
MikamiUitOpen | 0:c5b026c2d07e | 15 | DB1_(db1), BIN_(bin), MAX_DB_(maxDb), FS_(fs), |
MikamiUitOpen | 0:c5b026c2d07e | 16 | lcd_(lcd) |
MikamiUitOpen | 0:c5b026c2d07e | 17 | { |
MikamiUitOpen | 0:c5b026c2d07e | 18 | lcd_->background(Navy); |
MikamiUitOpen | 0:c5b026c2d07e | 19 | lcd_->foreground(White); |
MikamiUitOpen | 0:c5b026c2d07e | 20 | lcd_->cls(); |
MikamiUitOpen | 0:c5b026c2d07e | 21 | lcd_->set_orientation(1); |
MikamiUitOpen | 0:c5b026c2d07e | 22 | lcd_->set_font((uint8_t*) Arial12x12); |
MikamiUitOpen | 0:c5b026c2d07e | 23 | lcd_->locate(86,3); |
MikamiUitOpen | 0:c5b026c2d07e | 24 | lcd_->printf("Spectrum Analyzer"); |
MikamiUitOpen | 0:c5b026c2d07e | 25 | |
MikamiUitOpen | 0:c5b026c2d07e | 26 | AxisX(); |
MikamiUitOpen | 0:c5b026c2d07e | 27 | AxisY(); |
MikamiUitOpen | 0:c5b026c2d07e | 28 | } |
MikamiUitOpen | 0:c5b026c2d07e | 29 | |
MikamiUitOpen | 0:c5b026c2d07e | 30 | void SpectrumDisplay::BarChart(float db[], float offset) |
MikamiUitOpen | 0:c5b026c2d07e | 31 | { |
MikamiUitOpen | 0:c5b026c2d07e | 32 | for (int n=1; n<=N_FFT_/2; n++) |
MikamiUitOpen | 0:c5b026c2d07e | 33 | { |
MikamiUitOpen | 0:c5b026c2d07e | 34 | float h = ((db[n] + offset) >= 0)? db[n] + offset : 0; |
MikamiUitOpen | 0:c5b026c2d07e | 35 | if (h > MAX_DB_) h = MAX_DB_; |
MikamiUitOpen | 0:c5b026c2d07e | 36 | int y = Y0_ - (int)(h*DB1_); |
MikamiUitOpen | 0:c5b026c2d07e | 37 | lcd_->line(X0_+n, Y0_-1, X0_+n, y, Cyan); |
MikamiUitOpen | 0:c5b026c2d07e | 38 | lcd_->line(X0_+n, y-1, X0_+n, Y0_-(int)(MAX_DB_*DB1_), Navy); |
MikamiUitOpen | 0:c5b026c2d07e | 39 | } |
MikamiUitOpen | 0:c5b026c2d07e | 40 | lcd_->line(X0_, Y0_, X0_+BIN_*N_FFT_/2, Y0_, Yellow); |
MikamiUitOpen | 0:c5b026c2d07e | 41 | } |
MikamiUitOpen | 0:c5b026c2d07e | 42 | |
MikamiUitOpen | 0:c5b026c2d07e | 43 | void SpectrumDisplay::LineChart(float db[], float offset) |
MikamiUitOpen | 0:c5b026c2d07e | 44 | { |
MikamiUitOpen | 0:c5b026c2d07e | 45 | lcd_->fillrect(X0_+1, Y0_-(int)(MAX_DB_*DB1_), |
MikamiUitOpen | 0:c5b026c2d07e | 46 | X0_+N_FFT_*BIN_/2, Y0_-1, Navy); |
MikamiUitOpen | 0:c5b026c2d07e | 47 | |
MikamiUitOpen | 0:c5b026c2d07e | 48 | float db1 = ((db[1] + offset) > 0)? db[1] + offset : 0; |
MikamiUitOpen | 0:c5b026c2d07e | 49 | int y1 = Y0_ - (int)(db1*DB1_); |
MikamiUitOpen | 0:c5b026c2d07e | 50 | for (int n=1; n<N_FFT_/2; n++) |
MikamiUitOpen | 0:c5b026c2d07e | 51 | { |
MikamiUitOpen | 0:c5b026c2d07e | 52 | float db2 = ((db[n+1] + offset) > 0)? db[n+1] + offset : 0; |
MikamiUitOpen | 0:c5b026c2d07e | 53 | if (db2 > MAX_DB_) db2 = MAX_DB_; |
MikamiUitOpen | 0:c5b026c2d07e | 54 | int y2 = Y0_ - (int)(db2*DB1_); |
MikamiUitOpen | 0:c5b026c2d07e | 55 | lcd_->line(X0_+n, y1, X0_+n+1, y2, Cyan); |
MikamiUitOpen | 0:c5b026c2d07e | 56 | y1 = y2; |
MikamiUitOpen | 0:c5b026c2d07e | 57 | } |
MikamiUitOpen | 0:c5b026c2d07e | 58 | lcd_->line(X0_, Y0_, X0_+BIN_*N_FFT_/2, Y0_, Yellow); |
MikamiUitOpen | 0:c5b026c2d07e | 59 | } |
MikamiUitOpen | 0:c5b026c2d07e | 60 | |
MikamiUitOpen | 0:c5b026c2d07e | 61 | void SpectrumDisplay::DisplayVolume(float volume) |
MikamiUitOpen | 0:c5b026c2d07e | 62 | { |
MikamiUitOpen | 0:c5b026c2d07e | 63 | const int X_POS = 305; |
MikamiUitOpen | 0:c5b026c2d07e | 64 | const float TH = 0.85f; |
MikamiUitOpen | 0:c5b026c2d07e | 65 | if (volume < TH) // volume < 85 % |
MikamiUitOpen | 0:c5b026c2d07e | 66 | { |
MikamiUitOpen | 0:c5b026c2d07e | 67 | lcd_->fillrect(X_POS, Y0_-DB1_*MAX_DB_, X_POS+5, Y0_, Navy); |
MikamiUitOpen | 0:c5b026c2d07e | 68 | lcd_->fillrect(X_POS, Y0_-DB1_*MAX_DB_*volume, |
MikamiUitOpen | 0:c5b026c2d07e | 69 | X_POS+5, Y0_, Cyan); |
MikamiUitOpen | 0:c5b026c2d07e | 70 | } |
MikamiUitOpen | 0:c5b026c2d07e | 71 | else // volume >= 85 % |
MikamiUitOpen | 0:c5b026c2d07e | 72 | { |
MikamiUitOpen | 0:c5b026c2d07e | 73 | lcd_->fillrect(X_POS, Y0_-DB1_*MAX_DB_, X_POS+5, Y0_, Navy); |
MikamiUitOpen | 0:c5b026c2d07e | 74 | lcd_->fillrect(X_POS, Y0_-DB1_*MAX_DB_*volume, |
MikamiUitOpen | 0:c5b026c2d07e | 75 | X_POS+5, Y0_-DB1_*MAX_DB_*TH, Red); |
MikamiUitOpen | 0:c5b026c2d07e | 76 | lcd_->fillrect(X_POS, Y0_-DB1_*MAX_DB_*TH, X_POS+5, Y0_, Cyan); |
MikamiUitOpen | 0:c5b026c2d07e | 77 | } |
MikamiUitOpen | 0:c5b026c2d07e | 78 | } |
MikamiUitOpen | 0:c5b026c2d07e | 79 | |
MikamiUitOpen | 0:c5b026c2d07e | 80 | // x-axis |
MikamiUitOpen | 0:c5b026c2d07e | 81 | void SpectrumDisplay::AxisX() |
MikamiUitOpen | 0:c5b026c2d07e | 82 | { |
MikamiUitOpen | 0:c5b026c2d07e | 83 | lcd_->line(X0_, Y0_, X0_+BIN_*N_FFT_/2, Y0_, Yellow); |
MikamiUitOpen | 0:c5b026c2d07e | 84 | float dx = BIN_*(N_FFT_*1000.0f)/(float)FS_; |
MikamiUitOpen | 0:c5b026c2d07e | 85 | for (int n=0; n<=5; n++) |
MikamiUitOpen | 0:c5b026c2d07e | 86 | { |
MikamiUitOpen | 0:c5b026c2d07e | 87 | int xTick = X0_ + (int)(dx*n + 0.5f); |
MikamiUitOpen | 0:c5b026c2d07e | 88 | lcd_->locate(xTick-4, Y0_+10); |
MikamiUitOpen | 0:c5b026c2d07e | 89 | lcd_->printf("%d", n); |
MikamiUitOpen | 0:c5b026c2d07e | 90 | lcd_->line(xTick, Y0_, xTick, Y0_+5, Yellow); |
MikamiUitOpen | 0:c5b026c2d07e | 91 | } |
MikamiUitOpen | 0:c5b026c2d07e | 92 | lcd_->locate(110, Y0_+24); |
MikamiUitOpen | 0:c5b026c2d07e | 93 | lcd_->printf("Frequency [kHz]"); |
MikamiUitOpen | 0:c5b026c2d07e | 94 | } |
MikamiUitOpen | 0:c5b026c2d07e | 95 | |
MikamiUitOpen | 0:c5b026c2d07e | 96 | // y-axis |
MikamiUitOpen | 0:c5b026c2d07e | 97 | void SpectrumDisplay::AxisY() |
MikamiUitOpen | 0:c5b026c2d07e | 98 | { |
MikamiUitOpen | 0:c5b026c2d07e | 99 | lcd_->line(X0_, Y0_+5, X0_, Y0_-(int)(MAX_DB_*DB1_), Yellow); |
MikamiUitOpen | 0:c5b026c2d07e | 100 | for (int n=0; n<=(int)MAX_DB_; n+=20) |
MikamiUitOpen | 0:c5b026c2d07e | 101 | { |
MikamiUitOpen | 0:c5b026c2d07e | 102 | int yTick = Y0_-(int)(DB1_*n); |
MikamiUitOpen | 0:c5b026c2d07e | 103 | lcd_->locate(X0_-22, yTick-5); |
MikamiUitOpen | 0:c5b026c2d07e | 104 | lcd_->printf("%2d", n); |
MikamiUitOpen | 0:c5b026c2d07e | 105 | lcd_->line(X0_-5, yTick, X0_, yTick, Yellow); |
MikamiUitOpen | 0:c5b026c2d07e | 106 | } |
MikamiUitOpen | 0:c5b026c2d07e | 107 | lcd_->locate(X0_-27, Y0_-(int)(DB1_*MAX_DB_)-18); |
MikamiUitOpen | 0:c5b026c2d07e | 108 | lcd_->printf("[dB]"); |
MikamiUitOpen | 0:c5b026c2d07e | 109 | } |
MikamiUitOpen | 0:c5b026c2d07e | 110 | } |