Browse Source

pulsensor: Added new sensor (not stable and not documented yet)

Signed-off-by: Kiveisha Yevgeniy <yevgeniy.kiveisha@intel.com>
Kiveisha Yevgeniy 10 years ago
parent
commit
d00500ba12

+ 3
- 0
examples/CMakeLists.txt View File

@@ -18,6 +18,7 @@ add_executable (lcd st7735.cxx)
18 18
 add_executable (max31855-example max31855.cxx)
19 19
 add_executable (gy65-example gy65.cxx)
20 20
 add_executable (stepmotor-example stepmotor.cxx)
21
+add_executable (pulsensor-example pulsensor.cxx)
21 22
 
22 23
 include_directories (${PROJECT_SOURCE_DIR}/src/hmc5883l)
23 24
 include_directories (${PROJECT_SOURCE_DIR}/src/grove)
@@ -34,6 +35,7 @@ include_directories (${PROJECT_SOURCE_DIR}/src/st7735)
34 35
 include_directories (${PROJECT_SOURCE_DIR}/src/max31855)
35 36
 include_directories (${PROJECT_SOURCE_DIR}/src/gy65)
36 37
 include_directories (${PROJECT_SOURCE_DIR}/src/stepmotor)
38
+include_directories (${PROJECT_SOURCE_DIR}/src/pulsensor)
37 39
 
38 40
 target_link_libraries (compass hmc5883l ${CMAKE_THREAD_LIBS_INIT})
39 41
 target_link_libraries (groveled grove ${CMAKE_THREAD_LIBS_INIT})
@@ -55,3 +57,4 @@ target_link_libraries (lcd st7735 ${CMAKE_THREAD_LIBS_INIT})
55 57
 target_link_libraries (max31855-example max31855 ${CMAKE_THREAD_LIBS_INIT})
56 58
 target_link_libraries (gy65-example gy65 ${CMAKE_THREAD_LIBS_INIT})
57 59
 target_link_libraries (stepmotor-example stepmotor ${CMAKE_THREAD_LIBS_INIT})
60
+target_link_libraries (pulsensor-example pulsensor ${CMAKE_THREAD_LIBS_INIT})

+ 61
- 0
examples/pulsensor.cxx View File

@@ -0,0 +1,61 @@
1
+/*
2
+ * Author: Yevgeniy Kiveisha <yevgeniy.kiveisha@intel.com>
3
+ * Copyright (c) 2014 Intel Corporation.
4
+ *
5
+ * Permission is hereby granted, free of charge, to any person obtaining
6
+ * a copy of this software and associated documentation files (the
7
+ * "Software"), to deal in the Software without restriction, including
8
+ * without limitation the rights to use, copy, modify, merge, publish,
9
+ * distribute, sublicense, and/or sell copies of the Software, and to
10
+ * permit persons to whom the Software is furnished to do so, subject to
11
+ * the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be
14
+ * included in all copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+ */
24
+
25
+#include <string.h>
26
+#include <unistd.h>
27
+#include "pulsensor.h"
28
+#include <signal.h>
29
+
30
+int doWork = 0;
31
+pulsensor_context sensor_ctx;
32
+
33
+void
34
+sig_handler(int signo)
35
+{
36
+    printf("got signal\n");
37
+    if (signo == SIGINT) {
38
+        printf("exiting application\n");
39
+        doWork = 1;
40
+    }
41
+}
42
+
43
+void
44
+handler (clbk_data data) {
45
+    printf ("callback data (%d)\n", data);
46
+}
47
+
48
+int
49
+main(int argc, char **argv)
50
+{
51
+//! [Interesting]
52
+    init_pulsensor (&sensor_ctx, handler);
53
+    
54
+    start_sampler (&sensor_ctx);
55
+    while (!doWork) {
56
+        usleep (5);
57
+    }
58
+    stop_sampler (&sensor_ctx);
59
+//! [Interesting]
60
+    return 0;
61
+}

+ 5
- 0
src/pulsensor/CMakeLists.txt View File

@@ -0,0 +1,5 @@
1
+set (libname "pulsensor")
2
+set (libdescription "upm PULSENSOR")
3
+set (module_src ${libname}.cxx)
4
+set (module_h ${libname}.h)
5
+upm_module_init()

+ 7
- 0
src/pulsensor/jsupm_pulsensor.i View File

@@ -0,0 +1,7 @@
1
+%module jsupm_pulsensor
2
+
3
+%{
4
+    #include "pulsensor.h"
5
+%}
6
+
7
+%include "pulsensor.h"

+ 147
- 0
src/pulsensor/pulsensor.cxx View File

@@ -0,0 +1,147 @@
1
+/*
2
+ * Author: Yevgeniy Kiveisha <yevgeniy.kiveisha@intel.com>
3
+ * Copyright (c) 2014 Intel Corporation.
4
+ *
5
+ * Permission is hereby granted, free of charge, to any person obtaining
6
+ * a copy of this software and associated documentation files (the
7
+ * "Software"), to deal in the Software without restriction, including
8
+ * without limitation the rights to use, copy, modify, merge, publish,
9
+ * distribute, sublicense, and/or sell copies of the Software, and to
10
+ * permit persons to whom the Software is furnished to do so, subject to
11
+ * the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be
14
+ * included in all copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+ */
24
+
25
+#include <unistd.h>
26
+#include <stdlib.h>
27
+#include "pulsensor.h"
28
+
29
+void init_pulsensor (pulsensor_context * ctx, callback_handler handler) {
30
+    ctx->callback = handler;
31
+    
32
+    ctx->pin_ctx = maa_aio_init(0);
33
+    
34
+    ctx->sample_counter = 0;
35
+    ctx->last_beat_time = 0;
36
+    ctx->threshold      = 512;
37
+    ctx->ibi            = 600;
38
+    ctx->trough         = 512;
39
+    ctx->peak           = 512;
40
+    ctx->is_pulse       = FALSE;
41
+    ctx->ret            = FALSE;
42
+    ctx->bpm            = 0;
43
+    ctx->qs             = FALSE;
44
+    ctx->apmlitude      = 100;
45
+}
46
+
47
+void start_sampler (pulsensor_context * ctx) {
48
+    int error;
49
+    ctx_counter++;
50
+    usleep (100000);
51
+    error = pthread_create (&(ctx->sample_thread), NULL, do_sample, (void *) ctx);
52
+    if (error != 0) {
53
+        printf ("ERROR : Cannot created sampler thread.\n");
54
+    }
55
+}
56
+
57
+void stop_sampler (pulsensor_context * ctx) {
58
+    ctx_counter--;
59
+}
60
+
61
+void * do_sample (void * arg) {
62
+    int data_from_sensor;
63
+    clbk_data callback_data;
64
+    while (ctx_counter) {
65
+        pulsensor_context * ctx = (pulsensor_context *) arg;
66
+        maa_aio_context pin = ctx->pin_ctx;
67
+        data_from_sensor = maa_aio_read (pin);
68
+        ctx->ret = FALSE;
69
+        
70
+        ctx->sample_counter += 2;
71
+        int N = ctx->sample_counter - ctx->last_beat_time;
72
+        
73
+        if (data_from_sensor < ctx->threshold && N > ( ctx->ibi / 5)* 3) {
74
+            if (data_from_sensor < ctx->trough) {
75
+                ctx->trough = data_from_sensor;
76
+            }
77
+        }
78
+        
79
+        if (data_from_sensor > ctx->threshold && data_from_sensor > ctx->peak) {
80
+            ctx->peak = data_from_sensor;
81
+        }
82
+        
83
+        if (N > 250) {
84
+            // printf ("(NO_GDB) DEBUG\n");
85
+            if ( (data_from_sensor > ctx->threshold) && 
86
+                    (ctx->is_pulse == FALSE) && 
87
+                    (N > (ctx->ibi / 5)* 3) ) {
88
+                ctx->is_pulse = callback_data.is_heart_beat = TRUE;
89
+                ((pulsensor_context *) arg)->callback(callback_data);
90
+                
91
+                ctx->ibi = ctx->sample_counter - ctx->last_beat_time;
92
+                ctx->last_beat_time = ctx->sample_counter;
93
+                
94
+                // second beat
95
+                if (ctx->second_beat) {
96
+                    ctx->second_beat = FALSE;
97
+                    for (int i = 0; i <= 9; i++) {
98
+                        ctx->ibi_rate[i] = ctx->ibi;                      
99
+                    }
100
+                }
101
+                
102
+                // first beat
103
+                if (ctx->first_beat) {
104
+                    ctx->first_beat  = FALSE;
105
+                    ctx->second_beat = TRUE;
106
+                    ctx->ret = TRUE;
107
+                } else {                    
108
+                    uint32_t running_total = 0;
109
+                    for(int i = 0; i <= 8; i++){
110
+                        ctx->ibi_rate[i] = ctx->ibi_rate[i+1];
111
+                        running_total += ctx->ibi_rate[i];
112
+                    }
113
+                    
114
+                    ctx->ibi_rate[9] = ctx->ibi;
115
+                    running_total += ctx->ibi_rate[9];
116
+                    running_total /= 10;
117
+                    ctx->bpm = 60000 / running_total;
118
+                    ctx->qs = TRUE;
119
+                }
120
+            }
121
+        }
122
+        
123
+        if (ctx->ret == FALSE) {
124
+            if (data_from_sensor < ctx->threshold && ctx->is_pulse == TRUE) {
125
+                ctx->is_pulse = callback_data.is_heart_beat = FALSE;
126
+                ((pulsensor_context *) arg)->callback(callback_data);
127
+                
128
+                ctx->is_pulse   = FALSE;
129
+                ctx->apmlitude  = ctx->peak - ctx->trough;
130
+                ctx->threshold  = ctx->apmlitude / 2 + ctx->trough;
131
+                ctx->peak       = ctx->threshold;
132
+                ctx->trough     = ctx->threshold;
133
+            }
134
+
135
+            if (N > 2500) {
136
+                ctx->threshold      = 512;
137
+                ctx->peak           = 512;
138
+                ctx->trough         = 512;
139
+                ctx->last_beat_time = ctx->sample_counter;    
140
+                ctx->first_beat     = TRUE;
141
+                ctx->second_beat    = FALSE;
142
+            }
143
+        }
144
+        
145
+        usleep (2000);
146
+    }
147
+}

+ 76
- 0
src/pulsensor/pulsensor.h View File

@@ -0,0 +1,76 @@
1
+/*
2
+ * Author: Yevgeniy Kiveisha <yevgeniy.kiveisha@intel.com>
3
+ * Copyright (c) 2014 Intel Corporation.
4
+ *
5
+ * Credits to Adafruit.
6
+ * Based on Adafruit BMP085 library.
7
+ *
8
+ * Permission is hereby granted, free of charge, to any person obtaining
9
+ * a copy of this software and associated documentation files (the
10
+ * "Software"), to deal in the Software without restriction, including
11
+ * without limitation the rights to use, copy, modify, merge, publish,
12
+ * distribute, sublicense, and/or sell copies of the Software, and to
13
+ * permit persons to whom the Software is furnished to do so, subject to
14
+ * the following conditions:
15
+ *
16
+ * The above copyright notice and this permission notice shall be
17
+ * included in all copies or substantial portions of the Software.
18
+ *
19
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
23
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
24
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
25
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26
+ */
27
+#pragma once
28
+
29
+#include <string>
30
+#include <math.h>
31
+#include <maa/pwm.h>
32
+#include <maa/aio.h>
33
+#include <maa/gpio.h>
34
+#include <pthread.h>
35
+
36
+#define HIGH               1
37
+#define LOW                0
38
+
39
+#define TRUE               HIGH
40
+#define FALSE              LOW
41
+
42
+struct clbk_data {
43
+    int is_heart_beat;
44
+};
45
+
46
+typedef void (* callback_handler) (clbk_data);
47
+
48
+struct pulsensor_context {
49
+    pthread_t        sample_thread;
50
+    uint32_t         sample_counter;
51
+    uint32_t         last_beat_time;
52
+    int              threshold;
53
+    int              ibi_rate[10];
54
+    int              ibi;
55
+    int              trough;
56
+    int              peak;
57
+    int              bpm;
58
+    int              apmlitude;
59
+    uint8_t          qs;
60
+    uint8_t          is_pulse;
61
+    uint8_t          first_beat;
62
+    uint8_t          second_beat;
63
+    uint8_t          pin;
64
+    uint8_t          ret;
65
+    maa_aio_context  pin_ctx;
66
+    
67
+    callback_handler callback;
68
+};
69
+
70
+static volatile uint16_t ctx_counter = 0;
71
+
72
+void init_pulsensor (pulsensor_context * ctx, callback_handler handler);
73
+void start_sampler (pulsensor_context * ctx);
74
+void stop_sampler (pulsensor_context * ctx);
75
+
76
+void * do_sample (void * arg);

+ 10
- 0
src/pulsensor/pyupm_pulsensor.i View File

@@ -0,0 +1,10 @@
1
+%module pyupm_pulsensor
2
+
3
+%include "stdint.i"
4
+
5
+%feature("autodoc", "3");
6
+
7
+%include "pulsensor.h"
8
+%{
9
+    #include "pulsensor.h"
10
+%}