Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed SerialTxRxIntr DSP_MultirateLinearphase
Revision 0:f1e2a221b526, committed 2022-02-25
- Comitter:
- MikamiUitOpen
- Date:
- Fri Feb 25 02:26:41 2022 +0000
- Child:
- 1:2d08a91b6bf2
- Commit message:
- 1
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DSP_MultirateLinearphase.lib Fri Feb 25 02:26:41 2022 +0000 @@ -0,0 +1,1 @@ +https://os.mbed.com/users/MikamiUitOpen/code/DSP_MultirateLinearphase/#f7bfe38c93ab
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/IirVariable/Biquad.hpp Fri Feb 25 02:26:41 2022 +0000
@@ -0,0 +1,52 @@
+//--------------------------------------------------------------
+// 縦続形 IIR フィルタの構成要素として使う 2 次の IIR フィルタ
+// b0 は 1 と仮定している
+//
+// 2022/02/19, Copyright (c) 2022 MIKAMI, Naoki
+//--------------------------------------------------------------
+
+#ifndef IIR_BIQUAD_HPP
+#define IIR_BIQUAD_HPP
+
+#include "mbed.h"
+
+namespace Mikami
+{
+ class Biquad
+ {
+ public:
+ // フィルタの係数をまとめて扱うための構造体
+ struct Coefs { float a1, a2, b1, b2; };
+
+ // デフォルト・コンストラクタ
+ // 係数は構造体 Ceofs で与える
+ Biquad(const Coefs ck = (Coefs){0, 0, 0, 0})
+ : c_(ck), vn1_(0), vn2_(0) {}
+
+ // 2 次のフィルタを実行する
+ float Execute(float xn)
+ {
+ float vn = xn + c_.a1*vn1_ + c_.a2*vn2_;
+ float yn = vn + c_.b1*vn1_ + c_.b2*vn2_;
+
+ vn2_ = vn1_;
+ vn1_ = vn;
+
+ return yn;
+ }
+
+ // 係数を設定する
+ void SetCoefs(const Coefs ck) { c_ = ck; }
+
+ // 内部変数(遅延器)のクリア
+ void Clear() { vn1_ = vn2_ = 0; }
+
+ private:
+ Coefs c_;
+ float vn1_, vn2_;
+
+ // コピー・コンストラクタ禁止のため
+ Biquad(const Biquad&);
+ };
+}
+#endif // IIR_BIQUAD_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/IirVariable/IIR_Cascade.hpp Fri Feb 25 02:26:41 2022 +0000
@@ -0,0 +1,56 @@
+//---------------------------------------------------
+// 縦続形 IIR フィルタ
+//
+// 2022/02/19, Copyright (c) 2022 MIKAMI, Naoki
+//---------------------------------------------------
+
+#ifndef IIR_CASCADE_HPP
+#define IIR_CASCADE_HPP
+
+#include "Biquad.hpp"
+#include "Array.hpp" // Array クラスが定義されている
+
+namespace Mikami
+{
+ class IirCascade
+ {
+ public:
+ // コンストラクタ
+ IirCascade(int order = 0, const Biquad hk[] = NULL, float g0 = 1)
+ : order_(order), hn_((order+1)/2, hk), g0_(g0) {}
+
+ // フィルタ処理を実行する
+ float Execute(float xn)
+ {
+ float yn = g0_*xn;
+ for (int k=0; k<(order_+1)/2; k++) yn = hn_[k].Execute(yn);
+ return yn;
+ }
+
+ // 係数の設定
+ void SetCoefs(int order, const Biquad::Coefs ck[], float g0)
+ {
+ if (order_ != order)
+ {
+ order_ = order;
+ hn_.SetSize((order+1)/2);
+ }
+ g0_ = g0;
+ for (int k=0; k<(order+1)/2; k++) hn_[k].SetCoefs(ck[k]);
+ }
+
+ // 内部変数(遅延器)のクリア
+ void Clear()
+ { for (int k=0; k<(order_+1)/2; k++) hn_[k].Clear(); }
+
+ private:
+ int order_; // 次数
+ Array<Biquad> hn_; // Biquad クラスのオブジェクトの配列
+ float g0_; // 利得定数
+
+ // コピー・コンストラクタ,代入演算子禁止禁止のため
+ IirCascade(const IirCascade&);
+ IirCascade& operator=(const IirCascade&);
+ };
+}
+#endif // IIR_CASCADE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/IirVariable/IirVariable.hpp Fri Feb 25 02:26:41 2022 +0000
@@ -0,0 +1,63 @@
+//--------------------------------------------------------------
+// 可変 IIR フィルタのクラス
+//
+// 2022/02/21, Copyright (c) 2022 MIKAMI, Naoki
+//--------------------------------------------------------------
+
+#include "IIR_Cascade.hpp"
+
+#ifndef VARIABLE_IIR_FILTER_HPP
+#define VARIABLE_IIR_FILTER_HPP
+
+namespace Mikami
+{
+ class VariableIir
+ {
+ public:
+ // コンストラクタ
+ VariableIir() : fPtr2_(&VariableIir::Off)
+ {
+ SetOff(); // 最初は出力 Off
+ Validate(); // フィルタ処理有効
+ }
+
+ // IIR フィルタの実行
+ float Execute(float xn) { return (this->*fPtr_)((this->*fPtr2_)(xn)); }
+
+ // IIR フィルタの係数を設定する
+ void SetCoefficients(int order, const Biquad::Coefs ck[], float g0)
+ { iirFilter_.SetCoefs(order, ck, g0); }
+
+ // フィルタの遅延器をクリア
+ void Clear() { iirFilter_.Clear(); }
+
+ // IIR フィルタの処理を有効にする
+ void Validate() { fPtr_ = &VariableIir::Filtering; }
+
+ // IIR フィルタの処理を無効にする
+ void Invalidate() { fPtr_ = &VariableIir::Through; }
+
+ // 出力を On にする
+ void SetOn() { fPtr2_ = &VariableIir::On; }
+
+ // 出力を Off にする
+ void SetOff() { fPtr2_ = &VariableIir::Off; }
+
+ private:
+ IirCascade iirFilter_;
+
+ float (VariableIir::*fPtr_)(float); // フィルタ処理タの有無
+ float (VariableIir::*fPtr2_)(float); // 出力の On/Off
+
+ float Through(float xn) { return xn; } // そのまま出力
+ float Filtering(float xn) // フィルタを実行して出力
+ { return iirFilter_.Execute(xn); }
+ float On(float xn) { return xn; } // 出力: On
+ float Off(float xn) { return 0; } // 出力: Off
+
+ // コピー・コンストラクタ,代入演算子禁止禁止のため
+ VariableIir(const VariableIir&);
+ VariableIir& operator=(const VariableIir&);
+ };
+}
+#endif // VARIABLE_IIR_FILTER_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SerialTxRxIntr.lib Fri Feb 25 02:26:41 2022 +0000 @@ -0,0 +1,1 @@ +https://os.mbed.com/users/MikamiUitOpen/code/SerialTxRxIntr/#268977533f95
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp Fri Feb 25 02:26:41 2022 +0000
@@ -0,0 +1,96 @@
+//------------------------------------------------------------------
+// 遮断周波数可変 IIR フィルタ(LPF, HPF)
+// DA 出力はアップサンプリング使用
+//
+// PC 側のプログラム: F446_VariableLHpfB
+//
+// 2022/02/21, Copyright (c) 2022 MIKAMI, Naoki
+//------------------------------------------------------------------
+
+#include "MultirateLiPh.hpp" // DA でアップサンプリング
+#include "SerialRxTxIntr.hpp"
+#include "IirVariable.hpp"
+#include <cctype> // isalpha(), isdigit() で使用
+using namespace Mikami;
+
+const float FS_ = 44.1f; // 入力の標本化周波数: 44.1 kHz
+MultirateLiPh myAdDa_(FS_); // 出力標本化周波数を4倍にするオブジェクト
+
+// 縦続形 IIR フィルタによる可変フィルタのオブジェクト, 次数: 10 次
+VariableIir filter_;
+
+void Select(string str); // 有効,無効,出力 On/Off に対応する処理の選択
+void NumericCtrl(string str); // フィルタ係数の更新
+
+// LPF/HPF の信号処理
+void AdcIsr()
+{
+ float xn = myAdDa_.Input(); // 入力
+ float yn = filter_.Execute(xn); // IIR フィルタの実行
+ myAdDa_.Output(yn); // 出力
+}
+
+int main()
+{
+ SerialRxTxIntr rx(150); // PC との通信用,バッファサイズ:150,9600 baud
+
+ NVIC_SetPriority(ADC_IRQn, 0); // AD変換終了割り込みの優先度が最高
+ NVIC_SetPriority(USART2_IRQn, 1);
+
+ myAdDa_.Start(&AdcIsr); // 標本化を開始する
+ while (true)
+ {
+ if (rx.IsEol()) // PC からの指令に対応する処理
+ {
+ string str = rx.GetBuffer();
+ if (str == "VrFcB")
+ {
+ rx.TxString("ACK\n"); // "ACK" を送り返す
+ wait_ms(10);
+ rx.Baud(115300); // 以降は 115,300 baud
+ }
+ else
+ {
+ if (isalpha(str[0])) Select(str);
+ else NumericCtrl(str);
+ }
+ }
+ }
+}
+
+// 有効,無効,出力 On/Off に対応する処理の選択
+void Select(string str)
+{
+ if (str == "ACTIVE") filter_.Validate(); // フィルタ処理有効
+ if (str == "THROUGH") filter_.Invalidate(); // フィルタ処理無効
+ if (str == "ON") filter_.SetOn(); // 出力を On
+ if (str == "OFF") filter_.SetOff(); // 出力を Off
+}
+
+// フィルタ係数の設定
+void NumericCtrl(string str)
+{
+ static char typeOld = 'L'; // 最初は LPF
+ char type; // LPF/HPF の区別
+
+ const int N = 5; // 次数の 1/2
+ const int L0 = 13; // 一つの係数当たりの文字数
+ float a1, a2;
+ Biquad::Coefs cfs[N]; // 転送された文字列から変換された係数
+
+ float b1 = atof(str.substr(0, 2).c_str());
+ type = (b1 > 0)? 'L' : 'H';
+
+ for (int n=0; n<N; n++)
+ {
+ a1 = atof(str.substr(n*2*L0+2, L0).c_str());
+ a2 = atof(str.substr((n*2+1)*L0+2, L0).c_str());
+ cfs[n] = (Biquad::Coefs){a1, a2, b1, 1};
+ }
+ float g0 = atof(str.substr(N*2*L0+2, L0).c_str());
+ filter_.SetCoefficients(2*N, cfs, g0); // 係数設定
+
+ // LPF と HPF が切り替わった場合フィルタの遅延器をクリア
+ if (type != typeOld) filter_.Clear();
+ typeOld = type;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Fri Feb 25 02:26:41 2022 +0000 @@ -0,0 +1,1 @@ +https://os.mbed.com/users/mbed_official/code/mbed/builds/65be27845400 \ No newline at end of file