Interface 2015年4月号 第1部 第5章および第6章のプログラム
Information
FilterTest - Interface 2015年4月号 第1部 第5章 第6章 のソフトウェア
Program for Section 5 and 6 in April 2015 issue of Interface
(Japanese electronics magazine)
概要
このプログラムは、
- ハイパスフィルタ、ローパスフィルタ、ノッチフィルタ
を行うFilterTestクラスと、波形をUSBシリアル通信でホストへ送信するmain関数で構成されています。
FilterTest.h, FilterTest.cpp
- A-Dサンプリング - 1 kSPS
- ハイパスフィルタ(遮断周波数 0.5 Hz、1次バターワース)
- ローパスフィルタ(遮断周波数 30 Hz、2次バターワース)
- ノッチフィルタ(中心周波数 50 Hz、2次)
main.cpp
- データ送信レート - 1 kSPS
- FilterTestクラスのインスタンスを生成
- 処理開始メソッドを実行
- メインループ - ポーリングにより、サンプリング、フィルタ処理完了フラグがセットされたら、
USBシリアル通信経由で、ホストへ送信する
シリアル通信フォーマット
(※)誌面ではパケットサイズ 64 byteとなっていますが、
64 byteでは、PCのUSBドライバが 4096 byteまで保持し、波形が滑らかに描画できないため、
Ver.1.0.2で、32 byteに変更しています。
- 34byte固定長パケット方式
- 波形データパケット1種類
波形データパケット | |
0x00 | パケットヘッダ(固定値0xAA) |
0x01 | データ種別ID(0x01: 波形データ) |
0x02 | パケット番号(0 - 99繰り返し) |
0x03 | ペイロードサイズ(固定値30) |
0x04 - 0x21 | 波形データ(short, big endian) |
Description
This contains FilterTest class and main function.
FilterTest class:
- High pass filter, Low pass, Notch filter
Main function:
- Send waveform to host via USB serial class.
FilterTest.h, FilterTest.cpp
- A-D sampling - 1 kSPS
- High pass filter - Cut off frequency 0.5 Hz, first order butterworth
- Low pass filter - Cut off frequency 30 Hz, second order butterworth
- Notch filter - Center frequency 50 Hz, second order
main.cpp
- Data sending rate - 1 kSPS
- Executing start procedure method
- Main loop - sending waveform data via USB serial interface when detecting ready flag.
Packet format for USB serial interface
- Packet size: 34 bytes(fixed)
- One type of packet waveform packet
Waveform packet | |
0x00 | Packet header (0xAA (fixed)) |
0x01 | Data type ID (0x01: Waveform ID) |
0x02 | Packet number (0 - 99) |
0x03 | Payload size (30 (fixed)) |
0x04 - 0x21 | Waveform data (short, big endian) |
FilterTest.cpp
- Committer:
- t_tatsuoka
- Date:
- 2015-02-21
- Revision:
- 0:7a4d80e7ea81
File content as of revision 0:7a4d80e7ea81:
/** * @file FilterTest.cpp * @brief Calculate filters * HPF: 1st order / LPF: 2nd order / Notch: 2nd order * @date 2015.02.22 * @version 1.0.1 */ #include "FilterTest.h" /** Constructor */ FilterTest::FilterTest () { set_hpf_coef(INIT_HB, INIT_HA); set_lpf_coef(INIT_LB, INIT_LA1, INIT_LA2); set_brf_coef(INIT_NB, INIT_NA1, INIT_NA2); reset_hpf_buf(); reset_lpf_buf(); reset_brf_buf(); } /** Calculate filter * @param val Input value * @param hpf_on High pass filter enable * @param lpf_on Low pass filter enable * @param brf_on Notch filter enable * @return Output value */ double FilterTest::calc(double val, int hpf_on, int lpf_on, int brf_on) { double retVal = val; /* High pass filter */ if(hpf_on) { retVal = hpf(retVal); } else { reset_hpf_buf(); } /* Low pass filter */ if(lpf_on) { retVal = lpf(retVal); } else { reset_lpf_buf(); } /* Notch (Band reject) filter */ if(brf_on) { retVal = brf(retVal); } else { reset_brf_buf(); } return retVal; } /** Reset delay buffers for high pass filter */ void FilterTest::reset_hpf_buf() { _hw = 0.0; } /** Reset delay buffers for low pass filter */ void FilterTest::reset_lpf_buf() { _lw1 = 0.0; _lw2 = 0.0; } /** Reset delay buffers for notch filter */ void FilterTest::reset_brf_buf() { _nw1 = 0.0; _nw2 = 0.0; } /** Set coefficient for HPF * @param hb Numerator cofficient * @param ha Denominator cofficient * @retval true OK * @retval false NG */ bool FilterTest:: set_hpf_coef(double hb, double ha) { if(hb > 1.0) { return false; } else if((ha > 1.0)||(ha < -1.0)) { return false; } else { _hb = hb; _ha = ha; reset_hpf_buf(); return true; } } /** Set coefficient for LPF * @param lb Numerator cofficient * @param la1 Denominator cofficient 1 * @param la2 Denominator cofficient 2 * @retval true OK * @retval false NG */ bool FilterTest:: set_lpf_coef(double lb, double la1, double la2) { if(lb > 1.0) { return false; } else if((la1 > 2.0)||(la1 < -2.0)) { return false; } else if(la2 > 1.0) { return false; } else { _lb = lb; _la1 = la1; _la2 = la2; reset_lpf_buf(); return true; } } /** Set coefficient for BRF * @param nb Numerator cofficient * @param na1 Denominator cofficient 1 * @param na2 Denominator cofficient 2 * @retval true OK * @retval false NG */ bool FilterTest:: set_brf_coef(double nb, double na1, double na2) { if(nb > 1.0) { return false; } else if((na1 > 2.0)||(na1 < -2.0)) { return false; } else if(na2 > 1.0) { return false; } else { _nb = nb; _na1 = na1; _na2 = na2; reset_brf_buf(); return true; } } /** High pass filter (1st order) * @param x Input value * @return Output value * * hb v + * x ---I>---+---O-------+--- y * | hw|- | * | [z] | * | | ha | * +---O---<I--+ */ double FilterTest::hpf(double x) { double v, y; v = _hb * x; y = v - _hw; _hw = v + _ha * y; return y; } /** Low pass filter (2nd order) * @param x Input value * @return Output value * * lb v * x --I>--+-----O-------+--- y * | lw1| | * | [z] | * | 2 | -la1 | * +-I>--O---<I--+ * | lw2| | * | [z] | * | | -la2 | * +-----O---<I--+ */ double FilterTest::lpf(double x) { double v, y; v = _lb * x; y = v + _lw1; _lw1 = 2 * v - _la1 * y + _lw2; _lw2 = v - _la2 * y; return y; } /** Notch filter (Band reject filter) (2nd order) * @param x Input value * @return Output value * * nb v * x -+-I>--+----O-------+--- y * | | nw1| | * | | [z] | * +| na1 | | | * O-I>-------O | * -| | nw2| | * | | [z] | * | | | -na2 | * | +----O---<I--+ * | | * +------------------+ */ double FilterTest::brf(double x) { double v, y; v = _nb * x; y = v + _nw1; _nw1 = _na1 * ( x - y ) + _nw2; _nw2 = v - _na2 * y; return y; }