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

Dependencies:   USBDevice mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers PulseRate.cpp Source File

PulseRate.cpp

Go to the documentation of this file.
00001 /**
00002  *  @file       PulseRate.cpp
00003  *  @brief      Calculate pulse waveform and pulse rate 
00004  *  @date       2014.08.08
00005  *  @version    1.0.0
00006  */
00007  #include "PulseRate.h"
00008 
00009 /** Constructor
00010  *  @param      sensor      Pin for A/D converter
00011  *  @param      sync_led    Pin for synchronous LED
00012  *  @param      beep        Pin for piezo sounder
00013  */
00014  PulseRate::PulseRate(PinName sensor, PinName sync_led, PinName beep) :
00015  _sensor(sensor), _sync_led(sync_led), _beep(beep) {
00016       
00017     _sync_led = LED_OFF;
00018     _val = 0;
00019     _wave_flag = false;
00020     _pr_flag = false;
00021     _sampling_num = 0;
00022     _mv_idx = 0;
00023     _beep.period(1.0/BEEP_FREQ);
00024 }
00025 
00026 /** Start interval timer
00027  */
00028 void PulseRate::start_sampling() {
00029     _sampling.attach(this, &PulseRate::interval_timer, SAMPLING_RATE);
00030 }
00031 
00032 /** Get waveform data
00033  *  @param      &num        Sampling number
00034  *  @param      &wave_val   Waveform value
00035  *  @retval     true        Ready for data
00036  *  @retval     false       Not ready
00037  */ 
00038 bool PulseRate::get_wave(uint32_t &num, int32_t &wave_val) {    
00039     if(_wave_flag) {
00040         _wave_flag = false;
00041         num = _sampling_num;
00042         wave_val = _val;
00043         return true;
00044     } else {
00045         return false;
00046     }
00047 }
00048 
00049 /** Gat pulse rate
00050  *  @param      &pr         Pulse rate
00051  *  @retval     true        Ready for data
00052  *  @retval     false       Not ready
00053  */
00054  bool PulseRate::get_pr_val(uint32_t &pr) {
00055     if(_pr_flag) {
00056         _pr_flag = false;
00057         pr = _pr;
00058         return true; 
00059     } else {
00060         return false;
00061     }
00062 }
00063 
00064 /** Interval timer  
00065  */
00066 void PulseRate::interval_timer() {
00067     
00068     /* Pulse waveform */
00069     _val = ((int32_t)(_sensor.read_u16()) - AD_OFFSET); /* Get AD value */
00070     _val = hpf(_val);                                   /* High pass filter (Comment out if not necessary) */
00071     _sampling_num = (_sampling_num + 1) % SPL_NUM;      /* Update sampling number */
00072     _wave_flag = true;                                  /* Set ready flag for pulse waveform */
00073     
00074     /* Pulse rate */
00075     if(detect_peak(_val)) {     /* If detecting pulse */
00076         calc_pr();              /* Calculate pulse rate including flag set */                              
00077     }
00078     
00079     /* Control LED and Beep */
00080     if(_pr_flag) {
00081         _sync_led = LED_ON;
00082         _beep.write(BEEP_LOUD);        
00083     } else {
00084         _sync_led = LED_OFF;
00085         _beep.write(0); 
00086     }
00087 }
00088 
00089 /** Fixed point high pass filter
00090  *  @param      val         Input value
00091  *  @return                 Output value
00092  *
00093  *  A/D value of mbed is Q6 format.
00094  *  Please shift in advance if necessary.
00095  */
00096 int32_t PulseRate::hpf(int32_t val) {
00097     int32_t reg, ret_val;
00098     int64_t temp_val;
00099     
00100     temp_val = (int64_t)COEF_AH * (int64_t)_reg_hpf;
00101     reg = val + (int32_t)(temp_val >> 30);
00102     ret_val = reg - _reg_hpf;
00103     temp_val = (int64_t)COEF_BH * (int64_t)ret_val;
00104     ret_val = (int32_t)(temp_val >> 30);
00105     _reg_hpf = reg;
00106     return ret_val;
00107 }
00108 
00109 /** Detect pulse peak
00110  *  @param      &val        Waveform data value
00111  *  @retval     true        Detected pulse peak
00112  *  @retval     false       No detection
00113  */
00114 bool PulseRate::detect_peak(int32_t val) {
00115     int i;
00116     bool retVal = false;
00117 
00118     /* Calculate differential of input value */ 
00119     _mv_buf[_mv_idx] = val - _prev_val;
00120     _prev_val = val;
00121     _mv_idx = (_mv_idx + 1) % MV_LENGTH;
00122 
00123     /* Calculate moving averaging */ 
00124     _detect_val = 0;
00125     for(i=0; i<MV_LENGTH; i++)
00126     {
00127         _detect_val += _mv_buf[i];
00128     }
00129     _detect_val = _detect_val / MV_LENGTH;
00130     
00131     /* Calculate exponential decline for threshold line */
00132     _threshold_val = (int32_t)((double)_prev_th_val * TH_COEF);
00133     
00134     if(_detect_val >= _threshold_val) {
00135         /* If exceeding threshold */
00136         if(_prev_dt_val < _prev_th_val){
00137             /* If previous value is under threshold and over ignore value */
00138             if((_detect_val > PEAK_MIN) && (_pr_counter >= PR_INT_MIN)) {
00139                 /* Detecting peak!!! */
00140                 retVal = true;
00141             }
00142         }
00143         /* Previous threshold value is set to input value */
00144         _prev_th_val = _detect_val;
00145     } else {
00146         /* Previous threshold value is set to decline value */
00147         _prev_th_val = _threshold_val;
00148     }
00149     /* Update previous input value */
00150     _prev_dt_val = _detect_val;
00151     
00152     /* Increment pulse rate counter */
00153     _pr_counter++;
00154     
00155     return retVal;
00156 }
00157 
00158 /** Calculate pulse rate
00159  */
00160 void PulseRate::calc_pr() {
00161     int i;
00162 
00163     /* If pulse rate counter is within maximum value */
00164     if(_pr_counter <= PR_INT_MAX) {
00165         /* Calculate moving averaging */ 
00166         _pr_buf[_pr_idx] = _pr_counter;
00167         _pr_idx = (_pr_idx + 1) % PR_LENGTH;
00168         _pr = 0;
00169         for(i=0; i<PR_LENGTH; i++)
00170         {
00171             _pr += _pr_buf[i];
00172         }
00173         /* Set pulse rate value */
00174         _pr =  PR_1MIN_SPL * PR_LENGTH / _pr;
00175     } else {
00176         /* Pulse rate is set to invalid value */
00177         _pr = 0;
00178     }
00179     _pr_counter = 0;
00180 
00181     /* Set pulse rate flag */
00182     _pr_flag = true;
00183 }