トランジスタ技術2014年10月号第6章のソフトウェア

Dependencies:   USBDevice mbed

Information

tg_201410s6_Plethysmographs トランジスタ技術 2014年 10月号 第6章のソフトウェア

Program for Section 6 in October. 2014 issue of the Transistor Gijutsu
(Japanese electronics magazine)

概要

このプログラムは、

  • 脈波データ取得(A-Dサンプリング、ハイパスフィルタ)
  • 脈拍数の算出(パルス検出、LEDおよび同期音出力、移動平均処理)

を行うPulseRateクラスと、それらをUSBシリアル通信でホストへ送信するmain関数で構成されています。

PulseRate.h, PulseRate.cpp

  • A-Dサンプリング - 100 SPS
  • ハイパスフィルタ - 遮断周波数0.1Hz、1次バターワースフィルタ
  • パルス検出 - 脈波を微分処理、5point移動平均して速度脈波を求め、
    それを包絡線検波した波形を、速度脈波が再び超える点をパルス開始とする
  • LED、同期音出力 - パルス同期LED(10ms)、圧電サウンダ出力(1kHz、10ms)
  • 移動平均処理 - 直近5拍分の平均値を脈波として算出

main.cpp

  • PulseRateクラスのインスタンスを生成
  • 処理開始メソッドを実行
  • メインループ - ポーリングにより、脈波データ、脈拍数データの完了フラグが返されたら、
    USBシリアル通信経由で、ホストへ送信する

シリアル通信フォーマット

  • 4byte固定長パケット方式
  • 脈波データパケット、脈拍数データパケットの2種類
脈波データパケット脈拍数データパケット
0x00パケットヘッダ(固定値0xAA)パケットヘッダ(固定値0xAA)
0x01波形番号(0 - 99繰り返し)脈拍数ID(固定値0xBB)
0x02, 0x03脈波データ(singed, 2byte)脈拍数データ(20 - 300, 2byte)

Description

This contains PulseRate class and main function.

PulseRate class:

  • Acquiring pulse waveform (A-D sampling, high pass filter)
  • Calculate pulse rate (Detecting pulse, Sync. LED and buzzer, moving averaging)

Main function:

  • Send pulse waveform and rate to host via USB serial class.

PulseRate.h, PulseRate.cpp

  • A-D sampling - 100 SPS
  • High pass filter - Cut off frequency 0.1Hz, first order butterworth
  • Detecting pulse - Calculating velocity pulse waveform by derivation and moving averaging (5point).
    Moreover, calculating threshold waveform like envelope demodulator.
    Detecting point the velocity waveform pass over the threshold waveform as starting pulse.
  • Sync. LED, buzzer - Synchronous pulse LED(10ms), piezo sounder(1kHz, 10ms)
  • Moving averaging - Calculating pulse rate averaging the previous 5 pulse.

main.cpp

  • Generating an instance of PulseRate class
  • Executing start procedure method
  • Main loop - sending pulse waveform data and pulse rate data via USB serial interface when detecting ready in return value.

Packet format for USB serial interface

  • Packet size: 4 bytes(fixed)
  • Two types of packets, pulse waveform packet and pulse rate packet
Pulse waveform packetPulse rate packet
0x00Packet header (0xAA (fixed)))Packet header (0xAA (fixed))
0x01Sampling number (0 - 99)Pulse rate ID (0xBB (fixed))
0x02, 0x03Pulse waveform data (singed, 2byte)Pulse rate data (20 - 300, 2byte)
Revision:
0:f0c12790aadb
diff -r 000000000000 -r f0c12790aadb PulseRate.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PulseRate.h	Thu Sep 11 15:02:45 2014 +0000
@@ -0,0 +1,87 @@
+/**
+ *  @file       PulseRate.h
+ *  @brief      Header file for PulseRate.cpp
+ *  @date       2014.08.08
+ *  @version    1.0.0
+ */
+#ifndef _INC_PulseRate
+#define _INC_PulseRate
+
+#include "mbed.h"
+
+#define LED_ON  (0)
+#define LED_OFF (1)
+
+#define BEEP_FREQ (1000.0)
+#define BEEP_LOUD (0.5)
+
+#define SAMPLING_RATE (0.01)    /* A/D sampling rate (10ms) */
+#define SPL_NUM (100)           /* Range of sampling number (0 - 99) */
+
+#define AD_OFFSET (21845)       /* Offset value for VREF (about +1.1V) */
+
+#define COEF_BH (0x3FCCB062)    /* High pass filter b0, -b1 coefficient 0.1Hz/100Hz Q30 format */
+                                /* Use (0x3F02946A) when 0.5Hz/100Hz Q30 format */
+#define COEF_AH (0x3F9960C5)    /* High pass filter -a1     coefficient 0.1Hz/200Hz Q30 format */
+                                /* Use (0x3E0528D5) when 0.5Hz/100Hz Q30 format */
+
+#define MV_LENGTH (5)           /* Number of moving averaging for pulse detection */
+#define TH_COEF (0.993)         /* Coefficient for pulse threshold (exponential decline) */
+#define PEAK_MIN (127)          /* Ignore waveform as pulse under this value */
+
+#define PR_LENGTH (5)           /* Number of average for pulse rate */
+#define PR_1MIN_SPL (6000)      /* Number of sampling for 1 minute (60*100) */
+#define PR_INT_MAX (300)        /* 20 bpm (60*100/20) */
+#define PR_INT_MIN (20)         /* 300 bpm (60*100/300) */
+
+/** Calculate pulse waveform and pulse rate
+ */
+class PulseRate {
+
+public:
+    PulseRate(PinName sensor, PinName sync_led, PinName beep);
+    void start_sampling();
+    bool get_wave(uint32_t &num, int32_t &wave_val);
+    bool get_pr_val(uint32_t &pr);
+
+private:
+    Ticker      _sampling;          /* Interval timer for data sampling */
+
+    AnalogIn    _sensor;            /* A/D converter */
+    DigitalOut  _sync_led;          /* Synchronous LED */
+    PwmOut      _beep;              /* Piezo sounder */
+
+    /* Pulse waveform */
+    int32_t     _val;               /* Pulse waveform value */
+    int32_t     _prev_val;          /* Previous value */
+    int32_t     _reg_hpf;           /* High pass filter memory value */
+    bool        _wave_flag;         /* Pulse waveform set flag */
+    
+    uint32_t    _sampling_num;      /* Sampling number */
+    
+    /* Moving averaging */
+    int32_t     _mv_buf[MV_LENGTH]; /* Circular buffer */
+    int32_t     _mv_idx;            /* Buffer index */
+    
+    /* Threshold for detecting pulse */
+    int32_t     _detect_val;        /* Detection value */
+    int32_t     _prev_dt_val;       /* Previous data */
+    
+    int32_t     _threshold_val;     /* Threshold value */
+    int32_t     _prev_th_val;       /* Previous data */
+    
+    /* Pulse rate */
+    int32_t     _pr_counter;        /* Counter for pulse rate */
+    int32_t     _pr_buf[PR_LENGTH]; /* Circular buffer */
+    int32_t     _pr_idx;            /* Buffer index */
+    
+    int32_t     _pr;                /* Pulse rate value */
+    bool        _pr_flag;           /* Pulse rate set flag */
+
+    /* Member functions */
+    void interval_timer();
+    int32_t hpf(int32_t val);
+    bool detect_peak(int32_t val);
+    void calc_pr();
+};
+#endif    /* INC_PulseRate */