PC から,リアルタイム信号処理を行っている Nucleo-F446 を制御する例.

Dependencies:   mbed SerialTxRxIntr F446_AD_DA_Multirate

main.cpp

Committer:
MikamiUitOpen
Date:
2018-10-07
Revision:
3:42f9127d578d
Parent:
2:1aff436cba4a
Child:
4:3087a0841304

File content as of revision 3:42f9127d578d:

//----------------------------------------------------------------------
//  NUCLEO-F446RE で アナログ信号の入出力の際に,出力の標本化周波数を,入力の
//  標本化周波数の4倍にするクラス F446_Multirate を使い,PC からの指令でパラ
//  メータを変更する例
//
//  処理の内容:AD 変換器からの入力に倍率を乗算し DA 変換器に出力する
//            倍率は PC からの指令で変更する
//            PC からの指令: 0.00 ~ 1.00 倍
//            乗算あり/なしは PC からの指令により ACTIVE/THROUGH の切り替えが可能
//
//            "ENQ” を除く PC からの指令については,そのまま PC へ送る
//
//  PC 側のプログラム
//      F446_AD_DA_Ctrl
//      端末エミュレータでも使用可能
//
//  2018/10/06, Copyright (c) 2018 MIKAMI, Naoki
//----------------------------------------------------------------------

#include "F446_Multirate.hpp"
#include "SerialRxTxIntr.hpp"
#include  <cctype>
#pragma diag_suppress 870   // マルチバイト文字使用の警告抑制のため

using namespace Mikami;
                        
const int FS_ = 10000;  // 入力の標本化周波数: 10 kHz
F446_Multirate myAdDa_; // 出力標本化周波数を4倍にするオブジェクト
SerialRxTxIntr rxTx_;   // Serial クラスの受送信割込み用オブジェクト

int main()
{
    printf("\r\n端末エミュレータでも使用可能\r\n");
    printf("端末エミュレータから数値を入力する場合は 0 ~ 65535 の\r\n");
    printf("範囲の数値を入力してください\r\n");
    rxTx_.EchobackEnable();     // エコーバックを有効にする

    // 以下の割り込み優先順位の設定を忘れないこと
    NVIC_SetPriority(ADC_IRQn, 0);      // ADC 終了割り込み:最優先
    NVIC_SetPriority(USART2_IRQn, 1);   // USART2 割り込み:次に優先
    
    float volume = 0.5f;    // 音量を決める変数
    bool sw = true;

    myAdDa_.Start(FS_);     // 標本化を開始する
    while (true)
    {
        //------------------------------------------------------------
        // ここにディジタルフィルタ等の処理を記述する
        float xn = myAdDa_.Input(); // 入力
        float yn = sw ? volume*xn : xn;
        myAdDa_.Output(yn);         // 出力
        //------------------------------------------------------------

        //------------------------------------------------------------
        // PC からの指令に対応する処理
        if (rxTx_.IsEol())          // 受信バッファのデータが有効になった場合の処理
        {
            string str = rxTx_.GetBuffer();
            if (str == "ENQ")
            {
                rxTx_.Tx("ACK\n");      // PC からの "ENQ" に対して "ACK" を送信する
                rxTx_.Tx("LVolume: 0.4000\n");
                char buf[16];
                sprintf(buf, "S%5d\n", (uint32_t)(65535*0.4f));
                rxTx_.Tx(buf);  // スライダ(TrackBar)の位置を送信
            }
            else    // "ENQ" 以外の処理
            {
                if (isalpha(str[0]))    // 先頭が A ~ Z, a ~ z の場合
                {
                    // 大文字に変換する
                    for (int n=0; n<str.size(); n++)
                        str[n] = toupper(str[n]);
                    
                    if (str == "ACTIVE")  sw = true;
                    if (str == "THROUGH") sw = false;  
                }
                else                    // 先頭が A ~ Z, a ~ z 以外の場合
                {
                    // float 型のデータとみなして数値化する
                    volume = atoi(str.c_str())/65535.0f;
                    char buf[32];
                    sprintf(buf, "LVolume: %6.4f\r\n", volume);
                    rxTx_.Tx(buf);
                }
            }
        }
        // PC からの指令に対応する処理はここまで
        //------------------------------------------------------------
    }
}