diff --git a/src/pulsensor/Callback.h b/src/pulsensor/Callback.h new file mode 100644 index 00000000..f9c291a2 --- /dev/null +++ b/src/pulsensor/Callback.h @@ -0,0 +1,15 @@ +#pragma once + +#if defined(SWIGJAVA) || defined(JAVACALLBACK) +class Callback +{ + public: + virtual ~Callback() + { + } + virtual void run(clbk_data arg) + { /* empty, overloaded in Java*/ + } +}; + +#endif diff --git a/src/pulsensor/javaupm_pulsensor.i b/src/pulsensor/javaupm_pulsensor.i index 8767c602..0942206c 100644 --- a/src/pulsensor/javaupm_pulsensor.i +++ b/src/pulsensor/javaupm_pulsensor.i @@ -2,11 +2,14 @@ %include "../upm.i" %include "arrays_java.i" +%feature("director") Callback; + %ignore sample_thread; %ignore pin_ctx; %ignore do_sample; %ignore callback; +%include "Callback.h" %{ #include "pulsensor.h" %} diff --git a/src/pulsensor/pulsensor.cxx b/src/pulsensor/pulsensor.cxx index e8634885..3d933aac 100644 --- a/src/pulsensor/pulsensor.cxx +++ b/src/pulsensor/pulsensor.cxx @@ -1,6 +1,7 @@ /* + * Author: Andrei Vasiliu * Author: Yevgeniy Kiveisha - * Copyright (c) 2014 Intel Corporation. + * Copyright (c) 2015 Intel Corporation. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the @@ -26,126 +27,153 @@ #include #include #include + #include "pulsensor.h" -void init_pulsensor (pulsensor_context * ctx, callback_handler handler) { - ctx->callback = handler; +#if defined(JAVACALLBACK) +Pulsensor::Pulsensor (Callback *obj_call) : pin_ctx(0) +{ + obj_callback = obj_call; - if ( !(ctx->pin_ctx = mraa_aio_init(0)) ) - { - throw std::invalid_argument(std::string(__FUNCTION__) + - ": mraa_aio_init() failed, invalid pin?"); - return; - } + sample_counter = 0; + last_beat_time = 0; + threshold = 512; + ibi = 600; + trough = 512; + peak = 512; + is_pulse = FALSE; + ret = FALSE; + bpm = 0; + qs = FALSE; + apmlitude = 100; - ctx->sample_counter = 0; - ctx->last_beat_time = 0; - ctx->threshold = 512; - ctx->ibi = 600; - ctx->trough = 512; - ctx->peak = 512; - ctx->is_pulse = FALSE; - ctx->ret = FALSE; - ctx->bpm = 0; - ctx->qs = FALSE; - ctx->apmlitude = 100; } +#else +Pulsensor::Pulsensor (callback_handler handler) : pin_ctx(0) +{ + callback = handler; -void start_sampler (pulsensor_context * ctx) { + sample_counter = 0; + last_beat_time = 0; + threshold = 512; + ibi = 600; + trough = 512; + peak = 512; + is_pulse = FALSE; + ret = FALSE; + bpm = 0; + qs = FALSE; + apmlitude = 100; +} +#endif + +void Pulsensor::start_sampler () +{ int error; ctx_counter++; usleep (100000); - error = pthread_create (&(ctx->sample_thread), NULL, &do_sample, (void *) ctx); + error = pthread_create (&(sample_thread), NULL, &Pulsensor::do_sample, this); if (error != 0) { printf ("ERROR : Cannot created sampler thread.\n"); } } -void stop_sampler (pulsensor_context * ctx) { - ctx_counter--; +void Pulsensor::stop_sampler () { + Pulsensor::ctx_counter--; } -void * do_sample (void * arg) { +void *Pulsensor::do_sample (void *arg) { int data_from_sensor; clbk_data callback_data; - while (ctx_counter) { - pulsensor_context * ctx = (pulsensor_context *) arg; - mraa_aio_context pin = ctx->pin_ctx; - data_from_sensor = mraa_aio_read (pin); - ctx->ret = FALSE; - ctx->sample_counter += 2; - int N = ctx->sample_counter - ctx->last_beat_time; + Pulsensor *pulsensor = static_cast(arg); - if (data_from_sensor < ctx->threshold && N > ( ctx->ibi / 5)* 3) { - if (data_from_sensor < ctx->trough) { - ctx->trough = data_from_sensor; + while (Pulsensor::ctx_counter) { + data_from_sensor = pulsensor->pin_ctx.read (); + pulsensor->ret = FALSE; + + pulsensor->sample_counter += 2; + int N = pulsensor->sample_counter - pulsensor->last_beat_time; + + if (data_from_sensor < pulsensor->threshold && + N > ( pulsensor->ibi / 5)* 3) { + if (data_from_sensor < pulsensor->trough) { + pulsensor->trough = data_from_sensor; } } - if (data_from_sensor > ctx->threshold && data_from_sensor > ctx->peak) { - ctx->peak = data_from_sensor; + if (data_from_sensor > pulsensor->threshold && + data_from_sensor > pulsensor->peak) { + pulsensor->peak = data_from_sensor; } if (N > 250) { // printf ("(NO_GDB) DEBUG\n"); - if ( (data_from_sensor > ctx->threshold) && - (ctx->is_pulse == FALSE) && - (N > (ctx->ibi / 5)* 3) ) { - ctx->is_pulse = callback_data.is_heart_beat = TRUE; - ((pulsensor_context *) arg)->callback(callback_data); + if ( (data_from_sensor > pulsensor->threshold) && + (pulsensor->is_pulse == FALSE) && + (N > (pulsensor->ibi / 5)* 3) ) { + pulsensor->is_pulse = callback_data.is_heart_beat = TRUE; +#if defined(JAVACALLBACK) + pulsensor->obj_callback->run(callback_data); +#else + pulsensor->callback(callback_data); +#endif - ctx->ibi = ctx->sample_counter - ctx->last_beat_time; - ctx->last_beat_time = ctx->sample_counter; + pulsensor->ibi = pulsensor->sample_counter - pulsensor->last_beat_time; + pulsensor->last_beat_time = pulsensor->sample_counter; // second beat - if (ctx->second_beat) { - ctx->second_beat = FALSE; + if (pulsensor->second_beat) { + pulsensor->second_beat = FALSE; for (int i = 0; i <= 9; i++) { - ctx->ibi_rate[i] = ctx->ibi; + pulsensor->ibi_rate[i] = pulsensor->ibi; } } // first beat - if (ctx->first_beat) { - ctx->first_beat = FALSE; - ctx->second_beat = TRUE; - ctx->ret = TRUE; + if (pulsensor->first_beat) { + pulsensor->first_beat = FALSE; + pulsensor->second_beat = TRUE; + pulsensor->ret = TRUE; } else { uint32_t running_total = 0; for(int i = 0; i <= 8; i++){ - ctx->ibi_rate[i] = ctx->ibi_rate[i+1]; - running_total += ctx->ibi_rate[i]; + pulsensor->ibi_rate[i] = pulsensor->ibi_rate[i+1]; + running_total += pulsensor->ibi_rate[i]; } - ctx->ibi_rate[9] = ctx->ibi; - running_total += ctx->ibi_rate[9]; + pulsensor->ibi_rate[9] = pulsensor->ibi; + running_total += pulsensor->ibi_rate[9]; running_total /= 10; - ctx->bpm = 60000 / running_total; - ctx->qs = TRUE; + pulsensor->bpm = 60000 / running_total; + pulsensor->qs = TRUE; } } } - if (ctx->ret == FALSE) { - if (data_from_sensor < ctx->threshold && ctx->is_pulse == TRUE) { - ctx->is_pulse = callback_data.is_heart_beat = FALSE; - ((pulsensor_context *) arg)->callback(callback_data); - - ctx->is_pulse = FALSE; - ctx->apmlitude = ctx->peak - ctx->trough; - ctx->threshold = ctx->apmlitude / 2 + ctx->trough; - ctx->peak = ctx->threshold; - ctx->trough = ctx->threshold; + if (pulsensor->ret == FALSE) { + if (data_from_sensor < pulsensor->threshold && + pulsensor->is_pulse == TRUE) { + pulsensor->is_pulse = callback_data.is_heart_beat = FALSE; +#if defined(JAVACALLBACK) + pulsensor->obj_callback->run(callback_data); +#else + pulsensor->callback(callback_data); +#endif + pulsensor->is_pulse = FALSE; + pulsensor->apmlitude = pulsensor->peak - pulsensor->trough; + pulsensor->threshold = pulsensor->apmlitude / 2 + pulsensor->trough; + pulsensor->peak = pulsensor->threshold; + pulsensor->trough = pulsensor->threshold; } if (N > 2500) { - ctx->threshold = 512; - ctx->peak = 512; - ctx->trough = 512; - ctx->last_beat_time = ctx->sample_counter; - ctx->first_beat = TRUE; - ctx->second_beat = FALSE; + pulsensor->threshold = 512; + pulsensor->peak = 512; + pulsensor->trough = 512; + pulsensor->last_beat_time = pulsensor->sample_counter; + pulsensor->first_beat = TRUE; + pulsensor->second_beat = FALSE; } } diff --git a/src/pulsensor/pulsensor.h b/src/pulsensor/pulsensor.h index c4b9dc13..3bf26df5 100644 --- a/src/pulsensor/pulsensor.h +++ b/src/pulsensor/pulsensor.h @@ -1,6 +1,7 @@ /* + * Author: Andrei Vasiliu * Author: Yevgeniy Kiveisha - * Copyright (c) 2014 Intel Corporation. + * Copyright (c) 2015 Intel Corporation. * * Credits to Adafruit. * Based on Adafruit BMP085 library. @@ -28,9 +29,9 @@ #include #include -#include -#include -#include +#include +#include +#include #include #define HIGH 1 @@ -71,13 +72,30 @@ struct clbk_data { int is_heart_beat; /**< heartbeat check */ }; + +#if defined(SWIGJAVA) || defined(JAVACALLBACK) +#include "Callback.h" +#else typedef void (* callback_handler) (clbk_data); +#endif /*! - * @struct pulsensor_context + * @class Pulsensor * @brief The context for the heartbeat pulse sensor */ -struct pulsensor_context { +class Pulsensor { + +public: +#if defined(SWIGJAVA) || defined(JAVACALLBACK) + Pulsensor(Callback *callback); +#else + Pulsensor(callback_handler handler); +#endif + void start_sampler(); + void stop_sampler(); + +private: + static void *do_sample(void *arg); pthread_t sample_thread; /**< Thread for the code sample */ uint32_t sample_counter; /**< Counter for the code sample */ uint32_t last_beat_time; /**< Last heartbeat time */ @@ -94,15 +112,12 @@ struct pulsensor_context { uint8_t second_beat; /**< Second heartbeat */ uint8_t pin; /**< Pin */ uint8_t ret; /**< Return value */ - mraa_aio_context pin_ctx; /**< The pin context */ - + mraa::Aio pin_ctx; /**< The pin context */ +#if defined(SWIGJAVA) || defined(JAVACALLBACK) + Callback *obj_callback; /**< The callback object */ +#else callback_handler callback; /**< The callback function */ +#endif + static volatile uint16_t ctx_counter; }; -static volatile uint16_t ctx_counter = 0; - -void init_pulsensor (pulsensor_context * ctx, callback_handler handler); -void start_sampler (pulsensor_context * ctx); -void stop_sampler (pulsensor_context * ctx); - -void * do_sample (void * arg);