single global timer

Dependencies:   TextLCD mbed-rtos mbed

Fork of pacemaker_v8 by Pacemaker

Committer:
jfields
Date:
Thu Dec 04 01:02:18 2014 +0000
Revision:
3:c60266d9ce0b
Parent:
2:3773afd2256c
Child:
4:584d9e2e4fae
AA

Who changed what in which revision?

UserRevisionLine numberNew contents of line
jfields 0:3afa00a23ce2 1 #include "mbed.h"
jfields 0:3afa00a23ce2 2 #include "rtos.h"
jfields 0:3afa00a23ce2 3 #include "TextLCD.h"
jfields 0:3afa00a23ce2 4 #include <stdio.h>
jfields 0:3afa00a23ce2 5 #include <stdlib.h>
jfields 0:3afa00a23ce2 6
jfields 0:3afa00a23ce2 7 #define RUN 0x1
jfields 0:3afa00a23ce2 8
jfields 0:3afa00a23ce2 9 TextLCD lcd(p15, p16, p17, p18, p19, p20, TextLCD::LCD16x2);
jfields 0:3afa00a23ce2 10 Serial pc (USBTX, USBRX);
jfields 0:3afa00a23ce2 11
jfields 0:3afa00a23ce2 12 // ports
jfields 0:3afa00a23ce2 13 DigitalIn VGet(p11);
jfields 0:3afa00a23ce2 14 DigitalIn AGet(p12);
jfields 0:3afa00a23ce2 15 DigitalOut VPace(p13);
jfields 0:3afa00a23ce2 16 DigitalOut APace(p14);
jfields 0:3afa00a23ce2 17
jfields 0:3afa00a23ce2 18 // LEDs
jfields 0:3afa00a23ce2 19 DigitalOut leds[] = {LED1, LED2, LED3, LED4};
jfields 0:3afa00a23ce2 20 // 1 = VP
jfields 0:3afa00a23ce2 21 // 2 = AP
jfields 0:3afa00a23ce2 22 // 3 = VS
jfields 0:3afa00a23ce2 23 // 4 = AS
jfields 0:3afa00a23ce2 24
jfields 0:3afa00a23ce2 25 // global clocks
jfields 0:3afa00a23ce2 26 Timer ta; // time since a event
jfields 0:3afa00a23ce2 27 Timer tv; // time since v event
jfields 0:3afa00a23ce2 28
jfields 1:ea01c3232c4a 29 // mutexes
jfields 1:ea01c3232c4a 30 Mutex t_mutex; // protect reading of ta, tv
jfields 1:ea01c3232c4a 31 Mutex status_mutex; // protect reading of
jfields 1:ea01c3232c4a 32 Mutex input_mutex; // protects reading input
jfields 1:ea01c3232c4a 33
jfields 1:ea01c3232c4a 34 // input stuff
jfields 1:ea01c3232c4a 35 char input;
jfields 1:ea01c3232c4a 36
jfields 0:3afa00a23ce2 37 // heart rate global vars
jfields 0:3afa00a23ce2 38 int HR = 0;
jfields 0:3afa00a23ce2 39 int beats = 0;
jfields 0:3afa00a23ce2 40 int sampleRate = 10000; // default 10 seconds
jfields 0:3afa00a23ce2 41 int firstSample = 1;
jfields 3:c60266d9ce0b 42 int Omode = 0;
jfields 0:3afa00a23ce2 43
jfields 0:3afa00a23ce2 44 // Normal Values
jfields 0:3afa00a23ce2 45 const int N_PVARP = 325; // ms
jfields 0:3afa00a23ce2 46 const int N_VRP = 300; // ms
jfields 0:3afa00a23ce2 47 const int N_LRI = 857; // ms (= about 70ppm)
jfields 0:3afa00a23ce2 48 const int N_AVI = 65; // ms
jfields 0:3afa00a23ce2 49 const int N_UB = 100; // 100ppm
jfields 0:3afa00a23ce2 50 const int N_LB = 40; // 40ppm
jfields 0:3afa00a23ce2 51
jfields 1:ea01c3232c4a 52 // Exercise Values
jfields 1:ea01c3232c4a 53 const int E_PVARP = 175; // ms
jfields 1:ea01c3232c4a 54 const int E_VRP = 150; // ms
jfields 1:ea01c3232c4a 55 const int E_LRI = 428; // ms (= about 140ppm)
jfields 1:ea01c3232c4a 56 const int E_AVI = 30; // ms
jfields 1:ea01c3232c4a 57 const int E_UB = 175; // 175ppm
jfields 1:ea01c3232c4a 58 const int E_LB = 100; // 100ppm
jfields 1:ea01c3232c4a 59
jfields 1:ea01c3232c4a 60 // Sleep Values
jfields 1:ea01c3232c4a 61 const int S_PVARP = 500; // ms
jfields 1:ea01c3232c4a 62 const int S_VRP = 475; // ms
jfields 1:ea01c3232c4a 63 const int S_LRI = 1333; // ms (= about 45ppm)
jfields 1:ea01c3232c4a 64 const int S_AVI = 100; // ms
jfields 1:ea01c3232c4a 65 const int S_UB = 60; // 60ppm
jfields 1:ea01c3232c4a 66 const int S_LB = 30; // 30ppm
jfields 1:ea01c3232c4a 67
jfields 0:3afa00a23ce2 68 // Heart Values - Normal Mode is default
jfields 0:3afa00a23ce2 69 int PVARP = N_PVARP;
jfields 0:3afa00a23ce2 70 int VRP = N_VRP;
jfields 0:3afa00a23ce2 71 int LRI = N_LRI;
jfields 0:3afa00a23ce2 72 int AVI = N_AVI;
jfields 0:3afa00a23ce2 73 int UB = N_UB;
jfields 0:3afa00a23ce2 74 int LB = N_LB;
jfields 0:3afa00a23ce2 75
jfields 0:3afa00a23ce2 76 // status flags
jfields 0:3afa00a23ce2 77 int isVRP = 0;
jfields 0:3afa00a23ce2 78 int isPVARP = 0;
jfields 0:3afa00a23ce2 79 int waitingForV = 1;
jfields 3:c60266d9ce0b 80 int inManual = 0;
jfields 0:3afa00a23ce2 81
jfields 0:3afa00a23ce2 82 // functions
jfields 2:3773afd2256c 83 void A_func(void const *args);
jfields 2:3773afd2256c 84 void V_func(void const *args);
jfields 0:3afa00a23ce2 85 void manage_flags(void const *i);
jfields 0:3afa00a23ce2 86 void flashLED(int i);
jfields 1:ea01c3232c4a 87 void calcHR(void const *args);
jfields 1:ea01c3232c4a 88 void disp(void const *args);
jfields 1:ea01c3232c4a 89 void input_func(void const *args);
jfields 1:ea01c3232c4a 90 void setVals(char c);
jfields 2:3773afd2256c 91 void makeManual();
jfields 2:3773afd2256c 92 void blind();
jfields 3:c60266d9ce0b 93 void get_listener(void const *args);
jfields 0:3afa00a23ce2 94
jfields 0:3afa00a23ce2 95 // threads
jfields 2:3773afd2256c 96 Thread * A_thread;
jfields 2:3773afd2256c 97 Thread * V_thread;
jfields 1:ea01c3232c4a 98 Thread * input_thread;
jfields 0:3afa00a23ce2 99 Thread * disp_thread;
jfields 3:c60266d9ce0b 100 Thread * listener;
jfields 0:3afa00a23ce2 101
jfields 0:3afa00a23ce2 102 // rtos timers
jfields 0:3afa00a23ce2 103 RtosTimer * VRP_timer;
jfields 0:3afa00a23ce2 104 RtosTimer * PVARP_timer;
jfields 0:3afa00a23ce2 105 RtosTimer * HR_timer;
jfields 0:3afa00a23ce2 106
jfields 0:3afa00a23ce2 107 int main() {
jfields 0:3afa00a23ce2 108
jfields 0:3afa00a23ce2 109 // start global timer
jfields 0:3afa00a23ce2 110 tv.start();
jfields 0:3afa00a23ce2 111 ta.start();
jfields 0:3afa00a23ce2 112 tv.stop();
jfields 0:3afa00a23ce2 113
jfields 0:3afa00a23ce2 114 // init threads
jfields 1:ea01c3232c4a 115 disp_thread = new Thread(disp);
jfields 1:ea01c3232c4a 116 input_thread = new Thread(input_func);
jfields 2:3773afd2256c 117 A_thread = new Thread(A_func);
jfields 2:3773afd2256c 118 V_thread = new Thread(V_func);
jfields 3:c60266d9ce0b 119 listener = new Thread(get_listener);
jfields 0:3afa00a23ce2 120
jfields 0:3afa00a23ce2 121 // init timers
jfields 0:3afa00a23ce2 122 VRP_timer = new RtosTimer(manage_flags, osTimerOnce, (void *)1);
jfields 0:3afa00a23ce2 123 PVARP_timer = new RtosTimer(manage_flags, osTimerOnce, (void *)2);
jfields 0:3afa00a23ce2 124 HR_timer = new RtosTimer(calcHR, osTimerPeriodic, (void *)0);
jfields 0:3afa00a23ce2 125
jfields 0:3afa00a23ce2 126 // start display and heart rate sample
jfields 0:3afa00a23ce2 127 HR_timer->start(sampleRate);
jfields 0:3afa00a23ce2 128 disp_thread->signal_set(RUN);
jfields 0:3afa00a23ce2 129
jfields 0:3afa00a23ce2 130 // main thread
jfields 0:3afa00a23ce2 131 while (1) {
jfields 0:3afa00a23ce2 132
jfields 0:3afa00a23ce2 133 }
jfields 0:3afa00a23ce2 134 }
jfields 0:3afa00a23ce2 135
jfields 2:3773afd2256c 136 void A_func(void const *args) {
jfields 2:3773afd2256c 137 while (1) {
jfields 3:c60266d9ce0b 138 if (!inManual) {
jfields 3:c60266d9ce0b 139 while (tv.read_ms() <= (LRI-AVI)) {
jfields 3:c60266d9ce0b 140 t_mutex.unlock();
jfields 3:c60266d9ce0b 141 if (AGet==1 && !isPVARP && !waitingForV) {
jfields 3:c60266d9ce0b 142 tv.reset();
jfields 3:c60266d9ce0b 143 tv.stop();
jfields 3:c60266d9ce0b 144 ta.start();
jfields 3:c60266d9ce0b 145 waitingForV = 1;
jfields 3:c60266d9ce0b 146 flashLED(4);
jfields 3:c60266d9ce0b 147 while (AGet == 1);
jfields 3:c60266d9ce0b 148 }
jfields 3:c60266d9ce0b 149 t_mutex.lock();
jfields 2:3773afd2256c 150 }
jfields 3:c60266d9ce0b 151 APace = 1;
jfields 3:c60266d9ce0b 152 Thread::wait(2);
jfields 3:c60266d9ce0b 153 APace = 0;
jfields 3:c60266d9ce0b 154 tv.reset();
jfields 3:c60266d9ce0b 155 tv.stop();
jfields 3:c60266d9ce0b 156 ta.start();
jfields 3:c60266d9ce0b 157 waitingForV = 1;
jfields 3:c60266d9ce0b 158 flashLED(2);
jfields 2:3773afd2256c 159 }
jfields 2:3773afd2256c 160 }
jfields 2:3773afd2256c 161 }
jfields 2:3773afd2256c 162
jfields 2:3773afd2256c 163 void V_func(void const *args) {
jfields 2:3773afd2256c 164 while (1) {
jfields 3:c60266d9ce0b 165 if (!inManual) {
jfields 3:c60266d9ce0b 166 while (ta.read_ms() <= AVI) {
jfields 3:c60266d9ce0b 167 t_mutex.unlock();
jfields 3:c60266d9ce0b 168 if (VGet==1 && !isVRP && waitingForV) {
jfields 3:c60266d9ce0b 169 blind();
jfields 3:c60266d9ce0b 170 flashLED(3);
jfields 3:c60266d9ce0b 171 while (VGet == 1);
jfields 3:c60266d9ce0b 172 }
jfields 3:c60266d9ce0b 173 t_mutex.lock();
jfields 2:3773afd2256c 174 }
jfields 3:c60266d9ce0b 175 VPace = 1;
jfields 3:c60266d9ce0b 176 Thread::wait(2);
jfields 3:c60266d9ce0b 177 VPace = 0;
jfields 3:c60266d9ce0b 178 blind();
jfields 3:c60266d9ce0b 179 flashLED(1);
jfields 2:3773afd2256c 180 }
jfields 2:3773afd2256c 181 }
jfields 2:3773afd2256c 182 }
jfields 2:3773afd2256c 183
jfields 1:ea01c3232c4a 184 void input_func(void const *args) {
jfields 1:ea01c3232c4a 185 while (1) {
jfields 1:ea01c3232c4a 186 input_mutex.lock();
jfields 1:ea01c3232c4a 187 input=pc.getc();
jfields 1:ea01c3232c4a 188 if (input == 'n') setVals('n');
jfields 1:ea01c3232c4a 189 if (input == 's') setVals('s');
jfields 1:ea01c3232c4a 190 if (input == 'e') setVals('e');
jfields 2:3773afd2256c 191 if (input == 'm') makeManual();
jfields 3:c60266d9ce0b 192 if (input == 'o') {
jfields 3:c60266d9ce0b 193 lcd.printf("Enter\n\n");
jfields 3:c60266d9ce0b 194 Omode = 1;
jfields 3:c60266d9ce0b 195 input = pc.getc();
jfields 3:c60266d9ce0b 196 if (input == '1') sampleRate = 10000;
jfields 3:c60266d9ce0b 197 if (input == '2') sampleRate = 20000;
jfields 3:c60266d9ce0b 198 if (input == '3') sampleRate = 30000;
jfields 3:c60266d9ce0b 199 if (input == '4') sampleRate = 60000;
jfields 3:c60266d9ce0b 200 if (input == '5') sampleRate = 100000;
jfields 3:c60266d9ce0b 201 beats = 0;
jfields 3:c60266d9ce0b 202 HR = 0;
jfields 3:c60266d9ce0b 203 Omode = 0;
jfields 3:c60266d9ce0b 204 firstSample = 1;
jfields 3:c60266d9ce0b 205 disp_thread->signal_set(RUN);
jfields 3:c60266d9ce0b 206 }
jfields 1:ea01c3232c4a 207 input_mutex.unlock();
jfields 1:ea01c3232c4a 208 }
jfields 1:ea01c3232c4a 209 }
jfields 1:ea01c3232c4a 210
jfields 0:3afa00a23ce2 211 void calcHR(void const *args) {
jfields 0:3afa00a23ce2 212 if (firstSample == 1) {
jfields 0:3afa00a23ce2 213 HR = beats*(60000/sampleRate);
jfields 0:3afa00a23ce2 214 firstSample = 0;
jfields 0:3afa00a23ce2 215 }
jfields 0:3afa00a23ce2 216 else {
jfields 0:3afa00a23ce2 217 HR = (beats*60000/sampleRate+HR)/2;
jfields 0:3afa00a23ce2 218 }
jfields 0:3afa00a23ce2 219 disp_thread->signal_set(RUN);
jfields 3:c60266d9ce0b 220
jfields 3:c60266d9ce0b 221 if (HR>=UB || HR<=LB) {
jfields 3:c60266d9ce0b 222
jfields 3:c60266d9ce0b 223 }
jfields 3:c60266d9ce0b 224
jfields 3:c60266d9ce0b 225
jfields 0:3afa00a23ce2 226 }
jfields 0:3afa00a23ce2 227
jfields 0:3afa00a23ce2 228 void disp(void const *args) {
jfields 0:3afa00a23ce2 229 while (1) {
jfields 0:3afa00a23ce2 230 Thread::signal_wait(RUN,osWaitForever);
jfields 3:c60266d9ce0b 231 if (!Omode) {
jfields 3:c60266d9ce0b 232 lcd.printf("HR = %d ppm\nCycle = %d s\n",HR,sampleRate/1000);
jfields 3:c60266d9ce0b 233 }
jfields 0:3afa00a23ce2 234 beats = 0;
jfields 0:3afa00a23ce2 235 }
jfields 0:3afa00a23ce2 236 }
jfields 0:3afa00a23ce2 237
jfields 0:3afa00a23ce2 238 void manage_flags(void const *i) {
jfields 1:ea01c3232c4a 239 status_mutex.lock();
jfields 0:3afa00a23ce2 240 if ((int)i==1) isVRP = 0;
jfields 0:3afa00a23ce2 241 if ((int)i==2) isPVARP = 0;
jfields 1:ea01c3232c4a 242 status_mutex.unlock();
jfields 0:3afa00a23ce2 243 }
jfields 0:3afa00a23ce2 244
jfields 0:3afa00a23ce2 245 void flashLED(int i) {
jfields 0:3afa00a23ce2 246 leds[i-1] = 1;
jfields 0:3afa00a23ce2 247 wait(0.01);
jfields 0:3afa00a23ce2 248 leds[i-1] = 0;
jfields 0:3afa00a23ce2 249 }
jfields 0:3afa00a23ce2 250
jfields 0:3afa00a23ce2 251 void blind() {
jfields 0:3afa00a23ce2 252 tv.start();
jfields 0:3afa00a23ce2 253 ta.reset();
jfields 0:3afa00a23ce2 254 ta.stop();
jfields 0:3afa00a23ce2 255 isVRP = 1;
jfields 0:3afa00a23ce2 256 isPVARP = 1;
jfields 1:ea01c3232c4a 257 waitingForV = 0;
jfields 0:3afa00a23ce2 258 VRP_timer->start(VRP);
jfields 0:3afa00a23ce2 259 PVARP_timer->start(PVARP);
jfields 0:3afa00a23ce2 260 beats++;
jfields 0:3afa00a23ce2 261 }
jfields 0:3afa00a23ce2 262
jfields 2:3773afd2256c 263 void makeManual() {
jfields 3:c60266d9ce0b 264 inManual = 1;
jfields 2:3773afd2256c 265 ta.reset();
jfields 2:3773afd2256c 266 ta.stop();
jfields 3:c60266d9ce0b 267 tv.reset();
jfields 0:3afa00a23ce2 268 tv.stop();
jfields 3:c60266d9ce0b 269 UB = 175;
jfields 3:c60266d9ce0b 270 LB = 30;
jfields 3:c60266d9ce0b 271 int done = 0;
jfields 3:c60266d9ce0b 272 while (!done) {
jfields 2:3773afd2256c 273 input = pc.getc();
jfields 2:3773afd2256c 274 if (input == 'v') {
jfields 3:c60266d9ce0b 275 VPace = 1;
jfields 3:c60266d9ce0b 276 Thread::wait(2);
jfields 3:c60266d9ce0b 277 VPace = 0;
jfields 2:3773afd2256c 278 flashLED(1);
jfields 2:3773afd2256c 279 }
jfields 2:3773afd2256c 280 if (input == 'a') {
jfields 3:c60266d9ce0b 281 APace = 1;
jfields 3:c60266d9ce0b 282 Thread::wait(2);
jfields 3:c60266d9ce0b 283 APace = 0;
jfields 2:3773afd2256c 284 flashLED(2);
jfields 2:3773afd2256c 285 }
jfields 3:c60266d9ce0b 286 if (input == 's') {
jfields 3:c60266d9ce0b 287 setVals('s');
jfields 3:c60266d9ce0b 288 done = 1;
jfields 3:c60266d9ce0b 289 }
jfields 3:c60266d9ce0b 290 if (input == 'e') {
jfields 3:c60266d9ce0b 291 setVals('s');
jfields 3:c60266d9ce0b 292 done = 1;
jfields 3:c60266d9ce0b 293 }
jfields 3:c60266d9ce0b 294 if (input == 'n') {
jfields 3:c60266d9ce0b 295 setVals('s');
jfields 3:c60266d9ce0b 296 done = 1;
jfields 3:c60266d9ce0b 297 }
jfields 3:c60266d9ce0b 298 if (input == 'o') {
jfields 3:c60266d9ce0b 299 lcd.printf("Enter\n\n");
jfields 3:c60266d9ce0b 300 Omode = 1;
jfields 3:c60266d9ce0b 301 input = pc.getc();
jfields 3:c60266d9ce0b 302 if (input == '1') sampleRate = 10000;
jfields 3:c60266d9ce0b 303 if (input == '2') sampleRate = 20000;
jfields 3:c60266d9ce0b 304 if (input == '3') sampleRate = 30000;
jfields 3:c60266d9ce0b 305 if (input == '4') sampleRate = 60000;
jfields 3:c60266d9ce0b 306 if (input == '5') sampleRate = 100000;
jfields 3:c60266d9ce0b 307 beats = 0;
jfields 3:c60266d9ce0b 308 HR = 0;
jfields 3:c60266d9ce0b 309 Omode = 0;
jfields 3:c60266d9ce0b 310 firstSample = 1;
jfields 3:c60266d9ce0b 311 disp_thread->signal_set(RUN);
jfields 3:c60266d9ce0b 312
jfields 3:c60266d9ce0b 313 }
jfields 3:c60266d9ce0b 314 }
jfields 3:c60266d9ce0b 315 tv.start();
jfields 3:c60266d9ce0b 316 waitingForV = 1;
jfields 3:c60266d9ce0b 317 VRP_timer->stop();
jfields 3:c60266d9ce0b 318 PVARP_timer->stop();
jfields 3:c60266d9ce0b 319 inManual = 0;
jfields 3:c60266d9ce0b 320 }
jfields 3:c60266d9ce0b 321
jfields 3:c60266d9ce0b 322 void get_listener(void const *args) {
jfields 3:c60266d9ce0b 323 while (1) {
jfields 3:c60266d9ce0b 324 if (inManual) {
jfields 3:c60266d9ce0b 325 if (AGet == 1) {
jfields 3:c60266d9ce0b 326 flashLED(4);
jfields 3:c60266d9ce0b 327 while (AGet == 1);
jfields 3:c60266d9ce0b 328 }
jfields 3:c60266d9ce0b 329 if (VGet == 1) {
jfields 3:c60266d9ce0b 330 flashLED(3);
jfields 3:c60266d9ce0b 331 while (VGet == 1);
jfields 3:c60266d9ce0b 332 }
jfields 3:c60266d9ce0b 333 }
jfields 2:3773afd2256c 334 }
jfields 0:3afa00a23ce2 335 }
jfields 1:ea01c3232c4a 336
jfields 1:ea01c3232c4a 337 void setVals(char c) {
jfields 1:ea01c3232c4a 338 if (c == 'n') {
jfields 1:ea01c3232c4a 339 PVARP = N_PVARP;
jfields 1:ea01c3232c4a 340 VRP = N_VRP;
jfields 1:ea01c3232c4a 341 LRI = N_LRI;
jfields 1:ea01c3232c4a 342 AVI = N_AVI;
jfields 1:ea01c3232c4a 343 UB = N_UB;
jfields 1:ea01c3232c4a 344 LB = N_LB;
jfields 1:ea01c3232c4a 345 }
jfields 1:ea01c3232c4a 346 if (c == 's') {
jfields 1:ea01c3232c4a 347 PVARP = S_PVARP;
jfields 1:ea01c3232c4a 348 VRP = S_VRP;
jfields 1:ea01c3232c4a 349 LRI = S_LRI;
jfields 1:ea01c3232c4a 350 AVI = S_AVI;
jfields 1:ea01c3232c4a 351 UB = S_UB;
jfields 1:ea01c3232c4a 352 LB = S_LB;
jfields 1:ea01c3232c4a 353 }
jfields 1:ea01c3232c4a 354 if (c == 'e') {
jfields 1:ea01c3232c4a 355 PVARP = E_PVARP;
jfields 1:ea01c3232c4a 356 VRP = E_VRP;
jfields 1:ea01c3232c4a 357 LRI = E_LRI;
jfields 1:ea01c3232c4a 358 AVI = E_AVI;
jfields 1:ea01c3232c4a 359 UB = E_UB;
jfields 1:ea01c3232c4a 360 LB = E_LB;
jfields 1:ea01c3232c4a 361 }
jfields 1:ea01c3232c4a 362 }
jfields 2:3773afd2256c 363
jfields 2:3773afd2256c 364
jfields 2:3773afd2256c 365
jfields 2:3773afd2256c 366
jfields 2:3773afd2256c 367
jfields 2:3773afd2256c 368
jfields 2:3773afd2256c 369