here it is

Dependencies:   TextLCD mbed-rtos mbed

Fork of 541-pacemaker by Terry Fang

Committer:
terryfan
Date:
Wed Dec 07 15:10:36 2016 +0000
Revision:
2:682a3ac9d7a3
Parent:
1:e6f6471e2c00
Child:
3:77efff091ef1
latest pacemaker.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
terryfan 0:dac187b013e0 1 #include "mbed.h"
terryfan 0:dac187b013e0 2 #include "rtos.h"
terryfan 0:dac187b013e0 3 #include "TextLCD.h"
terryfan 0:dac187b013e0 4 #include <stdio.h>
terryfan 2:682a3ac9d7a3 5
terryfan 0:dac187b013e0 6 InterruptIn vsignal(p7);
terryfan 0:dac187b013e0 7 InterruptIn asignal(p8);
terryfan 0:dac187b013e0 8 DigitalOut Vpace(p5);
terryfan 0:dac187b013e0 9 DigitalOut Apace(p6);
terryfan 2:682a3ac9d7a3 10
terryfan 0:dac187b013e0 11 DigitalOut asense_led(LED1);
terryfan 0:dac187b013e0 12 DigitalOut vsense_led(LED2);
terryfan 0:dac187b013e0 13 DigitalOut apace_led(LED3);
terryfan 0:dac187b013e0 14 DigitalOut vpace_led(LED4);
terryfan 2:682a3ac9d7a3 15
terryfan 0:dac187b013e0 16 Thread *pacemodeThread;
terryfan 2:682a3ac9d7a3 17
terryfan 0:dac187b013e0 18 osThreadId signalTid;
terryfan 0:dac187b013e0 19 osThreadId senseTid;
terryfan 0:dac187b013e0 20 osThreadId displayTid;
terryfan 0:dac187b013e0 21 osThreadId pacemodeTid;
terryfan 1:e6f6471e2c00 22 osThreadId alarmTid;
terryfan 2:682a3ac9d7a3 23 osThreadId ledTid;
terryfan 0:dac187b013e0 24
terryfan 0:dac187b013e0 25 TextLCD lcd(p15, p16, p17, p18, p19, p20, TextLCD::LCD16x2);
terryfan 0:dac187b013e0 26 RawSerial pc(USBTX, USBRX);
terryfan 2:682a3ac9d7a3 27
terryfan 0:dac187b013e0 28 Timer vClock;
terryfan 0:dac187b013e0 29 Timer aClock; //PaceSignal model
terryfan 2:682a3ac9d7a3 30
terryfan 0:dac187b013e0 31 RtosTimer *apace_timer;
terryfan 0:dac187b013e0 32 RtosTimer *vpace_timer;
terryfan 0:dac187b013e0 33 //RtosTimer *vpace_timer2;
terryfan 2:682a3ac9d7a3 34
terryfan 0:dac187b013e0 35 double LRI = 1000;
terryfan 0:dac187b013e0 36 double URI = 700;
terryfan 0:dac187b013e0 37 double VRP = 200; // V noise interval
terryfan 0:dac187b013e0 38 double ARP = 50; // A noise interval
terryfan 0:dac187b013e0 39 double AVI = 150; // A-V max interval
terryfan 0:dac187b013e0 40 double PVARP = 300; // V-A max interval
terryfan 0:dac187b013e0 41 double ratio;
terryfan 0:dac187b013e0 42 int wait_period = 10; // 3a requirement
terryfan 2:682a3ac9d7a3 43
terryfan 0:dac187b013e0 44 int observation_interval = 10000; // In miliseconds
terryfan 0:dac187b013e0 45 int upperBound; //for mode changes
terryfan 0:dac187b013e0 46 int lowerBound; //for mode changes
terryfan 0:dac187b013e0 47 int heart_beats = 0; // Heart-Beats (sensed or paced) since the last observation interval
terryfan 0:dac187b013e0 48 char mode = 'n';
terryfan 0:dac187b013e0 49 char key = 'n';
terryfan 0:dac187b013e0 50 char newObsInt[8];
terryfan 0:dac187b013e0 51 int manual_mode = 0;
terryfan 1:e6f6471e2c00 52 Mutex hr_mutex; //hr_mutex.lock()/unlock()
terryfan 2:682a3ac9d7a3 53
terryfan 0:dac187b013e0 54 Queue<char,256> mode_q;
terryfan 0:dac187b013e0 55 Queue<char,256> signal_q;
terryfan 1:e6f6471e2c00 56 Queue<char,256> obsint_q;
terryfan 2:682a3ac9d7a3 57
terryfan 0:dac187b013e0 58 volatile char c;
terryfan 0:dac187b013e0 59 volatile int mm = 0;
terryfan 1:e6f6471e2c00 60 volatile int om = 0;
terryfan 0:dac187b013e0 61 int mm_flag = 0;
terryfan 2:682a3ac9d7a3 62
terryfan 0:dac187b013e0 63 void initialize_intervals()
terryfan 0:dac187b013e0 64 {
terryfan 0:dac187b013e0 65 LRI = 1000;
terryfan 0:dac187b013e0 66 URI = 700;
terryfan 1:e6f6471e2c00 67 // VRP = 200;
terryfan 1:e6f6471e2c00 68 // ARP = 50;
terryfan 1:e6f6471e2c00 69 // AVI = 150;
terryfan 1:e6f6471e2c00 70 // PVARP = 300;
terryfan 0:dac187b013e0 71 }
terryfan 2:682a3ac9d7a3 72
terryfan 0:dac187b013e0 73 void Rx_interrupt()
terryfan 0:dac187b013e0 74 {
terryfan 0:dac187b013e0 75 while(pc.readable()) {
terryfan 0:dac187b013e0 76 c = pc.getc();
terryfan 1:e6f6471e2c00 77 if(c == 'm' && om != 1) {
terryfan 0:dac187b013e0 78 mode_q.put((char*)c);
terryfan 0:dac187b013e0 79 mm = 1;
terryfan 1:e6f6471e2c00 80 } else if(c == 'n' || c == 'e' || c == 's' && om != 1) {
terryfan 0:dac187b013e0 81 mode_q.put((char*)c);
terryfan 0:dac187b013e0 82 mm = 0;
terryfan 0:dac187b013e0 83 } else if((c == 'a' || c == 'v') && mm) {
terryfan 0:dac187b013e0 84 signal_q.put((char*)c);
terryfan 1:e6f6471e2c00 85 } else if(c == 'o' && om != 1) {
terryfan 1:e6f6471e2c00 86 mode_q.put((char*)c);
terryfan 1:e6f6471e2c00 87 om = 1;
terryfan 1:e6f6471e2c00 88 } else if (c == '\r' && om) {
terryfan 1:e6f6471e2c00 89 obsint_q.put((char*)c);
terryfan 1:e6f6471e2c00 90 om = 0;
terryfan 1:e6f6471e2c00 91 } else if ((int)c > 47 && (int)c < 58 && om) {
terryfan 1:e6f6471e2c00 92 obsint_q.put((char*)c);
terryfan 0:dac187b013e0 93 }
terryfan 0:dac187b013e0 94 }
terryfan 0:dac187b013e0 95 }
terryfan 2:682a3ac9d7a3 96
terryfan 0:dac187b013e0 97
terryfan 2:682a3ac9d7a3 98 // Thread signals 1=0x5, 2=0x6, 3=0x7, 4=0x8
terryfan 2:682a3ac9d7a3 99 void ledThread(void const *args)
terryfan 0:dac187b013e0 100 {
terryfan 2:682a3ac9d7a3 101 while (1) {
terryfan 2:682a3ac9d7a3 102 osEvent ext_signal = osSignalWait(0, osWaitForever);
terryfan 2:682a3ac9d7a3 103 int evt = ext_signal.value.signals;
terryfan 2:682a3ac9d7a3 104
terryfan 2:682a3ac9d7a3 105 if (evt == 0x5)
terryfan 2:682a3ac9d7a3 106 {
terryfan 0:dac187b013e0 107 asense_led = 1;
terryfan 0:dac187b013e0 108 Thread::wait(wait_period);
terryfan 0:dac187b013e0 109 asense_led = 0;
terryfan 2:682a3ac9d7a3 110 }
terryfan 2:682a3ac9d7a3 111 else if (evt == 0x6)
terryfan 2:682a3ac9d7a3 112 {
terryfan 0:dac187b013e0 113 vsense_led = 1;
terryfan 0:dac187b013e0 114 Thread::wait(wait_period);
terryfan 0:dac187b013e0 115 vsense_led = 0;
terryfan 2:682a3ac9d7a3 116 }
terryfan 2:682a3ac9d7a3 117 else if (evt == 0x7)
terryfan 2:682a3ac9d7a3 118 {
terryfan 0:dac187b013e0 119 apace_led = 1;
terryfan 0:dac187b013e0 120 Thread::wait(wait_period);
terryfan 0:dac187b013e0 121 apace_led = 0;
terryfan 2:682a3ac9d7a3 122 }
terryfan 2:682a3ac9d7a3 123 else if (evt == 0x8)
terryfan 2:682a3ac9d7a3 124 {
terryfan 0:dac187b013e0 125 vpace_led = 1;
terryfan 0:dac187b013e0 126 Thread::wait(wait_period);
terryfan 0:dac187b013e0 127 vpace_led = 0;
terryfan 2:682a3ac9d7a3 128 }
terryfan 2:682a3ac9d7a3 129 }
terryfan 0:dac187b013e0 130 }
terryfan 2:682a3ac9d7a3 131
terryfan 1:e6f6471e2c00 132 void alarmThread(void const *args)
terryfan 1:e6f6471e2c00 133 {
terryfan 1:e6f6471e2c00 134 while (1)
terryfan 1:e6f6471e2c00 135 {
terryfan 1:e6f6471e2c00 136 osEvent ext_signal = osSignalWait(0, osWaitForever);
terryfan 1:e6f6471e2c00 137 int evt = ext_signal.value.signals;
terryfan 2:682a3ac9d7a3 138
terryfan 1:e6f6471e2c00 139 if (evt == 0xb){
terryfan 1:e6f6471e2c00 140 lcd.printf("%s", "\nALARM HIGH");
terryfan 1:e6f6471e2c00 141 }
terryfan 1:e6f6471e2c00 142 else if (evt == 0xc) {
terryfan 1:e6f6471e2c00 143 lcd.printf("%s", "\nALARM LOW");
terryfan 1:e6f6471e2c00 144 }
terryfan 1:e6f6471e2c00 145 }
terryfan 1:e6f6471e2c00 146 }
terryfan 2:682a3ac9d7a3 147
terryfan 0:dac187b013e0 148 void displayThread(void const *args)
terryfan 0:dac187b013e0 149 {
terryfan 0:dac187b013e0 150 while (1) {
terryfan 0:dac187b013e0 151 Thread::wait(observation_interval);
terryfan 0:dac187b013e0 152 lcd.cls();
terryfan 1:e6f6471e2c00 153
terryfan 1:e6f6471e2c00 154 hr_mutex.lock();
terryfan 0:dac187b013e0 155 int hr = (heart_beats*60) / (observation_interval / 1000);
terryfan 1:e6f6471e2c00 156 heart_beats = 0;
terryfan 1:e6f6471e2c00 157 hr_mutex.unlock();
terryfan 1:e6f6471e2c00 158
terryfan 0:dac187b013e0 159 lcd.printf("%s%d%s","HR: ", hr, " bpm");
terryfan 1:e6f6471e2c00 160
terryfan 1:e6f6471e2c00 161 if (hr > upperBound)
terryfan 1:e6f6471e2c00 162 {
terryfan 1:e6f6471e2c00 163 osSignalSet(alarmTid, 0xb);
terryfan 0:dac187b013e0 164 }
terryfan 1:e6f6471e2c00 165 else if (hr < lowerBound)
terryfan 1:e6f6471e2c00 166 {
terryfan 1:e6f6471e2c00 167 osSignalSet(alarmTid, 0xc);
terryfan 1:e6f6471e2c00 168 }
terryfan 0:dac187b013e0 169 }
terryfan 0:dac187b013e0 170 }
terryfan 2:682a3ac9d7a3 171
terryfan 2:682a3ac9d7a3 172
terryfan 2:682a3ac9d7a3 173
terryfan 0:dac187b013e0 174 // Incoming signal from the heart
terryfan 0:dac187b013e0 175 void asignal_irq()
terryfan 0:dac187b013e0 176 {
terryfan 0:dac187b013e0 177 osSignalSet(signalTid, 0x1);
terryfan 0:dac187b013e0 178 }
terryfan 2:682a3ac9d7a3 179
terryfan 0:dac187b013e0 180 // Incoming signal from the heart
terryfan 0:dac187b013e0 181 void vsignal_irq()
terryfan 0:dac187b013e0 182 {
terryfan 0:dac187b013e0 183 osSignalSet(signalTid, 0x2);
terryfan 0:dac187b013e0 184 }
terryfan 2:682a3ac9d7a3 185
terryfan 2:682a3ac9d7a3 186
terryfan 0:dac187b013e0 187 // Timer-driven function to pace the Atrial
terryfan 0:dac187b013e0 188 void a_pace(void const*)
terryfan 0:dac187b013e0 189 {
terryfan 1:e6f6471e2c00 190 Apace = 1;
terryfan 0:dac187b013e0 191 aClock.reset();
terryfan 1:e6f6471e2c00 192 apace_timer->stop();
terryfan 2:682a3ac9d7a3 193 osSignalSet(ledTid, 0x7);
terryfan 0:dac187b013e0 194 Apace = 0;
terryfan 0:dac187b013e0 195 osSignalSet(signalTid, 0x3);
terryfan 0:dac187b013e0 196 }
terryfan 2:682a3ac9d7a3 197
terryfan 0:dac187b013e0 198 // Timer-driven function to pace the ventrical
terryfan 0:dac187b013e0 199 void v_pace(void const*)
terryfan 0:dac187b013e0 200 {
terryfan 1:e6f6471e2c00 201 Vpace = 1;
terryfan 2:682a3ac9d7a3 202
terryfan 2:682a3ac9d7a3 203
terryfan 0:dac187b013e0 204 vClock.reset();
terryfan 1:e6f6471e2c00 205 vpace_timer->start(LRI);
terryfan 1:e6f6471e2c00 206 apace_timer->start(LRI-AVI);
terryfan 2:682a3ac9d7a3 207 osSignalSet(ledTid, 0x8);
terryfan 0:dac187b013e0 208 Vpace = 0;
terryfan 0:dac187b013e0 209 osSignalSet(signalTid, 0x4);
terryfan 2:682a3ac9d7a3 210
terryfan 1:e6f6471e2c00 211 hr_mutex.lock();
terryfan 0:dac187b013e0 212 heart_beats++;
terryfan 1:e6f6471e2c00 213 hr_mutex.unlock();
terryfan 0:dac187b013e0 214 }
terryfan 2:682a3ac9d7a3 215
terryfan 2:682a3ac9d7a3 216
terryfan 2:682a3ac9d7a3 217
terryfan 0:dac187b013e0 218 void PaceSignal(void const *args)
terryfan 0:dac187b013e0 219 {
terryfan 0:dac187b013e0 220 int pFlag1 = 0;
terryfan 0:dac187b013e0 221 int pFlag2 = 0;
terryfan 0:dac187b013e0 222 vClock.start();
terryfan 0:dac187b013e0 223 aClock.start();
terryfan 1:e6f6471e2c00 224 if(!mm_flag) {
terryfan 0:dac187b013e0 225 vpace_timer->start(LRI);
terryfan 0:dac187b013e0 226 apace_timer->start(LRI-AVI);
terryfan 0:dac187b013e0 227 }
terryfan 0:dac187b013e0 228 // vpace_timer2->start(AVI);
terryfan 0:dac187b013e0 229 while(1) {
terryfan 0:dac187b013e0 230 while (!pFlag1) {
terryfan 0:dac187b013e0 231 osEvent ext_signal = osSignalWait(0, osWaitForever);
terryfan 0:dac187b013e0 232 int evt = ext_signal.value.signals;
terryfan 2:682a3ac9d7a3 233
terryfan 0:dac187b013e0 234 if (evt == 0x1 && vClock.read_ms() >= PVARP) { //aSignal
terryfan 0:dac187b013e0 235 osSignalSet(senseTid, 0x1);
terryfan 0:dac187b013e0 236 aClock.reset();
terryfan 1:e6f6471e2c00 237 if(!mm_flag) {
terryfan 1:e6f6471e2c00 238 apace_timer->stop();
terryfan 1:e6f6471e2c00 239 int interval = (vClock.read_ms() + AVI >= URI) ? AVI : URI - vClock.read_ms();
terryfan 1:e6f6471e2c00 240 apace_timer->start(interval);
terryfan 0:dac187b013e0 241 }
terryfan 0:dac187b013e0 242 pFlag1 = 1;
terryfan 0:dac187b013e0 243 } else if(evt == 0x2 && vClock.read_ms() >= VRP) { //vSignal
terryfan 2:682a3ac9d7a3 244 hr_mutex.lock();
terryfan 2:682a3ac9d7a3 245 heart_beats++;
terryfan 2:682a3ac9d7a3 246 hr_mutex.unlock();
terryfan 0:dac187b013e0 247 osSignalSet(senseTid, 0x2);
terryfan 0:dac187b013e0 248 vClock.reset();
terryfan 1:e6f6471e2c00 249 if(!mm_flag) {
terryfan 0:dac187b013e0 250 vpace_timer->start(LRI);
terryfan 0:dac187b013e0 251 apace_timer->start(LRI-AVI);
terryfan 0:dac187b013e0 252 }
terryfan 2:682a3ac9d7a3 253
terryfan 0:dac187b013e0 254 } else if (evt == 0x3) { //aPace
terryfan 0:dac187b013e0 255 pFlag1 = 1;
terryfan 0:dac187b013e0 256 }
terryfan 0:dac187b013e0 257 }
terryfan 0:dac187b013e0 258 pFlag1 = 0;
terryfan 2:682a3ac9d7a3 259
terryfan 0:dac187b013e0 260 while(!pFlag2) {
terryfan 2:682a3ac9d7a3 261
terryfan 0:dac187b013e0 262 osEvent ext_signal = osSignalWait(0, osWaitForever);
terryfan 0:dac187b013e0 263 int evt = ext_signal.value.signals;
terryfan 2:682a3ac9d7a3 264
terryfan 0:dac187b013e0 265 if (evt == 0x1 && aClock.read_ms() >= ARP) { //aSignal
terryfan 0:dac187b013e0 266 osSignalSet(senseTid, 0x1);
terryfan 0:dac187b013e0 267 aClock.reset();
terryfan 0:dac187b013e0 268 } else if(evt == 0x2) { //vSignal
terryfan 2:682a3ac9d7a3 269 hr_mutex.lock();
terryfan 2:682a3ac9d7a3 270 heart_beats++;
terryfan 2:682a3ac9d7a3 271 hr_mutex.unlock();
terryfan 0:dac187b013e0 272 osSignalSet(senseTid, 0x2);
terryfan 0:dac187b013e0 273 vClock.reset();
terryfan 1:e6f6471e2c00 274 if(!mm_flag) {
terryfan 0:dac187b013e0 275 vpace_timer->start(LRI);
terryfan 0:dac187b013e0 276 apace_timer->start(LRI-AVI);
terryfan 0:dac187b013e0 277 }
terryfan 0:dac187b013e0 278 pFlag2 = 1;
terryfan 0:dac187b013e0 279 } else if (evt == 0x4) { //vPace
terryfan 0:dac187b013e0 280 pFlag2 = 1;
terryfan 0:dac187b013e0 281 }
terryfan 0:dac187b013e0 282 }
terryfan 0:dac187b013e0 283 pFlag2 = 0;
terryfan 0:dac187b013e0 284 }
terryfan 0:dac187b013e0 285 }
terryfan 2:682a3ac9d7a3 286
terryfan 2:682a3ac9d7a3 287
terryfan 0:dac187b013e0 288 void PaceSense(void const *args)
terryfan 0:dac187b013e0 289 {
terryfan 0:dac187b013e0 290 int pFlag1 = 0;
terryfan 0:dac187b013e0 291 int pFlag2 = 0;
terryfan 0:dac187b013e0 292 while(1) {
terryfan 0:dac187b013e0 293 while (!pFlag1) {
terryfan 0:dac187b013e0 294 osEvent ext_signal = osSignalWait(0, osWaitForever);
terryfan 0:dac187b013e0 295 int evt = ext_signal.value.signals;
terryfan 2:682a3ac9d7a3 296
terryfan 0:dac187b013e0 297 if (evt == 0x1) { //aSense
terryfan 2:682a3ac9d7a3 298 osSignalSet(ledTid, 0x5);
terryfan 0:dac187b013e0 299 pFlag1 = 1;
terryfan 0:dac187b013e0 300 } else if(evt == 0x2) { //vSense
terryfan 2:682a3ac9d7a3 301 osSignalSet(ledTid, 0x6);
terryfan 0:dac187b013e0 302 } else if (evt == 0x3) { //aPace
terryfan 0:dac187b013e0 303 pFlag1 = 1;
terryfan 0:dac187b013e0 304 }
terryfan 2:682a3ac9d7a3 305
terryfan 0:dac187b013e0 306 }
terryfan 0:dac187b013e0 307 pFlag1 = 0;
terryfan 0:dac187b013e0 308 while(!pFlag2) {
terryfan 0:dac187b013e0 309 osEvent ext_signal = osSignalWait(0, osWaitForever);
terryfan 0:dac187b013e0 310 int evt = ext_signal.value.signals;
terryfan 2:682a3ac9d7a3 311
terryfan 0:dac187b013e0 312 if (evt == 0x1) { //aSense
terryfan 2:682a3ac9d7a3 313 osSignalSet(ledTid, 0x5);
terryfan 0:dac187b013e0 314 } else if(evt == 0x2) { //vSignal
terryfan 2:682a3ac9d7a3 315 osSignalSet(ledTid, 0x6);
terryfan 0:dac187b013e0 316 pFlag2 = 1;
terryfan 0:dac187b013e0 317 } else if (evt == 0x4) { //vPace
terryfan 0:dac187b013e0 318 pFlag2 = 1;
terryfan 0:dac187b013e0 319 }
terryfan 0:dac187b013e0 320 }
terryfan 0:dac187b013e0 321 pFlag2 = 0;
terryfan 0:dac187b013e0 322 }
terryfan 0:dac187b013e0 323 }
terryfan 2:682a3ac9d7a3 324
terryfan 0:dac187b013e0 325 void normalmode(void const *args)
terryfan 0:dac187b013e0 326 {
terryfan 0:dac187b013e0 327 initialize_intervals();
terryfan 0:dac187b013e0 328 mode = 'n';
terryfan 0:dac187b013e0 329 lcd.printf("N");
terryfan 0:dac187b013e0 330 upperBound = 100; //beats per msecond
terryfan 0:dac187b013e0 331 lowerBound = 40; //beats per msecond
terryfan 1:e6f6471e2c00 332 //reset obs interval
terryfan 1:e6f6471e2c00 333 hr_mutex.lock();
terryfan 1:e6f6471e2c00 334 heart_beats = 0;
terryfan 1:e6f6471e2c00 335 hr_mutex.unlock();
terryfan 2:682a3ac9d7a3 336
terryfan 0:dac187b013e0 337 vpace_timer->start(LRI);
terryfan 0:dac187b013e0 338 apace_timer->start(LRI-AVI);
terryfan 0:dac187b013e0 339 }
terryfan 2:682a3ac9d7a3 340
terryfan 0:dac187b013e0 341 void exercisemode(void const *args)
terryfan 0:dac187b013e0 342 {
terryfan 0:dac187b013e0 343 initialize_intervals();
terryfan 0:dac187b013e0 344 mode = 'e';
terryfan 0:dac187b013e0 345 lcd.printf("E");
terryfan 0:dac187b013e0 346 upperBound = 175; //beats per msecond
terryfan 0:dac187b013e0 347 lowerBound = 100; //beats per msecond
terryfan 0:dac187b013e0 348 ratio = (175.00/100.00 + 100.00/40.00) / 2.00;
terryfan 0:dac187b013e0 349 LRI /= ratio;
terryfan 0:dac187b013e0 350 URI /= ratio;
terryfan 1:e6f6471e2c00 351 //reset obs interval
terryfan 1:e6f6471e2c00 352 hr_mutex.lock();
terryfan 1:e6f6471e2c00 353 heart_beats = 0;
terryfan 1:e6f6471e2c00 354 hr_mutex.unlock();
terryfan 2:682a3ac9d7a3 355
terryfan 0:dac187b013e0 356 vpace_timer->start(LRI);
terryfan 0:dac187b013e0 357 apace_timer->start(LRI-AVI);
terryfan 0:dac187b013e0 358 }
terryfan 2:682a3ac9d7a3 359
terryfan 0:dac187b013e0 360 void sleepmode(void const *args)
terryfan 0:dac187b013e0 361 {
terryfan 0:dac187b013e0 362 initialize_intervals();
terryfan 0:dac187b013e0 363 mode = 's';
terryfan 0:dac187b013e0 364 lcd.printf("S");
terryfan 0:dac187b013e0 365 upperBound = 60; //beats per msecond
terryfan 0:dac187b013e0 366 lowerBound = 30; //beats per msecond v-v 0.5s
terryfan 0:dac187b013e0 367 ratio = (60.00/100.00 + 30.00/40.00) / 2.00;
terryfan 0:dac187b013e0 368 LRI /= ratio;
terryfan 0:dac187b013e0 369 URI /= ratio;
terryfan 1:e6f6471e2c00 370 //reset obs interval
terryfan 1:e6f6471e2c00 371 hr_mutex.lock();
terryfan 1:e6f6471e2c00 372 heart_beats = 0;
terryfan 1:e6f6471e2c00 373 hr_mutex.unlock();
terryfan 2:682a3ac9d7a3 374
terryfan 0:dac187b013e0 375 vpace_timer->start(LRI);
terryfan 0:dac187b013e0 376 apace_timer->start(LRI-AVI);
terryfan 0:dac187b013e0 377 }
terryfan 2:682a3ac9d7a3 378
terryfan 1:e6f6471e2c00 379 void m_vpace()
terryfan 1:e6f6471e2c00 380 {
terryfan 0:dac187b013e0 381 vClock.reset();
terryfan 0:dac187b013e0 382 Vpace = 1;
terryfan 2:682a3ac9d7a3 383 osSignalSet(ledTid, 0x8);
terryfan 0:dac187b013e0 384 Vpace = 0;
terryfan 0:dac187b013e0 385 osSignalSet(signalTid, 0x4);
terryfan 1:e6f6471e2c00 386 hr_mutex.lock();
terryfan 0:dac187b013e0 387 heart_beats++;
terryfan 1:e6f6471e2c00 388 hr_mutex.unlock();
terryfan 0:dac187b013e0 389 }
terryfan 2:682a3ac9d7a3 390
terryfan 1:e6f6471e2c00 391 void m_apace()
terryfan 1:e6f6471e2c00 392 {
terryfan 0:dac187b013e0 393 aClock.reset();
terryfan 0:dac187b013e0 394 Apace = 1;
terryfan 2:682a3ac9d7a3 395 osSignalSet(ledTid, 0x7);
terryfan 0:dac187b013e0 396 Apace = 0;
terryfan 0:dac187b013e0 397 osSignalSet(signalTid, 0x3);
terryfan 0:dac187b013e0 398 }
terryfan 2:682a3ac9d7a3 399
terryfan 0:dac187b013e0 400 void manualmode(void const *args)
terryfan 0:dac187b013e0 401 {
terryfan 0:dac187b013e0 402 upperBound = 175; //beats per msecond
terryfan 0:dac187b013e0 403 lowerBound = 30; //beats per msecond
terryfan 0:dac187b013e0 404 lcd.printf("M");
terryfan 0:dac187b013e0 405 mode = 'm';
terryfan 1:e6f6471e2c00 406 LRI = 2125; // max V-V (LRI) based on exercise mode
terryfan 1:e6f6471e2c00 407 URI = 675; // min V-V (URI) based on sleep mode
terryfan 2:682a3ac9d7a3 408
terryfan 0:dac187b013e0 409 while(1) {
terryfan 0:dac187b013e0 410 osEvent evt = signal_q.get();
terryfan 0:dac187b013e0 411 if(evt.status == osEventMessage) {
terryfan 0:dac187b013e0 412 if((char)evt.value.p == 'v') {
terryfan 0:dac187b013e0 413 m_vpace();
terryfan 0:dac187b013e0 414 } else if((char)evt.value.p == 'a') {
terryfan 0:dac187b013e0 415 m_apace();
terryfan 0:dac187b013e0 416 }
terryfan 0:dac187b013e0 417 }
terryfan 0:dac187b013e0 418 }
terryfan 0:dac187b013e0 419 }
terryfan 2:682a3ac9d7a3 420
terryfan 1:e6f6471e2c00 421 void obsinterval()
terryfan 1:e6f6471e2c00 422 {
terryfan 1:e6f6471e2c00 423 char newObsInt[8];
terryfan 1:e6f6471e2c00 424 int isChangingObsInt = 1;
terryfan 1:e6f6471e2c00 425 int i = 0;
terryfan 1:e6f6471e2c00 426 while(isChangingObsInt) {
terryfan 1:e6f6471e2c00 427 osEvent evt = obsint_q.get();
terryfan 1:e6f6471e2c00 428 if(evt.status == osEventMessage) {
terryfan 1:e6f6471e2c00 429 key = (char)evt.value.p;
terryfan 1:e6f6471e2c00 430 if(key != '\r' && i < 7 ) {
terryfan 1:e6f6471e2c00 431 newObsInt[i] = key;
terryfan 1:e6f6471e2c00 432 i++;
terryfan 1:e6f6471e2c00 433 } else if((key == '\r') && (i > 0)) {
terryfan 2:682a3ac9d7a3 434 hr_mutex.lock();
terryfan 1:e6f6471e2c00 435 heart_beats = 0;
terryfan 2:682a3ac9d7a3 436 hr_mutex.unlock();
terryfan 1:e6f6471e2c00 437 int obsint;
terryfan 1:e6f6471e2c00 438 newObsInt[i] = '\0';
terryfan 1:e6f6471e2c00 439 sscanf(newObsInt, "%d", &obsint);
terryfan 2:682a3ac9d7a3 440 hr_mutex.lock();
terryfan 1:e6f6471e2c00 441 observation_interval = (obsint > 0 ) ? obsint: 1;
terryfan 2:682a3ac9d7a3 442 hr_mutex.unlock();
terryfan 1:e6f6471e2c00 443 isChangingObsInt = 0;
terryfan 1:e6f6471e2c00 444 lcd.printf("%d", observation_interval);
terryfan 1:e6f6471e2c00 445 }
terryfan 1:e6f6471e2c00 446 }
terryfan 1:e6f6471e2c00 447 }
terryfan 1:e6f6471e2c00 448 }
terryfan 2:682a3ac9d7a3 449
terryfan 0:dac187b013e0 450 osThreadDef(PaceSignal, osPriorityNormal, DEFAULT_STACK_SIZE);
terryfan 0:dac187b013e0 451 osThreadDef(PaceSense, osPriorityNormal, DEFAULT_STACK_SIZE);
terryfan 1:e6f6471e2c00 452 osThreadDef(alarmThread, osPriorityBelowNormal, DEFAULT_STACK_SIZE); //priority BelowNormal
terryfan 2:682a3ac9d7a3 453 osThreadDef(ledThread, osPriorityBelowNormal, DEFAULT_STACK_SIZE); //priority BelowNormal
terryfan 1:e6f6471e2c00 454 osThreadDef(displayThread, osPriorityLow, DEFAULT_STACK_SIZE); //priority Low
terryfan 0:dac187b013e0 455 osThreadDef(manualmode, osPriorityNormal, DEFAULT_STACK_SIZE);
terryfan 0:dac187b013e0 456 osThreadDef(normalmode, osPriorityNormal, DEFAULT_STACK_SIZE);
terryfan 0:dac187b013e0 457 osThreadDef(exercisemode, osPriorityNormal, DEFAULT_STACK_SIZE);
terryfan 0:dac187b013e0 458 osThreadDef(sleepmode, osPriorityNormal, DEFAULT_STACK_SIZE);
terryfan 2:682a3ac9d7a3 459
terryfan 2:682a3ac9d7a3 460
terryfan 1:e6f6471e2c00 461 ////////////////////////////////////////////
terryfan 1:e6f6471e2c00 462 ////////////////////////////////////////////
terryfan 1:e6f6471e2c00 463 ////////////////////////////////////////////
terryfan 2:682a3ac9d7a3 464
terryfan 0:dac187b013e0 465 int main()
terryfan 0:dac187b013e0 466 {
terryfan 2:682a3ac9d7a3 467 ledTid = osThreadCreate(osThread(ledThread), NULL);
terryfan 1:e6f6471e2c00 468 alarmTid = osThreadCreate(osThread(alarmThread), NULL);
terryfan 0:dac187b013e0 469 senseTid = osThreadCreate(osThread(PaceSense), NULL);
terryfan 0:dac187b013e0 470 signalTid = osThreadCreate(osThread(PaceSignal), NULL);
terryfan 0:dac187b013e0 471 displayTid = osThreadCreate(osThread(displayThread), NULL);
terryfan 0:dac187b013e0 472 pacemodeTid = osThreadCreate(osThread(normalmode), NULL);
terryfan 1:e6f6471e2c00 473
terryfan 0:dac187b013e0 474 vsignal.rise(&vsignal_irq); //rising edge of timer
terryfan 0:dac187b013e0 475 asignal.rise(&asignal_irq);
terryfan 2:682a3ac9d7a3 476
terryfan 0:dac187b013e0 477 Callback<void()> apaceTimerTask((void*)NULL, (void (*)(void*))&a_pace);
terryfan 0:dac187b013e0 478 Callback<void()> vpaceTimerTask((void*)NULL, (void (*)(void*))&v_pace);
terryfan 0:dac187b013e0 479 apace_timer = new RtosTimer(apaceTimerTask);
terryfan 0:dac187b013e0 480 vpace_timer = new RtosTimer(vpaceTimerTask);
terryfan 2:682a3ac9d7a3 481
terryfan 0:dac187b013e0 482 lcd.cls();
terryfan 2:682a3ac9d7a3 483
terryfan 0:dac187b013e0 484 pc.attach(&Rx_interrupt, RawSerial::RxIrq);
terryfan 2:682a3ac9d7a3 485
terryfan 0:dac187b013e0 486 while(true) {
terryfan 0:dac187b013e0 487 osEvent evt = mode_q.get();
terryfan 0:dac187b013e0 488 if(evt.status == osEventMessage) {
terryfan 0:dac187b013e0 489 switch((char)evt.value.p) {
terryfan 0:dac187b013e0 490 case('n'):
terryfan 0:dac187b013e0 491 mm_flag = 0;
terryfan 0:dac187b013e0 492 osThreadTerminate (pacemodeTid);
terryfan 1:e6f6471e2c00 493 osThreadTerminate (displayTid);
terryfan 0:dac187b013e0 494 pacemodeTid = osThreadCreate(osThread(normalmode), NULL);
terryfan 1:e6f6471e2c00 495 displayTid = osThreadCreate(osThread(displayThread), NULL);
terryfan 1:e6f6471e2c00 496 lcd.printf("%d", observation_interval);
terryfan 0:dac187b013e0 497 break;
terryfan 0:dac187b013e0 498 case('s'):
terryfan 0:dac187b013e0 499 mm_flag = 0;
terryfan 1:e6f6471e2c00 500 // lcd.printf("testingS");
terryfan 0:dac187b013e0 501 osThreadTerminate (pacemodeTid);
terryfan 1:e6f6471e2c00 502 osThreadTerminate (displayTid);
terryfan 0:dac187b013e0 503 pacemodeTid = osThreadCreate(osThread(sleepmode), NULL);
terryfan 1:e6f6471e2c00 504 displayTid = osThreadCreate(osThread(displayThread), NULL);
terryfan 0:dac187b013e0 505 break;
terryfan 0:dac187b013e0 506 case('e'):
terryfan 0:dac187b013e0 507 mm_flag = 0;
terryfan 1:e6f6471e2c00 508 // lcd.printf("testingE");
terryfan 0:dac187b013e0 509 osThreadTerminate (pacemodeTid);
terryfan 1:e6f6471e2c00 510 osThreadTerminate (displayTid);
terryfan 0:dac187b013e0 511 pacemodeTid = osThreadCreate(osThread(exercisemode), NULL);
terryfan 1:e6f6471e2c00 512 displayTid = osThreadCreate(osThread(displayThread), NULL);
terryfan 1:e6f6471e2c00 513 lcd.printf("%d", observation_interval);
terryfan 0:dac187b013e0 514 break;
terryfan 0:dac187b013e0 515 case('m'):
terryfan 0:dac187b013e0 516 mm_flag = 1;
terryfan 0:dac187b013e0 517 osThreadTerminate (pacemodeTid);
terryfan 1:e6f6471e2c00 518 //osThreadTerminate (displayTid);
terryfan 0:dac187b013e0 519 apace_timer->stop();
terryfan 0:dac187b013e0 520 vpace_timer->stop();
terryfan 0:dac187b013e0 521 pacemodeTid = osThreadCreate(osThread(manualmode), NULL);
terryfan 1:e6f6471e2c00 522 // displayTid = osThreadCreate(osThread(displayThread), NULL);
terryfan 0:dac187b013e0 523 manual_mode = 1;
terryfan 0:dac187b013e0 524 break;
terryfan 0:dac187b013e0 525 case('o'):
terryfan 1:e6f6471e2c00 526 lcd.printf("modeO");
terryfan 2:682a3ac9d7a3 527 obsinterval();;
terryfan 1:e6f6471e2c00 528 osThreadTerminate (displayTid);
terryfan 1:e6f6471e2c00 529 displayTid = osThreadCreate(osThread(displayThread), NULL);
terryfan 0:dac187b013e0 530 break;
terryfan 0:dac187b013e0 531 }
terryfan 0:dac187b013e0 532 }
terryfan 0:dac187b013e0 533 }
terryfan 2:682a3ac9d7a3 534 }