java/pulsensor: Changed to C++ types and added callback functionality for Java

Signed-off-by: Andrei Vasiliu <andrei.vasiliu@intel.com>
Signed-off-by: Mihai Tudor Panu <mihai.tudor.panu@intel.com>
This commit is contained in:
Andrei Vasiliu 2015-09-16 18:09:05 +03:00 committed by Mihai Tudor Panu
parent 6719168a20
commit 701a25261f
4 changed files with 149 additions and 88 deletions

15
src/pulsensor/Callback.h Normal file
View File

@ -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

View File

@ -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"
%}

View File

@ -1,6 +1,7 @@
/*
* Author: Andrei Vasiliu <andrei.vasiliu@intel.com>
* Author: Yevgeniy Kiveisha <yevgeniy.kiveisha@intel.com>
* 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 <stdexcept>
#include <unistd.h>
#include <stdlib.h>
#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<Pulsensor *>(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;
}
}

View File

@ -1,6 +1,7 @@
/*
* Author: Andrei Vasiliu <andrei.vasiliu@intel.com>
* Author: Yevgeniy Kiveisha <yevgeniy.kiveisha@intel.com>
* Copyright (c) 2014 Intel Corporation.
* Copyright (c) 2015 Intel Corporation.
*
* Credits to Adafruit.
* Based on Adafruit BMP085 library.
@ -28,9 +29,9 @@
#include <string>
#include <math.h>
#include <mraa/pwm.h>
#include <mraa/aio.h>
#include <mraa/gpio.h>
#include <mraa/pwm.hpp>
#include <mraa/aio.hpp>
#include <mraa/gpio.hpp>
#include <pthread.h>
#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);