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

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]");
+    }
+}