1 /*
2 * Author: Andrei Vasiliu <andrei.vasiliu@intel.com>
3 * Author: Yevgeniy Kiveisha <yevgeniy.kiveisha@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)
Pulsensor(Callback * obj_call)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
Pulsensor(callback_handler handler)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
start_sampler()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
stop_sampler()80 void Pulsensor::stop_sampler () {
81 ctx_counter--;
82 }
83
do_sample(void * arg)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