1 /* 2 * Author: Andrei Vasiliu <andrei.vasiliu (at) intel.com> 3 * Author: Yevgeniy Kiveisha <yevgeniy.kiveisha (at) intel.com> 4 * Copyright (c) 2015 Intel Corporation. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining 7 * a copy of this software and associated documentation files (the 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sublicense, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be 15 * included in all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 21 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 */ 25 26 #include <string> 27 #include <stdexcept> 28 #include <unistd.h> 29 #include <stdlib.h> 30 31 #include "pulsensor.h" 32 33 #if defined(JAVACALLBACK) 34 Pulsensor::Pulsensor (Callback *obj_call) : pin_ctx(0) 35 { 36 obj_callback = obj_call; 37 38 sample_counter = 0; 39 last_beat_time = 0; 40 threshold = 512; 41 ibi = 600; 42 trough = 512; 43 peak = 512; 44 is_pulse = FALSE; 45 ret = FALSE; 46 bpm = 0; 47 qs = FALSE; 48 apmlitude = 100; 49 } 50 #else 51 Pulsensor::Pulsensor (callback_handler handler) : pin_ctx(0) 52 { 53 callback = handler; 54 55 sample_counter = 0; 56 last_beat_time = 0; 57 threshold = 512; 58 ibi = 600; 59 trough = 512; 60 peak = 512; 61 is_pulse = FALSE; 62 ret = FALSE; 63 bpm = 0; 64 qs = FALSE; 65 apmlitude = 100; 66 } 67 #endif 68 69 void Pulsensor::start_sampler () 70 { 71 int error; 72 ctx_counter++; 73 usleep (100000); 74 error = pthread_create (&(sample_thread), NULL, &Pulsensor::do_sample, this); 75 if (error != 0) { 76 printf ("ERROR : Cannot created sampler thread.\n"); 77 } 78 } 79 80 void Pulsensor::stop_sampler () { 81 ctx_counter--; 82 } 83 84 void *Pulsensor::do_sample (void *arg) { 85 int data_from_sensor; 86 clbk_data callback_data; 87 88 Pulsensor *pulsensor = static_cast<Pulsensor *>(arg); 89 90 while (pulsensor->ctx_counter) { 91 data_from_sensor = pulsensor->pin_ctx.read (); 92 pulsensor->ret = FALSE; 93 94 pulsensor->sample_counter += 2; 95 int N = pulsensor->sample_counter - pulsensor->last_beat_time; 96 97 if (data_from_sensor < pulsensor->threshold && 98 N > ( pulsensor->ibi / 5)* 3) { 99 if (data_from_sensor < pulsensor->trough) { 100 pulsensor->trough = data_from_sensor; 101 } 102 } 103 104 if (data_from_sensor > pulsensor->threshold && 105 data_from_sensor > pulsensor->peak) { 106 pulsensor->peak = data_from_sensor; 107 } 108 109 if (N > 250) { 110 // printf ("(NO_GDB) DEBUG\n"); 111 if ( (data_from_sensor > pulsensor->threshold) && 112 (pulsensor->is_pulse == FALSE) && 113 (N > (pulsensor->ibi / 5)* 3) ) { 114 pulsensor->is_pulse = callback_data.is_heart_beat = TRUE; 115 #if defined(JAVACALLBACK) 116 pulsensor->obj_callback->run(callback_data); 117 #else 118 pulsensor->callback(callback_data); 119 #endif 120 121 pulsensor->ibi = pulsensor->sample_counter - pulsensor->last_beat_time; 122 pulsensor->last_beat_time = pulsensor->sample_counter; 123 124 // second beat 125 if (pulsensor->second_beat) { 126 pulsensor->second_beat = FALSE; 127 for (int i = 0; i <= 9; i++) { 128 pulsensor->ibi_rate[i] = pulsensor->ibi; 129 } 130 } 131 132 // first beat 133 if (pulsensor->first_beat) { 134 pulsensor->first_beat = FALSE; 135 pulsensor->second_beat = TRUE; 136 pulsensor->ret = TRUE; 137 } else { 138 uint32_t running_total = 0; 139 for(int i = 0; i <= 8; i++){ 140 pulsensor->ibi_rate[i] = pulsensor->ibi_rate[i+1]; 141 running_total += pulsensor->ibi_rate[i]; 142 } 143 144 pulsensor->ibi_rate[9] = pulsensor->ibi; 145 running_total += pulsensor->ibi_rate[9]; 146 running_total /= 10; 147 pulsensor->bpm = 60000 / running_total; 148 pulsensor->qs = TRUE; 149 } 150 } 151 } 152 153 if (pulsensor->ret == FALSE) { 154 if (data_from_sensor < pulsensor->threshold && 155 pulsensor->is_pulse == TRUE) { 156 pulsensor->is_pulse = callback_data.is_heart_beat = FALSE; 157 #if defined(JAVACALLBACK) 158 pulsensor->obj_callback->run(callback_data); 159 #else 160 pulsensor->callback(callback_data); 161 #endif 162 pulsensor->is_pulse = FALSE; 163 pulsensor->apmlitude = pulsensor->peak - pulsensor->trough; 164 pulsensor->threshold = pulsensor->apmlitude / 2 + pulsensor->trough; 165 pulsensor->peak = pulsensor->threshold; 166 pulsensor->trough = pulsensor->threshold; 167 } 168 169 if (N > 2500) { 170 pulsensor->threshold = 512; 171 pulsensor->peak = 512; 172 pulsensor->trough = 512; 173 pulsensor->last_beat_time = pulsensor->sample_counter; 174 pulsensor->first_beat = TRUE; 175 pulsensor->second_beat = FALSE; 176 } 177 } 178 179 usleep (2000); 180 } 181 return NULL; 182 } 183