Demo Heart Rate with PAH8011

Dependencies:   pixart_heart_rate pixart_pah8011

Dependents:   PAH8011_nRF52_Program PixArt_PAH8011_HeartRate_NUCLEO-L476RG PixArt_PAH8011_HR_NUCLEO-L476RG

pixart_heart_rate_demo.cpp

Committer:
bell_huang
Date:
2019-01-23
Revision:
5:4fe132cb9273
Parent:
3:e03a9fcf825c

File content as of revision 5:4fe132cb9273:

#include "pixart_heart_rate_demo.h"

#include "system_clock.h"

#include "pixart_heart_rate.h"
#include "pixart_pah8011.h"


namespace pixart {
    
    
    static Serial *pc = NULL;
    
    
    heart_rate_demo::heart_rate_demo(I2C &i2c, InterruptIn &interrupt, Serial &serial)
        : m_i2c(i2c)
        , m_interrupt(interrupt)
        , m_has_pah8011_interrupt(false)
        , m_pah8011_interrupt_timestamp(0)
    {
        pc = &serial;
    }
    
    void heart_rate_demo::run()
    {
        pc->printf("Pixart Demo HeartRate with PAH8011\n");
        
        // system clock
        system_clock_init();
        
        // interrupt
        m_interrupt.rise(this, &heart_rate_demo::pah8011_interrupt_handle);
        
        // heart_rate
        pixart::heart_rate heart_rate(heart_rate_demo::time_to_millisec);
        heart_rate.enable_debug_print(heart_rate_demo::debug_print);
        if (!heart_rate.init())
        {
            pc->printf("heart_rate.init() failed\n");
            error_handler();
        }
        
        // pah8011
        pixart::pah8011 pah8011(m_i2c);
        pah8011.enable_debug_print(heart_rate_demo::debug_print);
        if (!pah8011.init())
        {
            pc->printf("pah8011.init() failed\n");
            error_handler();
        }
        if (!pah8011.enable_ppg())
        {
            pc->printf("pah8011.enable_ppg() failed\n");
            error_handler();
        }
        
        while(true)
        {
            if (m_has_pah8011_interrupt)
            {
                m_has_pah8011_interrupt = false;
            
                if (!pah8011.task())
                {
                    pc->printf("pah8011.task() failed\n");
                    error_handler();
                }
            
                pixart::pah8011::task_result result;
                if (pah8011.get_result(result))
                {
                    if (result.ch_num != 2)
                        error_handler();
                
                    for (uint32_t i = 0; i < result.num_per_ch; ++i)
                    {
                        // set ppg sample
                        pixart::heart_rate::ppg_sample ppg_sample;
                        ppg_sample.ch1 = result.data[i * result.ch_num + 0];
                        ppg_sample.ch2 = result.data[i * result.ch_num + 1];
                        ppg_sample.is_touched = result.is_touched;
                        ppg_sample.timestamp = m_pah8011_interrupt_timestamp;
                        heart_rate.set_ppg_sample(ppg_sample);
                    
                        // set accel sample (dummy)
                        pixart::heart_rate::accel_sample accel_sample;
                        accel_sample.x = 0.0f;
                        accel_sample.y = 0.0f;
                        accel_sample.z = 0.0f;
                        accel_sample.timestamp = m_pah8011_interrupt_timestamp;
                        heart_rate.set_accel_sample(accel_sample);                
                    }
                
                    pixart::heart_rate::result hr_result = heart_rate.get_result();
                    switch (hr_result.ret)
                    {
                    case pixart::heart_rate::ret_success:
                        pc->printf("hr = %d, hr_trust_level = %d\n", (int)hr_result.hr, hr_result.hr_trust_level);
                        break;
                        
                    case pixart::heart_rate::ret_no_touch:
                        pc->printf("no touch\n");
                        break;
                        
                    case pixart::heart_rate::ret_signal_poor:
                        pc->printf("signal is poor\n");
                        break;
                        
                    default:
                        pc->printf("heart_rate.get_result() failed, ret = %d\n", hr_result.ret);
                        error_handler();
                        break;
                    }
                }
            }
        }
    }
    
    void heart_rate_demo::error_handler()
    {
        pc->printf("error_handler()!\n");
    
        while (true)
        {
        }
    }

    void heart_rate_demo::debug_print(const char *fmt, ...)
    {
        char msg[128];
        va_list marker;
        va_start(marker, fmt);
        vsprintf(msg, fmt, marker);
        va_end(marker);
        
        pc->printf(msg);
    }
    
    uint64_t heart_rate_demo::time_to_millisec(uint64_t time)
    {
        return system_clock_time_to_milliseconds(time);
    }

    void heart_rate_demo::pah8011_interrupt_handle(void)
    {
        m_has_pah8011_interrupt = true;
        m_pah8011_interrupt_timestamp = system_clock_get_tick();
    }

}