
comm with heart
Dependencies: TextLCD mbed-rtos mbed
Fork of pacemaker_v3 by
main.cpp@2:1e42b5fdf9e9, 2014-12-03 (annotated)
- Committer:
- jfields
- Date:
- Wed Dec 03 02:32:50 2014 +0000
- Revision:
- 2:1e42b5fdf9e9
- Parent:
- 1:9d463bc2b7b9
code for dual mbed mode
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
jfields | 0:cd6f505d57da | 1 | #include "mbed.h" |
jfields | 0:cd6f505d57da | 2 | #include "rtos.h" |
jfields | 0:cd6f505d57da | 3 | #include "TextLCD.h" |
jfields | 0:cd6f505d57da | 4 | #include <stdio.h> |
jfields | 0:cd6f505d57da | 5 | #include <stdlib.h> |
jfields | 0:cd6f505d57da | 6 | |
jfields | 0:cd6f505d57da | 7 | #define RUN 0x1 |
jfields | 0:cd6f505d57da | 8 | |
jfields | 0:cd6f505d57da | 9 | TextLCD lcd(p15, p16, p17, p18, p19, p20, TextLCD::LCD16x2); |
jfields | 0:cd6f505d57da | 10 | Serial pc (USBTX, USBRX); |
jfields | 0:cd6f505d57da | 11 | |
jfields | 2:1e42b5fdf9e9 | 12 | // ports |
jfields | 2:1e42b5fdf9e9 | 13 | DigitalIn VGet(p11); |
jfields | 2:1e42b5fdf9e9 | 14 | DigitalIn AGet(p12); |
jfields | 2:1e42b5fdf9e9 | 15 | DigitalOut VPace(p13); |
jfields | 2:1e42b5fdf9e9 | 16 | DigitalOut APace(p14); |
jfields | 2:1e42b5fdf9e9 | 17 | |
jfields | 0:cd6f505d57da | 18 | // LEDs |
jfields | 0:cd6f505d57da | 19 | DigitalOut leds[] = {LED1, LED2, LED3, LED4}; // 1 = VP, 2 = AP, 3 = AS, 4 = VS |
jfields | 0:cd6f505d57da | 20 | |
jfields | 0:cd6f505d57da | 21 | // create log file and debugging vars |
jfields | 0:cd6f505d57da | 22 | //LocalFileSystem local("local"); |
jfields | 0:cd6f505d57da | 23 | //FILE *fp = fopen("/local/out.txt", "w"); |
jfields | 0:cd6f505d57da | 24 | int between_a = 0; |
jfields | 0:cd6f505d57da | 25 | int between_v = 0; |
jfields | 0:cd6f505d57da | 26 | |
jfields | 0:cd6f505d57da | 27 | // Heart Signals |
jfields | 0:cd6f505d57da | 28 | int AG = 0; |
jfields | 0:cd6f505d57da | 29 | int VG = 0; |
jfields | 0:cd6f505d57da | 30 | |
jfields | 2:1e42b5fdf9e9 | 31 | // heart rate global vars |
jfields | 2:1e42b5fdf9e9 | 32 | int HR = 0; |
jfields | 2:1e42b5fdf9e9 | 33 | int beats = 0; |
jfields | 2:1e42b5fdf9e9 | 34 | int sampleRate = 10000; // default 10 seconds |
jfields | 2:1e42b5fdf9e9 | 35 | int firstSample = 1; |
jfields | 2:1e42b5fdf9e9 | 36 | |
jfields | 0:cd6f505d57da | 37 | // Normal Values |
jfields | 0:cd6f505d57da | 38 | const int N_PVARP = 325; // ms |
jfields | 0:cd6f505d57da | 39 | const int N_VRP = 300; // ms |
jfields | 0:cd6f505d57da | 40 | const int N_LRI = 857; // ms (= about 70ppm) |
jfields | 0:cd6f505d57da | 41 | const int N_AVI = 65; // ms |
jfields | 0:cd6f505d57da | 42 | const int N_UB = 100; // 100ppm |
jfields | 0:cd6f505d57da | 43 | const int N_LB = 40; // 40ppm |
jfields | 0:cd6f505d57da | 44 | |
jfields | 0:cd6f505d57da | 45 | // Heart Values - Normal Mode is default |
jfields | 0:cd6f505d57da | 46 | int PVARP = N_PVARP; |
jfields | 0:cd6f505d57da | 47 | int VRP = N_VRP; |
jfields | 0:cd6f505d57da | 48 | int LRI = N_LRI; |
jfields | 0:cd6f505d57da | 49 | int default_LRI = N_LRI; |
jfields | 0:cd6f505d57da | 50 | int AVI = N_AVI; |
jfields | 0:cd6f505d57da | 51 | int UB = N_UB; |
jfields | 0:cd6f505d57da | 52 | int LB = N_LB; |
jfields | 0:cd6f505d57da | 53 | |
jfields | 0:cd6f505d57da | 54 | // time vars |
jfields | 0:cd6f505d57da | 55 | Timer global_t; |
jfields | 0:cd6f505d57da | 56 | int isVRP = 0; |
jfields | 0:cd6f505d57da | 57 | int isPVARP = 0; |
jfields | 0:cd6f505d57da | 58 | int waitingForV = 1; |
jfields | 0:cd6f505d57da | 59 | |
jfields | 0:cd6f505d57da | 60 | // functions |
jfields | 0:cd6f505d57da | 61 | void VP_func(void const *args); |
jfields | 0:cd6f505d57da | 62 | void AP_func(void const *args); |
jfields | 0:cd6f505d57da | 63 | void VS_func(void const *args); |
jfields | 0:cd6f505d57da | 64 | void AS_func(void const *args); |
jfields | 0:cd6f505d57da | 65 | void PM_monitor_func(void const *args); |
jfields | 0:cd6f505d57da | 66 | void manage_signals(void const *i); |
jfields | 0:cd6f505d57da | 67 | void flashLED(int i); |
jfields | 0:cd6f505d57da | 68 | void event_out(char *s, int between_t); |
jfields | 0:cd6f505d57da | 69 | void blind(); |
jfields | 2:1e42b5fdf9e9 | 70 | //void rand_heart_func(void const *args); |
jfields | 2:1e42b5fdf9e9 | 71 | void calcHR(void const *args); |
jfields | 2:1e42b5fdf9e9 | 72 | void disp(void const *args); |
jfields | 2:1e42b5fdf9e9 | 73 | void send_Apace(); |
jfields | 2:1e42b5fdf9e9 | 74 | void send_Vpace(); |
jfields | 0:cd6f505d57da | 75 | |
jfields | 0:cd6f505d57da | 76 | // threads |
jfields | 0:cd6f505d57da | 77 | Thread * VS_thread; |
jfields | 0:cd6f505d57da | 78 | Thread * AS_thread; |
jfields | 1:9d463bc2b7b9 | 79 | Thread * PM_monitor_thread; |
jfields | 2:1e42b5fdf9e9 | 80 | Thread * disp_thread; |
jfields | 2:1e42b5fdf9e9 | 81 | //Thread * rand_heart_thread; // just for testing until mbed connection is made |
jfields | 0:cd6f505d57da | 82 | |
jfields | 0:cd6f505d57da | 83 | // rtos timers |
jfields | 0:cd6f505d57da | 84 | RtosTimer * VP_timer; |
jfields | 0:cd6f505d57da | 85 | RtosTimer * AP_timer; |
jfields | 0:cd6f505d57da | 86 | RtosTimer * VRP_timer; |
jfields | 0:cd6f505d57da | 87 | RtosTimer * PVARP_timer; |
jfields | 2:1e42b5fdf9e9 | 88 | RtosTimer * HR_timer; |
jfields | 0:cd6f505d57da | 89 | //RtosTimer * exit_timer; // for log file |
jfields | 0:cd6f505d57da | 90 | |
jfields | 0:cd6f505d57da | 91 | int main() { |
jfields | 0:cd6f505d57da | 92 | |
jfields | 0:cd6f505d57da | 93 | // start global timer |
jfields | 0:cd6f505d57da | 94 | global_t.start(); |
jfields | 0:cd6f505d57da | 95 | |
jfields | 0:cd6f505d57da | 96 | // init threads |
jfields | 0:cd6f505d57da | 97 | VS_thread = new Thread(VS_func); |
jfields | 0:cd6f505d57da | 98 | AS_thread = new Thread(AS_func); |
jfields | 2:1e42b5fdf9e9 | 99 | disp_thread = new Thread(disp); |
jfields | 1:9d463bc2b7b9 | 100 | PM_monitor_thread = new Thread(PM_monitor_func); |
jfields | 2:1e42b5fdf9e9 | 101 | //rand_heart_thread = new Thread(rand_heart_func); // just for testing until mbed connection is made |
jfields | 0:cd6f505d57da | 102 | |
jfields | 0:cd6f505d57da | 103 | // init timers |
jfields | 0:cd6f505d57da | 104 | VP_timer = new RtosTimer(VP_func, osTimerOnce, (void *)0); |
jfields | 0:cd6f505d57da | 105 | AP_timer = new RtosTimer(AP_func, osTimerOnce, (void *)0); |
jfields | 2:1e42b5fdf9e9 | 106 | HR_timer = new RtosTimer(calcHR, osTimerPeriodic, (void *)0); |
jfields | 0:cd6f505d57da | 107 | VRP_timer = new RtosTimer(manage_signals, osTimerOnce, (void *)1); |
jfields | 0:cd6f505d57da | 108 | PVARP_timer = new RtosTimer(manage_signals, osTimerOnce, (void *)2); |
jfields | 0:cd6f505d57da | 109 | //exit_timer = new RtosTimer(manage_signals, osTimerOnce, (void *)99); |
jfields | 0:cd6f505d57da | 110 | |
jfields | 2:1e42b5fdf9e9 | 111 | // init VP thread, HR timer, display timer |
jfields | 0:cd6f505d57da | 112 | VP_timer->start(AVI); |
jfields | 2:1e42b5fdf9e9 | 113 | HR_timer->start(sampleRate); |
jfields | 2:1e42b5fdf9e9 | 114 | disp_thread->signal_set(RUN); |
jfields | 0:cd6f505d57da | 115 | //exit_timer->start(60000); |
jfields | 0:cd6f505d57da | 116 | |
jfields | 0:cd6f505d57da | 117 | // main thread |
jfields | 0:cd6f505d57da | 118 | while (1) { |
jfields | 0:cd6f505d57da | 119 | |
jfields | 0:cd6f505d57da | 120 | } |
jfields | 0:cd6f505d57da | 121 | } |
jfields | 0:cd6f505d57da | 122 | |
jfields | 2:1e42b5fdf9e9 | 123 | void calcHR(void const *args) { |
jfields | 2:1e42b5fdf9e9 | 124 | |
jfields | 2:1e42b5fdf9e9 | 125 | // calc |
jfields | 2:1e42b5fdf9e9 | 126 | if (firstSample == 1) { |
jfields | 2:1e42b5fdf9e9 | 127 | HR = beats*(60000/sampleRate); |
jfields | 2:1e42b5fdf9e9 | 128 | firstSample = 0; |
jfields | 2:1e42b5fdf9e9 | 129 | } |
jfields | 2:1e42b5fdf9e9 | 130 | else { |
jfields | 2:1e42b5fdf9e9 | 131 | HR = (beats*60000/sampleRate+HR)/2; |
jfields | 2:1e42b5fdf9e9 | 132 | } |
jfields | 2:1e42b5fdf9e9 | 133 | |
jfields | 2:1e42b5fdf9e9 | 134 | // display |
jfields | 2:1e42b5fdf9e9 | 135 | disp_thread->signal_set(RUN); |
jfields | 2:1e42b5fdf9e9 | 136 | } |
jfields | 2:1e42b5fdf9e9 | 137 | |
jfields | 0:cd6f505d57da | 138 | void manage_signals(void const *i) { |
jfields | 0:cd6f505d57da | 139 | if ((int)i==1) isVRP = 0; |
jfields | 0:cd6f505d57da | 140 | if ((int)i==2) isPVARP = 0; |
jfields | 0:cd6f505d57da | 141 | |
jfields | 0:cd6f505d57da | 142 | // for debuggging |
jfields | 0:cd6f505d57da | 143 | //if ((int)i==99) { |
jfields | 0:cd6f505d57da | 144 | //fclose(fp); |
jfields | 0:cd6f505d57da | 145 | //exit(1); |
jfields | 0:cd6f505d57da | 146 | //} |
jfields | 0:cd6f505d57da | 147 | } |
jfields | 0:cd6f505d57da | 148 | |
jfields | 0:cd6f505d57da | 149 | void AP_func(void const *args) { |
jfields | 0:cd6f505d57da | 150 | |
jfields | 0:cd6f505d57da | 151 | // start VP timer |
jfields | 0:cd6f505d57da | 152 | VP_timer->start(AVI); |
jfields | 0:cd6f505d57da | 153 | |
jfields | 2:1e42b5fdf9e9 | 154 | // send Apace |
jfields | 2:1e42b5fdf9e9 | 155 | send_Apace(); |
jfields | 2:1e42b5fdf9e9 | 156 | |
jfields | 0:cd6f505d57da | 157 | // update state |
jfields | 0:cd6f505d57da | 158 | waitingForV = 1; |
jfields | 0:cd6f505d57da | 159 | |
jfields | 0:cd6f505d57da | 160 | // output |
jfields | 0:cd6f505d57da | 161 | event_out("AP",between_a); |
jfields | 0:cd6f505d57da | 162 | between_a = global_t.read_ms(); |
jfields | 0:cd6f505d57da | 163 | |
jfields | 0:cd6f505d57da | 164 | // flash LED |
jfields | 0:cd6f505d57da | 165 | flashLED(2); |
jfields | 0:cd6f505d57da | 166 | } |
jfields | 0:cd6f505d57da | 167 | |
jfields | 0:cd6f505d57da | 168 | void VP_func(void const *args) { |
jfields | 0:cd6f505d57da | 169 | |
jfields | 0:cd6f505d57da | 170 | // start AP timer |
jfields | 0:cd6f505d57da | 171 | AP_timer->start(LRI-AVI); |
jfields | 0:cd6f505d57da | 172 | |
jfields | 2:1e42b5fdf9e9 | 173 | // send Vpace |
jfields | 2:1e42b5fdf9e9 | 174 | send_Vpace(); |
jfields | 2:1e42b5fdf9e9 | 175 | |
jfields | 0:cd6f505d57da | 176 | // update state |
jfields | 0:cd6f505d57da | 177 | waitingForV = 0; |
jfields | 0:cd6f505d57da | 178 | |
jfields | 2:1e42b5fdf9e9 | 179 | // set VRP, PVARP, update beats |
jfields | 0:cd6f505d57da | 180 | blind(); |
jfields | 0:cd6f505d57da | 181 | |
jfields | 0:cd6f505d57da | 182 | // output |
jfields | 0:cd6f505d57da | 183 | event_out("VP", between_v); |
jfields | 0:cd6f505d57da | 184 | between_v = global_t.read_ms(); |
jfields | 0:cd6f505d57da | 185 | |
jfields | 0:cd6f505d57da | 186 | // flash LED |
jfields | 0:cd6f505d57da | 187 | flashLED(1); |
jfields | 0:cd6f505d57da | 188 | } |
jfields | 0:cd6f505d57da | 189 | |
jfields | 0:cd6f505d57da | 190 | void AS_func(void const *args) { |
jfields | 0:cd6f505d57da | 191 | while (1) { |
jfields | 0:cd6f505d57da | 192 | |
jfields | 0:cd6f505d57da | 193 | // wait for event |
jfields | 0:cd6f505d57da | 194 | Thread::signal_wait(RUN,osWaitForever); |
jfields | 0:cd6f505d57da | 195 | |
jfields | 0:cd6f505d57da | 196 | // update state |
jfields | 0:cd6f505d57da | 197 | waitingForV = 1; |
jfields | 0:cd6f505d57da | 198 | |
jfields | 0:cd6f505d57da | 199 | // stop AP timer and start VP timer |
jfields | 0:cd6f505d57da | 200 | AP_timer->stop(); |
jfields | 0:cd6f505d57da | 201 | VP_timer->start(AVI); |
jfields | 0:cd6f505d57da | 202 | |
jfields | 0:cd6f505d57da | 203 | // output |
jfields | 0:cd6f505d57da | 204 | event_out("AS", between_a); |
jfields | 0:cd6f505d57da | 205 | between_a = global_t.read_ms(); |
jfields | 0:cd6f505d57da | 206 | |
jfields | 0:cd6f505d57da | 207 | // flash LED |
jfields | 0:cd6f505d57da | 208 | flashLED(3); |
jfields | 0:cd6f505d57da | 209 | } |
jfields | 0:cd6f505d57da | 210 | } |
jfields | 0:cd6f505d57da | 211 | |
jfields | 0:cd6f505d57da | 212 | void VS_func(void const *args) { |
jfields | 0:cd6f505d57da | 213 | while (1) { |
jfields | 0:cd6f505d57da | 214 | |
jfields | 0:cd6f505d57da | 215 | // wait for event |
jfields | 0:cd6f505d57da | 216 | Thread::signal_wait(RUN,osWaitForever); |
jfields | 0:cd6f505d57da | 217 | |
jfields | 0:cd6f505d57da | 218 | // update state |
jfields | 0:cd6f505d57da | 219 | waitingForV = 0; |
jfields | 0:cd6f505d57da | 220 | |
jfields | 0:cd6f505d57da | 221 | // stop VP timer and start AP timer |
jfields | 0:cd6f505d57da | 222 | VP_timer->stop(); |
jfields | 0:cd6f505d57da | 223 | AP_timer->start(LRI-AVI); |
jfields | 0:cd6f505d57da | 224 | |
jfields | 0:cd6f505d57da | 225 | // set VRP, PVARP |
jfields | 0:cd6f505d57da | 226 | blind(); |
jfields | 0:cd6f505d57da | 227 | |
jfields | 0:cd6f505d57da | 228 | // output |
jfields | 0:cd6f505d57da | 229 | event_out("VS", between_v); |
jfields | 0:cd6f505d57da | 230 | between_v = global_t.read_ms(); |
jfields | 0:cd6f505d57da | 231 | |
jfields | 0:cd6f505d57da | 232 | // flash LED |
jfields | 0:cd6f505d57da | 233 | flashLED(4); |
jfields | 0:cd6f505d57da | 234 | } |
jfields | 0:cd6f505d57da | 235 | } |
jfields | 0:cd6f505d57da | 236 | |
jfields | 2:1e42b5fdf9e9 | 237 | /* |
jfields | 0:cd6f505d57da | 238 | void rand_heart_func(void const *args) { |
jfields | 2:1e42b5fdf9e9 | 239 | int interval; |
jfields | 2:1e42b5fdf9e9 | 240 | srand(time(NULL)); |
jfields | 2:1e42b5fdf9e9 | 241 | while (1) { |
jfields | 2:1e42b5fdf9e9 | 242 | interval = rand()%5000+10; |
jfields | 2:1e42b5fdf9e9 | 243 | //fprintf(fp,"interval = %d\n",interval); |
jfields | 2:1e42b5fdf9e9 | 244 | Thread::wait(interval); |
jfields | 2:1e42b5fdf9e9 | 245 | if (interval%2) AG = 1; |
jfields | 2:1e42b5fdf9e9 | 246 | else |
jfields | 2:1e42b5fdf9e9 | 247 | VG = 1; |
jfields | 0:cd6f505d57da | 248 | } |
jfields | 2:1e42b5fdf9e9 | 249 | } |
jfields | 2:1e42b5fdf9e9 | 250 | */ |
jfields | 0:cd6f505d57da | 251 | |
jfields | 0:cd6f505d57da | 252 | void PM_monitor_func(void const *args) { |
jfields | 0:cd6f505d57da | 253 | while (1) { |
jfields | 2:1e42b5fdf9e9 | 254 | if (AGet == 1) { |
jfields | 0:cd6f505d57da | 255 | //fprintf(fp,"%f\tAget\t%d\n",global_t.read_ms(),isPVARP); |
jfields | 2:1e42b5fdf9e9 | 256 | //AG = 0; |
jfields | 0:cd6f505d57da | 257 | if (!isPVARP && !waitingForV) AS_thread->signal_set(RUN); |
jfields | 2:1e42b5fdf9e9 | 258 | wait(0.1); |
jfields | 2:1e42b5fdf9e9 | 259 | while(AGet == 1); |
jfields | 0:cd6f505d57da | 260 | } |
jfields | 2:1e42b5fdf9e9 | 261 | if (VGet == 1) { |
jfields | 0:cd6f505d57da | 262 | //fprintf(fp,"%f\tVget\t%d\n",global_t.read_ms(),isVRP); |
jfields | 2:1e42b5fdf9e9 | 263 | //VG = 0; |
jfields | 0:cd6f505d57da | 264 | if (!isVRP && waitingForV) VS_thread->signal_set(RUN); |
jfields | 2:1e42b5fdf9e9 | 265 | wait(0.1); |
jfields | 2:1e42b5fdf9e9 | 266 | while(VGet == 1); |
jfields | 0:cd6f505d57da | 267 | } |
jfields | 0:cd6f505d57da | 268 | } |
jfields | 0:cd6f505d57da | 269 | } |
jfields | 0:cd6f505d57da | 270 | |
jfields | 0:cd6f505d57da | 271 | void flashLED(int i) { |
jfields | 0:cd6f505d57da | 272 | leds[i-1] = 1; |
jfields | 0:cd6f505d57da | 273 | wait(0.01); |
jfields | 0:cd6f505d57da | 274 | leds[i-1] = 0; |
jfields | 0:cd6f505d57da | 275 | } |
jfields | 0:cd6f505d57da | 276 | |
jfields | 0:cd6f505d57da | 277 | void event_out(char *s, int between_t) { |
jfields | 2:1e42b5fdf9e9 | 278 | //lcd.printf("%d\t%s\t%d\n",global_t.read_ms(),s,global_t.read_ms()-between_t); |
jfields | 0:cd6f505d57da | 279 | //fprintf(fp, "%f\t%s\t%f\n",global_t.read_ms(),s,global_t.read_ms()-between_t); |
jfields | 0:cd6f505d57da | 280 | } |
jfields | 0:cd6f505d57da | 281 | |
jfields | 0:cd6f505d57da | 282 | void blind() { |
jfields | 2:1e42b5fdf9e9 | 283 | beats++; |
jfields | 0:cd6f505d57da | 284 | isVRP = 1; |
jfields | 0:cd6f505d57da | 285 | isPVARP = 1; |
jfields | 0:cd6f505d57da | 286 | VRP_timer->start(VRP); |
jfields | 0:cd6f505d57da | 287 | PVARP_timer->start(PVARP); |
jfields | 0:cd6f505d57da | 288 | } |
jfields | 2:1e42b5fdf9e9 | 289 | |
jfields | 2:1e42b5fdf9e9 | 290 | void disp(void const *args) { |
jfields | 2:1e42b5fdf9e9 | 291 | while (1) { |
jfields | 2:1e42b5fdf9e9 | 292 | Thread::signal_wait(RUN,osWaitForever); |
jfields | 2:1e42b5fdf9e9 | 293 | lcd.printf("HR = %d ppm\nCyle = %d s\n",HR,sampleRate/1000); |
jfields | 2:1e42b5fdf9e9 | 294 | beats = 0; |
jfields | 2:1e42b5fdf9e9 | 295 | } |
jfields | 2:1e42b5fdf9e9 | 296 | } |
jfields | 2:1e42b5fdf9e9 | 297 | |
jfields | 2:1e42b5fdf9e9 | 298 | void send_Apace() { |
jfields | 2:1e42b5fdf9e9 | 299 | APace = 1; |
jfields | 2:1e42b5fdf9e9 | 300 | Thread::wait(50); |
jfields | 2:1e42b5fdf9e9 | 301 | APace = 0; |
jfields | 2:1e42b5fdf9e9 | 302 | } |
jfields | 2:1e42b5fdf9e9 | 303 | |
jfields | 2:1e42b5fdf9e9 | 304 | void send_Vpace() { |
jfields | 2:1e42b5fdf9e9 | 305 | VPace = 1; |
jfields | 2:1e42b5fdf9e9 | 306 | Thread::wait(50); |
jfields | 2:1e42b5fdf9e9 | 307 | VPace = 0; |
jfields | 2:1e42b5fdf9e9 | 308 | } |