From d00500ba12e2ea5c8ded59015c860c03ea6b535c Mon Sep 17 00:00:00 2001 From: Kiveisha Yevgeniy Date: Wed, 18 Jun 2014 09:37:50 +0000 Subject: [PATCH] pulsensor: Added new sensor (not stable and not documented yet) Signed-off-by: Kiveisha Yevgeniy --- examples/CMakeLists.txt | 3 + examples/pulsensor.cxx | 61 +++++++++++++++++ src/pulsensor/CMakeLists.txt | 5 ++ src/pulsensor/jsupm_pulsensor.i | 7 ++ src/pulsensor/pulsensor.cxx | 147 ++++++++++++++++++++++++++++++++++++++++ src/pulsensor/pulsensor.h | 76 +++++++++++++++++++++ src/pulsensor/pyupm_pulsensor.i | 10 +++ 7 files changed, 309 insertions(+) create mode 100644 examples/pulsensor.cxx create mode 100644 src/pulsensor/CMakeLists.txt create mode 100644 src/pulsensor/jsupm_pulsensor.i create mode 100644 src/pulsensor/pulsensor.cxx create mode 100644 src/pulsensor/pulsensor.h create mode 100644 src/pulsensor/pyupm_pulsensor.i diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 0fcd077..edf92ac 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -18,6 +18,7 @@ add_executable (lcd st7735.cxx) add_executable (max31855-example max31855.cxx) add_executable (gy65-example gy65.cxx) add_executable (stepmotor-example stepmotor.cxx) +add_executable (pulsensor-example pulsensor.cxx) include_directories (${PROJECT_SOURCE_DIR}/src/hmc5883l) include_directories (${PROJECT_SOURCE_DIR}/src/grove) @@ -34,6 +35,7 @@ include_directories (${PROJECT_SOURCE_DIR}/src/st7735) include_directories (${PROJECT_SOURCE_DIR}/src/max31855) include_directories (${PROJECT_SOURCE_DIR}/src/gy65) include_directories (${PROJECT_SOURCE_DIR}/src/stepmotor) +include_directories (${PROJECT_SOURCE_DIR}/src/pulsensor) target_link_libraries (compass hmc5883l ${CMAKE_THREAD_LIBS_INIT}) target_link_libraries (groveled grove ${CMAKE_THREAD_LIBS_INIT}) @@ -55,3 +57,4 @@ target_link_libraries (lcd st7735 ${CMAKE_THREAD_LIBS_INIT}) target_link_libraries (max31855-example max31855 ${CMAKE_THREAD_LIBS_INIT}) target_link_libraries (gy65-example gy65 ${CMAKE_THREAD_LIBS_INIT}) target_link_libraries (stepmotor-example stepmotor ${CMAKE_THREAD_LIBS_INIT}) +target_link_libraries (pulsensor-example pulsensor ${CMAKE_THREAD_LIBS_INIT}) diff --git a/examples/pulsensor.cxx b/examples/pulsensor.cxx new file mode 100644 index 0000000..196d704 --- /dev/null +++ b/examples/pulsensor.cxx @@ -0,0 +1,61 @@ +/* + * Author: Yevgeniy Kiveisha + * Copyright (c) 2014 Intel Corporation. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include "pulsensor.h" +#include + +int doWork = 0; +pulsensor_context sensor_ctx; + +void +sig_handler(int signo) +{ + printf("got signal\n"); + if (signo == SIGINT) { + printf("exiting application\n"); + doWork = 1; + } +} + +void +handler (clbk_data data) { + printf ("callback data (%d)\n", data); +} + +int +main(int argc, char **argv) +{ +//! [Interesting] + init_pulsensor (&sensor_ctx, handler); + + start_sampler (&sensor_ctx); + while (!doWork) { + usleep (5); + } + stop_sampler (&sensor_ctx); +//! [Interesting] + return 0; +} diff --git a/src/pulsensor/CMakeLists.txt b/src/pulsensor/CMakeLists.txt new file mode 100644 index 0000000..223c642 --- /dev/null +++ b/src/pulsensor/CMakeLists.txt @@ -0,0 +1,5 @@ +set (libname "pulsensor") +set (libdescription "upm PULSENSOR") +set (module_src ${libname}.cxx) +set (module_h ${libname}.h) +upm_module_init() diff --git a/src/pulsensor/jsupm_pulsensor.i b/src/pulsensor/jsupm_pulsensor.i new file mode 100644 index 0000000..ff6d49d --- /dev/null +++ b/src/pulsensor/jsupm_pulsensor.i @@ -0,0 +1,7 @@ +%module jsupm_pulsensor + +%{ + #include "pulsensor.h" +%} + +%include "pulsensor.h" diff --git a/src/pulsensor/pulsensor.cxx b/src/pulsensor/pulsensor.cxx new file mode 100644 index 0000000..ae19b3b --- /dev/null +++ b/src/pulsensor/pulsensor.cxx @@ -0,0 +1,147 @@ +/* + * Author: Yevgeniy Kiveisha + * Copyright (c) 2014 Intel Corporation. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include "pulsensor.h" + +void init_pulsensor (pulsensor_context * ctx, callback_handler handler) { + ctx->callback = handler; + + ctx->pin_ctx = maa_aio_init(0); + + 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; +} + +void start_sampler (pulsensor_context * ctx) { + int error; + ctx_counter++; + usleep (100000); + error = pthread_create (&(ctx->sample_thread), NULL, do_sample, (void *) ctx); + if (error != 0) { + printf ("ERROR : Cannot created sampler thread.\n"); + } +} + +void stop_sampler (pulsensor_context * ctx) { + ctx_counter--; +} + +void * do_sample (void * arg) { + int data_from_sensor; + clbk_data callback_data; + while (ctx_counter) { + pulsensor_context * ctx = (pulsensor_context *) arg; + maa_aio_context pin = ctx->pin_ctx; + data_from_sensor = maa_aio_read (pin); + ctx->ret = FALSE; + + ctx->sample_counter += 2; + int N = ctx->sample_counter - ctx->last_beat_time; + + if (data_from_sensor < ctx->threshold && N > ( ctx->ibi / 5)* 3) { + if (data_from_sensor < ctx->trough) { + ctx->trough = data_from_sensor; + } + } + + if (data_from_sensor > ctx->threshold && data_from_sensor > ctx->peak) { + ctx->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); + + ctx->ibi = ctx->sample_counter - ctx->last_beat_time; + ctx->last_beat_time = ctx->sample_counter; + + // second beat + if (ctx->second_beat) { + ctx->second_beat = FALSE; + for (int i = 0; i <= 9; i++) { + ctx->ibi_rate[i] = ctx->ibi; + } + } + + // first beat + if (ctx->first_beat) { + ctx->first_beat = FALSE; + ctx->second_beat = TRUE; + ctx->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]; + } + + ctx->ibi_rate[9] = ctx->ibi; + running_total += ctx->ibi_rate[9]; + running_total /= 10; + ctx->bpm = 60000 / running_total; + ctx->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 (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; + } + } + + usleep (2000); + } +} diff --git a/src/pulsensor/pulsensor.h b/src/pulsensor/pulsensor.h new file mode 100644 index 0000000..ae54832 --- /dev/null +++ b/src/pulsensor/pulsensor.h @@ -0,0 +1,76 @@ +/* + * Author: Yevgeniy Kiveisha + * Copyright (c) 2014 Intel Corporation. + * + * Credits to Adafruit. + * Based on Adafruit BMP085 library. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#pragma once + +#include +#include +#include +#include +#include +#include + +#define HIGH 1 +#define LOW 0 + +#define TRUE HIGH +#define FALSE LOW + +struct clbk_data { + int is_heart_beat; +}; + +typedef void (* callback_handler) (clbk_data); + +struct pulsensor_context { + pthread_t sample_thread; + uint32_t sample_counter; + uint32_t last_beat_time; + int threshold; + int ibi_rate[10]; + int ibi; + int trough; + int peak; + int bpm; + int apmlitude; + uint8_t qs; + uint8_t is_pulse; + uint8_t first_beat; + uint8_t second_beat; + uint8_t pin; + uint8_t ret; + maa_aio_context pin_ctx; + + callback_handler callback; +}; + +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); diff --git a/src/pulsensor/pyupm_pulsensor.i b/src/pulsensor/pyupm_pulsensor.i new file mode 100644 index 0000000..cece2b0 --- /dev/null +++ b/src/pulsensor/pyupm_pulsensor.i @@ -0,0 +1,10 @@ +%module pyupm_pulsensor + +%include "stdint.i" + +%feature("autodoc", "3"); + +%include "pulsensor.h" +%{ + #include "pulsensor.h" +%} -- 2.7.4