Measuring plethysmogram with BH1792GLC (Rohm Semiconductor) and calculating pulse rate

Dependencies:   USBDevice mbed

PulseRate.h

Committer:
t_tatsuoka
Date:
2018-02-05
Revision:
1:90f70c146a26
Parent:
0:18d735a66926

File content as of revision 1:90f70c146a26:

/**
 *  @file       PulseRate.h
 *  @brief      Header file for PulseRate.cpp
 *  @date       2018.02.06
 *  @version    1.1.1
 */
#ifndef _INC_PulseRate
#define _INC_PulseRate

// #define _OP_MODE_INT_AD         /* When using internal ADC */
#define _OP_MODE_BH1792GLC      /* When using BH1792GLC sensor */

#include "mbed.h"
#ifdef _OP_MODE_BH1792GLC
#include "Bh1792glcCtrl.h"
#endif

#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) */

#ifdef _OP_MODE_INT_AD
#define PEAK_MIN (127)          /* Ignore waveform as pulse under this value */
#elif defined _OP_MODE_BH1792GLC
#define PEAK_MIN (63)           /* Ignore waveform as pulse under this value */
#endif

#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:
#ifdef _OP_MODE_INT_AD
    PulseRate(PinName sensor, PinName sync_led, PinName beep);
#elif defined _OP_MODE_BH1792GLC
    PulseRate(PinName bh_sda, PinName bh_scl, PinName bh_int, PinName sync_led, PinName beep);
#endif
    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 */

#ifdef _OP_MODE_INT_AD
    AnalogIn    _sensor;            /* A/D converter */
#elif defined _OP_MODE_BH1792GLC
    Bh1792glcCtrl  _bh;             /* BH1792GLC Control */
#endif
    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 */
    bool        _sync_flag;         /* Pulse sync sign flag */

    /* Member functions */
    void init();
    void interval_timer();
    int32_t hpf(int32_t val);
    bool detect_peak(int32_t val);
    void calc_pr();
};
#endif    /* INC_PulseRate */