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

Dependencies:   USBDevice mbed

Bh1792glcCtrl.cpp

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

File content as of revision 1:90f70c146a26:

/**
 *  @file       Bh1792glcCtrl.cpp
 *  @brief      Control BH1792GLC (Plethysmogram sensor by Rohm Semiconductor)
 *  @date       2018.02.06
 *  @version    1.0.1
 */
#include "Bh1792glcCtrl.h"

/** Constructor
 *  @param      bh_sda      Pin for SDA on BH1792GLC
 *  @param      bh_scl      Pin for SCL on BH1792GLC
 *  @param      bh_int      Pin for INT on BH1792GLC
 */
Bh1792glcCtrl::Bh1792glcCtrl(PinName bh_sda, PinName bh_scl, PinName bh_int) :
    _i2c(bh_sda, bh_scl), _bh_int(bh_int)
{
    init();
}

/** Get waveform data
 *  @param      *val        Result value
 *  @retval     Status
 */
int Bh1792glcCtrl::get_val(int32_t &val)
{
    int i;
    int ret;
    uint8_t read_addr[1] = { BH1792_ADDR_GDATA_LEDOFF_LSBS };
    uint8_t reg_val[4];
    uint16_t led_val[2];

    ret = start_measure();
    if (ret) {
        // Measuring start error
        return ret;
    }

    for(i=0; i<INT_CHECK_COUNT_LIMIT; i++) {
        if(_bh_int.read() == 0) {
            ret = _i2c.write((_sad | 0), (const char*)read_addr, 1, true);
            if (ret) {
                // Read command error
                return ret;
            }
            ret = _i2c.read((_sad | 1), (char *)reg_val, 4);
            if (ret) {
                // Read data error
                return ret;
            }
            led_val[0] = ((unsigned short)reg_val[1] << 8) | (reg_val[0]);     /* When LED off */
            led_val[1] = ((unsigned short)reg_val[3] << 8) | (reg_val[2]);     /* When LED on */
            val = (int32_t)led_val[1] - (int32_t)led_val[0];
            break;
        }
        wait_us(INT_CHECK_INTERVAL_US);
    }
    if(i >= INT_CHECK_COUNT_LIMIT) {
        // INT timeout error
        return BH1792_I2C_ERR;
    }

    return BH1792_SUCCESS;
}

/** Initialize
 *  @retval     Status
 */
int Bh1792glcCtrl::init()
{
    int ret = BH1792_SUCCESS;
    _sad = (BH1792_SLAVE_ADDR << 1);

    _i2c.frequency(I2C_FREQENCY);
    wait(0.1);

    ret = send_default_params();
    return ret;
}

/** Send default settings to BH1792GLC
 *  @retval     Status
 */
int Bh1792glcCtrl::send_default_params()
{
    int ret = BH1792_SUCCESS;
    int32_t len = DEFAULT_PARAM_SIZE + 1;
    uint8_t reg[len];

    reg[0] = BH1792_ADDR_MEAS_CTRL1;
    reg[1] = (BH1792_PRM_RDY << 7) | (BH1792_PRM_SEL_ADC_GREEN << 4) | BH1792_PRM_MSR_SINGLE;
    reg[2] = (BH1792_PRM_LED_EN1_0 << 6) | BH1792_PRM_LED_CUR1_MA(DEFAULT_LED_CURRENT1);
    reg[3] = (BH1792_PRM_LED_EN2_0 << 7) | BH1792_PRM_LED_CUR2_MA(DEFAULT_LED_CURRENT2);
    reg[4] = (uint8_t)DEFAULT_MEAS_CTRL4_LSB;
    reg[5] = (uint8_t)DEFAULT_MEAS_CTRL4_MSB;
    reg[6] = BH1792_PRM_INT_SEL_SGL;

    ret = _i2c.write((_sad | 0), (char *)reg, len);
    return ret;
}

/** Start measuring plethysmotram
 *  @retval     Status
 */
int Bh1792glcCtrl::start_measure()
{
    int32_t ret = BH1792_SUCCESS;
    uint8_t reg[2];

    reg[0] = BH1792_ADDR_MEAS_START;
    reg[1] = BH1792_PRM_MEAS_ST;

    ret = _i2c.write((_sad | 0), (char *)reg, 2);
    return ret;
}