Home | History | Annotate | Download | only in pulsensor
      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