CW Decoder (Morse code decoder) 1st release version. mbed = 131 revision (Not latest) is used. Only run on DISCO-F746NG mbed board.

Dependencies:   BSP_DISCO_F746NG F746_GUI F746_SAI_IO LCD_DISCO_F746NG TS_DISCO_F746NG UIT_FFT_Real mbed

Base on F746_Spectrogram program created by 不韋 呂-san.
/users/MikamiUitOpen/code/F746_Spectrogram/
Thanks 不韋 呂-san to use fundamental parts such as FFT, SAI, GUI and other useful subroutines.
You do NOT need any modification for mbed hardware and NO additional circuits.
The mbed board read CW tone from your receiver speaker via MEMES microphone (on board) and show it on the screen.

MySpectrogram/MethodCollection.hpp

Committer:
kenjiArai
Date:
2017-02-05
Revision:
0:e608fc311e4e

File content as of revision 0:e608fc311e4e:

//--------------------------------------------------------------
//  スペクトログラムで使う大域関数
//
//  2016/08/11, Copyright (c) 2016 MIKAMI, Naoki
//--------------------------------------------------------------

#ifndef METHOD_COLLECTION_HPP
#define METHOD_COLLECTION_HPP

#include "mbed.h"
#include "NumericLabel.hpp"
#include "Matrix.hpp"
#include "FFT_Analysis.hpp"

namespace Mikami
{
    // 色相の違いで表示
    //      0.0 <= x <= 1.0
    uint32_t HueScale(float x)
    {
        if (x >= 1) return LCD_COLOR_WHITE;
        int r = 0;
        int b = 0;

        if (x<0.5f) b = (x<0.33f) ? 255 : -(int)(1500.0f*x) + 750;
        else        r = (0.67f<x) ? 255 :  (int)(1500.0f*x) - 750;
        int g = 255 - (int)(1020.0f*(x - 0.5f)*(x - 0.5f));

        return 0xFF000000 | (((r << 8) | g) << 8) | b;
    }

    // 座標軸
    void DrawAxis(int x0, int y0, int w0, int h0, uint32_t axisColor,
                  uint16_t ms100, uint16_t px1kHz, LCD_DISCO_F746NG *lcd)
    {
        const uint16_t TICK = 5;    // 目盛線の長さ
        // 横標軸
        lcd->SetTextColor(axisColor);
        lcd->DrawHLine(x0, y0+TICK, w0);
        for (int n=0; n<=w0/ms100; n++)
            if ((n % 10)== 0) lcd->DrawVLine(x0+n*ms100, y0, 5);
            else              lcd->DrawVLine(x0+n*ms100, y0+3, 2);
        for (int n=0; n<=w0/ms100; n+=10)
            NumericLabel<int> num(x0+n*ms100, y0+TICK+3,
                                  "%1d", (int)(n*0.1f), Label::CENTER);
        Label time(x0+w0/2, y0+22, "TIME [s]", Label::CENTER);
    
        // 縦標軸
        lcd->SetTextColor(axisColor);
        lcd->DrawVLine(x0-TICK, y0-h0, h0);
        for (int n=0; n<=h0/px1kHz; n++)
            lcd->DrawHLine(x0-TICK, y0-n*px1kHz, TICK);
        for (int n=0; n<=h0/px1kHz; n++)
            NumericLabel<int> num(x0-TICK-12, y0-n*px1kHz-5, "%1d", n);
        Label hz(x0-32, y0-5*px1kHz-20, "[kHz]");
    }

    // 色と dB の関係の表示
    void ColorDb(int y0, uint32_t axisColor, LCD_DISCO_F746NG *lcd)
    {
        lcd->SetTextColor(axisColor);
        lcd->DrawVLine(455, y0-100, 100);
        for (int n=0; n<=8; n++)
            lcd->DrawHLine(455, y0-(n*100)/8, 4);
        for (int n=0; n<=4; n++)
            NumericLabel<int> num(440, y0-(n*100)/4-5, "%2d", n*20);
        Label dB(432, y0-120, "[dB]");

        for (int n=0; n<=100; n++)
        {
            lcd->SetTextColor(HueScale(n/100.0f));
            lcd->DrawHLine(460, y0-n, 16);
        }
    }

    // スペクトルの更新
    void SpectrumUpdate(Matrix<uint32_t> &x, FftAnalyzer &analyzer,
                        const Array<float> &sn, const Array<float> &db)
    {
        // 過去のスペクトルを一つずらす
        for (int n=0; n<x.Rows()-1; n++)
            for (int k=0; k<x.Cols(); k++)
                x[n][k] = x[n+1][k];

        // 新しいスペクトル
        analyzer.Execute(sn, db);
        const float FACTOR = 1.0f/80.0f;    // 表示範囲: 0 ~ 80 dB
        for (int k=0; k<=x.Cols(); k++)
            x[x.Rows()-1][k] = HueScale(FACTOR*((db[k] > 20) ? db[k]-20 : 0));
    }

    // スペクトルの表示
    void DisplaySpectrum(const Matrix<uint32_t> &x, int x0, int y0,
                         int hBar, LCD_DISCO_F746NG *lcd)
    {
        for (int n=0; n<x.Rows(); n++)
            for (int k=0; k<x.Cols(); k++)
            {
                lcd->SetTextColor(x[n][k]);
                lcd->DrawHLine(x0+n*hBar, y0-k, hBar);
            }
    }
}
#endif  // METHOD_COLLECTION_HPP