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)
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})
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})
--- /dev/null
+/*
+ * Author: Yevgeniy Kiveisha <yevgeniy.kiveisha@intel.com>
+ * 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 <string.h>
+#include <unistd.h>
+#include "pulsensor.h"
+#include <signal.h>
+
+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;
+}
--- /dev/null
+set (libname "pulsensor")
+set (libdescription "upm PULSENSOR")
+set (module_src ${libname}.cxx)
+set (module_h ${libname}.h)
+upm_module_init()
--- /dev/null
+%module jsupm_pulsensor
+
+%{
+ #include "pulsensor.h"
+%}
+
+%include "pulsensor.h"
--- /dev/null
+/*
+ * Author: Yevgeniy Kiveisha <yevgeniy.kiveisha@intel.com>
+ * 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 <unistd.h>
+#include <stdlib.h>
+#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);
+ }
+}
--- /dev/null
+/*
+ * Author: Yevgeniy Kiveisha <yevgeniy.kiveisha@intel.com>
+ * 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 <string>
+#include <math.h>
+#include <maa/pwm.h>
+#include <maa/aio.h>
+#include <maa/gpio.h>
+#include <pthread.h>
+
+#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);
--- /dev/null
+%module pyupm_pulsensor
+
+%include "stdint.i"
+
+%feature("autodoc", "3");
+
+%include "pulsensor.h"
+%{
+ #include "pulsensor.h"
+%}