トランジスタ技術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)
Committer:
t_tatsuoka
Date:
Thu Sep 11 15:02:45 2014 +0000
Revision:
0:f0c12790aadb
Name?tg_201410s6_Plethysmographs; Description?????????2014?10???6????????; Publish in :CQ Publishing

Who changed what in which revision?

UserRevisionLine numberNew contents of line
t_tatsuoka 0:f0c12790aadb 1 /**
t_tatsuoka 0:f0c12790aadb 2 * @file PulseRate.h
t_tatsuoka 0:f0c12790aadb 3 * @brief Header file for PulseRate.cpp
t_tatsuoka 0:f0c12790aadb 4 * @date 2014.08.08
t_tatsuoka 0:f0c12790aadb 5 * @version 1.0.0
t_tatsuoka 0:f0c12790aadb 6 */
t_tatsuoka 0:f0c12790aadb 7 #ifndef _INC_PulseRate
t_tatsuoka 0:f0c12790aadb 8 #define _INC_PulseRate
t_tatsuoka 0:f0c12790aadb 9
t_tatsuoka 0:f0c12790aadb 10 #include "mbed.h"
t_tatsuoka 0:f0c12790aadb 11
t_tatsuoka 0:f0c12790aadb 12 #define LED_ON (0)
t_tatsuoka 0:f0c12790aadb 13 #define LED_OFF (1)
t_tatsuoka 0:f0c12790aadb 14
t_tatsuoka 0:f0c12790aadb 15 #define BEEP_FREQ (1000.0)
t_tatsuoka 0:f0c12790aadb 16 #define BEEP_LOUD (0.5)
t_tatsuoka 0:f0c12790aadb 17
t_tatsuoka 0:f0c12790aadb 18 #define SAMPLING_RATE (0.01) /* A/D sampling rate (10ms) */
t_tatsuoka 0:f0c12790aadb 19 #define SPL_NUM (100) /* Range of sampling number (0 - 99) */
t_tatsuoka 0:f0c12790aadb 20
t_tatsuoka 0:f0c12790aadb 21 #define AD_OFFSET (21845) /* Offset value for VREF (about +1.1V) */
t_tatsuoka 0:f0c12790aadb 22
t_tatsuoka 0:f0c12790aadb 23 #define COEF_BH (0x3FCCB062) /* High pass filter b0, -b1 coefficient 0.1Hz/100Hz Q30 format */
t_tatsuoka 0:f0c12790aadb 24 /* Use (0x3F02946A) when 0.5Hz/100Hz Q30 format */
t_tatsuoka 0:f0c12790aadb 25 #define COEF_AH (0x3F9960C5) /* High pass filter -a1 coefficient 0.1Hz/200Hz Q30 format */
t_tatsuoka 0:f0c12790aadb 26 /* Use (0x3E0528D5) when 0.5Hz/100Hz Q30 format */
t_tatsuoka 0:f0c12790aadb 27
t_tatsuoka 0:f0c12790aadb 28 #define MV_LENGTH (5) /* Number of moving averaging for pulse detection */
t_tatsuoka 0:f0c12790aadb 29 #define TH_COEF (0.993) /* Coefficient for pulse threshold (exponential decline) */
t_tatsuoka 0:f0c12790aadb 30 #define PEAK_MIN (127) /* Ignore waveform as pulse under this value */
t_tatsuoka 0:f0c12790aadb 31
t_tatsuoka 0:f0c12790aadb 32 #define PR_LENGTH (5) /* Number of average for pulse rate */
t_tatsuoka 0:f0c12790aadb 33 #define PR_1MIN_SPL (6000) /* Number of sampling for 1 minute (60*100) */
t_tatsuoka 0:f0c12790aadb 34 #define PR_INT_MAX (300) /* 20 bpm (60*100/20) */
t_tatsuoka 0:f0c12790aadb 35 #define PR_INT_MIN (20) /* 300 bpm (60*100/300) */
t_tatsuoka 0:f0c12790aadb 36
t_tatsuoka 0:f0c12790aadb 37 /** Calculate pulse waveform and pulse rate
t_tatsuoka 0:f0c12790aadb 38 */
t_tatsuoka 0:f0c12790aadb 39 class PulseRate {
t_tatsuoka 0:f0c12790aadb 40
t_tatsuoka 0:f0c12790aadb 41 public:
t_tatsuoka 0:f0c12790aadb 42 PulseRate(PinName sensor, PinName sync_led, PinName beep);
t_tatsuoka 0:f0c12790aadb 43 void start_sampling();
t_tatsuoka 0:f0c12790aadb 44 bool get_wave(uint32_t &num, int32_t &wave_val);
t_tatsuoka 0:f0c12790aadb 45 bool get_pr_val(uint32_t &pr);
t_tatsuoka 0:f0c12790aadb 46
t_tatsuoka 0:f0c12790aadb 47 private:
t_tatsuoka 0:f0c12790aadb 48 Ticker _sampling; /* Interval timer for data sampling */
t_tatsuoka 0:f0c12790aadb 49
t_tatsuoka 0:f0c12790aadb 50 AnalogIn _sensor; /* A/D converter */
t_tatsuoka 0:f0c12790aadb 51 DigitalOut _sync_led; /* Synchronous LED */
t_tatsuoka 0:f0c12790aadb 52 PwmOut _beep; /* Piezo sounder */
t_tatsuoka 0:f0c12790aadb 53
t_tatsuoka 0:f0c12790aadb 54 /* Pulse waveform */
t_tatsuoka 0:f0c12790aadb 55 int32_t _val; /* Pulse waveform value */
t_tatsuoka 0:f0c12790aadb 56 int32_t _prev_val; /* Previous value */
t_tatsuoka 0:f0c12790aadb 57 int32_t _reg_hpf; /* High pass filter memory value */
t_tatsuoka 0:f0c12790aadb 58 bool _wave_flag; /* Pulse waveform set flag */
t_tatsuoka 0:f0c12790aadb 59
t_tatsuoka 0:f0c12790aadb 60 uint32_t _sampling_num; /* Sampling number */
t_tatsuoka 0:f0c12790aadb 61
t_tatsuoka 0:f0c12790aadb 62 /* Moving averaging */
t_tatsuoka 0:f0c12790aadb 63 int32_t _mv_buf[MV_LENGTH]; /* Circular buffer */
t_tatsuoka 0:f0c12790aadb 64 int32_t _mv_idx; /* Buffer index */
t_tatsuoka 0:f0c12790aadb 65
t_tatsuoka 0:f0c12790aadb 66 /* Threshold for detecting pulse */
t_tatsuoka 0:f0c12790aadb 67 int32_t _detect_val; /* Detection value */
t_tatsuoka 0:f0c12790aadb 68 int32_t _prev_dt_val; /* Previous data */
t_tatsuoka 0:f0c12790aadb 69
t_tatsuoka 0:f0c12790aadb 70 int32_t _threshold_val; /* Threshold value */
t_tatsuoka 0:f0c12790aadb 71 int32_t _prev_th_val; /* Previous data */
t_tatsuoka 0:f0c12790aadb 72
t_tatsuoka 0:f0c12790aadb 73 /* Pulse rate */
t_tatsuoka 0:f0c12790aadb 74 int32_t _pr_counter; /* Counter for pulse rate */
t_tatsuoka 0:f0c12790aadb 75 int32_t _pr_buf[PR_LENGTH]; /* Circular buffer */
t_tatsuoka 0:f0c12790aadb 76 int32_t _pr_idx; /* Buffer index */
t_tatsuoka 0:f0c12790aadb 77
t_tatsuoka 0:f0c12790aadb 78 int32_t _pr; /* Pulse rate value */
t_tatsuoka 0:f0c12790aadb 79 bool _pr_flag; /* Pulse rate set flag */
t_tatsuoka 0:f0c12790aadb 80
t_tatsuoka 0:f0c12790aadb 81 /* Member functions */
t_tatsuoka 0:f0c12790aadb 82 void interval_timer();
t_tatsuoka 0:f0c12790aadb 83 int32_t hpf(int32_t val);
t_tatsuoka 0:f0c12790aadb 84 bool detect_peak(int32_t val);
t_tatsuoka 0:f0c12790aadb 85 void calc_pr();
t_tatsuoka 0:f0c12790aadb 86 };
t_tatsuoka 0:f0c12790aadb 87 #endif /* INC_PulseRate */