Library for the Grove Earbud Heartrate Sensor
Dependents: BLE_Police_HRM_Earbud df-2014-salesforce-hrm-k64f BLE_HeartRate_ppm emoSound ... more
GroveEarbudSensor.cpp
00001 /* Copyright C2014 ARM, MIT License 00002 * 00003 * Author: Doug Anson (doug.anson@arm.com) 00004 * 00005 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software 00006 * and associated documentation files the "Software", to deal in the Software without restriction, 00007 * including without limitation the rights to use, copy, modify, merge, publish, distribute, 00008 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 00009 * furnished to do so, subject to the following conditions: 00010 * 00011 * The above copyright notice and this permission notice shall be included in all copies or 00012 * substantial portions of the Software. 00013 * 00014 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 00015 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 00016 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 00017 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00018 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00019 */ 00020 00021 #include "GroveEarbudSensor.h" 00022 00023 // Console logging 00024 //#define LOG_CONSOLE(...) { if (this->m_pc != NULL) this->m_pc->printf(__VA_ARGS__); } 00025 #define LOG_CONSOLE(...) { ; } 00026 00027 // Our instance 00028 GroveEarbudSensor *_grove_earbud_sensor_instance = NULL; 00029 00030 // interrupt function 00031 void __grove_earbud_sensor_interrupt() { if (_grove_earbud_sensor_instance != NULL) _grove_earbud_sensor_instance->interrupt(); } 00032 00033 // constructor 00034 GroveEarbudSensor::GroveEarbudSensor(InterruptIn *rx,RawSerial *pc) { 00035 _grove_earbud_sensor_instance = this; 00036 this->m_rx = rx; 00037 this->m_pc = pc; 00038 this->m_sub = 0; 00039 this->m_counter = 0; 00040 this->m_data_effect = true; 00041 this->m_cb_fn = NULL; 00042 this->m_cb_data = NULL; 00043 this->m_heartrate = HEARTRATE_OFF; 00044 this->m_timer = new Timer(); 00045 this->m_internal_interrupt_instance = false; 00046 00047 // register the interrupt handler 00048 if (this->m_rx != NULL) this->m_rx->rise(&__grove_earbud_sensor_interrupt); 00049 00050 // start the timer and initialize the summation array 00051 if (this->m_timer != NULL) { 00052 // start the timer 00053 this->m_timer->start(); 00054 00055 // initialize the summation array 00056 this->initSummationArray(); 00057 } 00058 } 00059 00060 // constructor 00061 GroveEarbudSensor::GroveEarbudSensor(PinName interrupt_pin,RawSerial *pc) { 00062 _grove_earbud_sensor_instance = this; 00063 this->m_rx = new InterruptIn(interrupt_pin); 00064 this->m_pc = pc; 00065 this->m_sub = 0; 00066 this->m_counter = 0; 00067 this->m_data_effect = true; 00068 this->m_cb_fn = NULL; 00069 this->m_cb_data = NULL; 00070 this->m_heartrate = HEARTRATE_OFF; 00071 this->m_timer = new Timer(); 00072 this->m_internal_interrupt_instance = true; 00073 00074 // register the interrupt handler 00075 if (this->m_rx != NULL) this->m_rx->rise(&__grove_earbud_sensor_interrupt); 00076 00077 // start the timer and initialize the summation array 00078 if (this->m_timer != NULL) { 00079 // start the timer 00080 this->m_timer->start(); 00081 00082 // initialize the summation array 00083 this->initSummationArray(); 00084 } 00085 } 00086 00087 // destructor 00088 GroveEarbudSensor::~GroveEarbudSensor() { 00089 if (this->m_timer != NULL) delete this->m_timer; 00090 if (this->m_internal_interrupt_instance == true && this->m_rx != NULL) delete this->m_rx; 00091 } 00092 00093 // initialize the summation array 00094 void GroveEarbudSensor::initSummationArray(void) { 00095 for(int i=0;i<(NUM_SLOTS-1);++i) this->m_temp[i]=0; 00096 this->m_temp[NUM_SLOTS-1] = this->m_timer->read_ms(); 00097 } 00098 00099 // register callback 00100 void GroveEarbudSensor::registerCallback(GroveEarbudSensorCallback *cb_fn,void *cb_data) { 00101 this->m_cb_fn = cb_fn; 00102 this->m_cb_data = cb_data; 00103 } 00104 00105 // get the current heartrate 00106 float GroveEarbudSensor::getHeartRate(void) { return this->m_heartrate; } 00107 00108 // summation method + internal callback to fire any registered callback fns 00109 void GroveEarbudSensor::sumAndInvokeCallback(void) { 00110 if(this->m_data_effect) { 00111 // summation 00112 int tmp = 60 * (NUM_SLOTS-1) * 1000; 00113 this->m_heartrate = tmp/(this->m_temp[NUM_SLOTS-1]-this->m_temp[0]); 00114 00115 // DEBUG/Log 00116 if (this->m_heartrate > 0) LOG_CONSOLE("heartrate: %d bpm\r\n",this->m_heartrate); 00117 00118 // invoke any callbacks we might have 00119 if (this->m_cb_fn != NULL) { 00120 // invoke the callback 00121 LOG_CONSOLE("invoking callback with heartrate = %d bpm\r\n",this->m_heartrate); 00122 (*this->m_cb_fn)(this->m_heartrate,this->m_cb_data); 00123 } 00124 } 00125 this->m_data_effect = 1; //sign bit 00126 } 00127 00128 // interrupt() method for earbud 00129 void GroveEarbudSensor::interrupt() { 00130 this->m_temp[this->m_counter] = this->m_timer->read_ms(); 00131 switch(this->m_counter) { 00132 case 0: 00133 this->m_sub=this->m_temp[this->m_counter]-this->m_temp[NUM_SLOTS-1]; 00134 break; 00135 default: 00136 this->m_sub=this->m_temp[this->m_counter]-this->m_temp[this->m_counter-1]; 00137 break; 00138 } 00139 if(this->m_sub > HEARTPULSE_DUTY) { 00140 this->m_data_effect = 0; //sign bit 00141 this->m_counter = 0; 00142 LOG_CONSOLE("heartrate measure error. Restarting timer..\r\n"); 00143 this->initSummationArray(); 00144 this->m_timer->stop(); 00145 this->m_timer->start(); 00146 } 00147 if (this->m_counter >= (NUM_SLOTS-1) && this->m_data_effect) { 00148 this->m_counter = 0; 00149 this->sumAndInvokeCallback(); 00150 } 00151 else if(this->m_counter < (NUM_SLOTS-1) && this->m_data_effect) { 00152 this->m_counter++; 00153 } 00154 else { 00155 this->m_counter = 0; 00156 this->m_data_effect = 1; 00157 } 00158 } 00159
Generated on Fri Jul 15 2022 13:36:17 by 1.7.2