Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: TextLCD mbed-rtos mbed
Fork of pm_pacemaker by
main.cpp
00001 #include "mbed.h" 00002 #include "rtos.h" 00003 #include "TextLCD.h" 00004 00005 InterruptIn vsignal(p7); 00006 InterruptIn asignal(p8); 00007 DigitalOut Vpace(p5); 00008 DigitalOut Apace(p6); 00009 00010 DigitalOut asense_led(LED1); 00011 DigitalOut vsense_led(LED2); 00012 DigitalOut apace_led(LED3); 00013 DigitalOut vpace_led(LED4); 00014 00015 Thread *pacemodeThread; 00016 00017 osThreadId signalTid; 00018 osThreadId senseTid; 00019 osThreadId displayTid; 00020 00021 TextLCD lcd(p15, p16, p17, p18, p19, p20, TextLCD::LCD16x2); 00022 Serial pc(USBTX, USBRX); 00023 RawSerial pc2(USBTX, USBRX); 00024 00025 Timer vClock; 00026 Timer aClock; //PaceSignal model 00027 00028 RtosTimer *apace_timer; 00029 RtosTimer *vpace_timer; 00030 00031 double LRI = 1000; 00032 double URI = 700; 00033 double VRP = 200; // V noise interval 00034 double ARP = 50; // A noise interval 00035 double AVI = 150; // A-V max interval 00036 double PVARP = 300; // V-A max interval 00037 double ratio; 00038 int wait_period = 10; // 3a requirement in miliseconds 00039 00040 int upperBound; //for mode changes 00041 int lowerBound; //for mode changes 00042 00043 int observation_interval = 10; // In seconds 00044 int heart_beats = 0; // Heart-Beats (sensed or paced) since the last observation interval 00045 00046 int isChangingObsInt = 0; 00047 char key = 'n'; 00048 char newObsInt[8]; 00049 int manual_mode = 0; 00050 char mode = 'n'; 00051 00052 00053 00054 void initialize_intervals() 00055 { 00056 LRI = 1000; 00057 URI = 700; 00058 VRP = 200; 00059 ARP = 50; 00060 AVI = 150; 00061 PVARP = 300; 00062 } 00063 00064 00065 // Function to toggle the LEDs 1,2,3,4 00066 void toggleLed(int led) 00067 { 00068 switch (led) { 00069 case (1): 00070 asense_led = 1; 00071 Thread::wait(wait_period); 00072 asense_led = 0; 00073 break; 00074 case (2): 00075 vsense_led = 1; 00076 Thread::wait(wait_period); 00077 vsense_led = 0; 00078 break; 00079 case (3): 00080 apace_led = 1; 00081 Thread::wait(wait_period); 00082 apace_led = 0; 00083 break; 00084 case (4): 00085 vpace_led = 1; 00086 Thread::wait(wait_period); 00087 vpace_led = 0; 00088 break; 00089 } 00090 } 00091 00092 void displayThread(void const *args) 00093 { 00094 while (1) { 00095 Thread::wait(observation_interval * 1000); 00096 lcd.cls(); 00097 int hr = (heart_beats*60) / (observation_interval); 00098 lcd.printf("%s%d%s","HR: ", hr, " bpm\n"); 00099 //lcd.printf("%d", observation_interval); 00100 switch(mode) { 00101 case('n'): 00102 if (hr > 100) { 00103 lcd.printf("%s", "\nALARM HIGH"); 00104 } else if (hr < 40) { 00105 lcd.printf("%s", "\nALARM LOW"); 00106 } 00107 break; 00108 case('e'): 00109 if (hr > 175) { 00110 lcd.printf("%s", "\nALARM HIGH"); 00111 } else if (hr < 100) { 00112 lcd.printf("%s", "\nALARM LOW"); 00113 } 00114 break; 00115 case('s'): 00116 if (hr > 60) { 00117 lcd.printf("%s", "\nALARM HIGH"); 00118 } else if (hr < 30) { 00119 lcd.printf("%s", "\nALARM LOW"); 00120 } 00121 break; 00122 case('m'): 00123 if (hr > 175) { 00124 lcd.printf("%s", "\nALARM HIGH"); 00125 } else if (hr < 30) { 00126 lcd.printf("%s", "\nALARM LOW"); 00127 } 00128 break; 00129 } 00130 00131 heart_beats = 0; 00132 } 00133 } 00134 00135 00136 // Incoming a signal from the heart 00137 void asignal_irq() 00138 { 00139 osSignalSet(signalTid, 0x1); 00140 } 00141 00142 // Incoming v signal from the heart 00143 void vsignal_irq() 00144 { 00145 osSignalSet(signalTid, 0x2); 00146 } 00147 00148 00149 // Timer-driven function to pace the Atria 00150 void a_pace(void const*) 00151 { 00152 Apace = 1; 00153 aClock.reset(); 00154 apace_timer->stop(); 00155 toggleLed(3); 00156 Apace = 0; 00157 osSignalSet(signalTid, 0x3); 00158 } 00159 00160 // Timer-driven function to pace the ventricle 00161 void v_pace(void const*) 00162 { 00163 Vpace = 1; 00164 vClock.reset(); 00165 vpace_timer->start(LRI); 00166 apace_timer->start(LRI-AVI); 00167 toggleLed(4); 00168 Vpace = 0; 00169 osSignalSet(signalTid, 0x4); 00170 heart_beats++; 00171 } 00172 00173 00174 00175 void PaceSignal(void const *args) 00176 { 00177 int pFlag1 = 0; 00178 int pFlag2 = 0; 00179 vClock.start(); 00180 aClock.start(); 00181 vpace_timer->start(LRI); 00182 apace_timer->start(LRI-AVI); 00183 00184 while(1) { 00185 while (!pFlag1) { 00186 osEvent ext_signal = osSignalWait(0, osWaitForever); 00187 int evt = ext_signal.value.signals; 00188 00189 //lcd.printf("%d",evt); // 4(Vpace), 3(Apace), 2(Vsignal), 1(Asignal) 00190 00191 if (evt == 0x1 && vClock.read_ms() >= PVARP) { //aSignal 00192 osSignalSet(senseTid, 0x1); 00193 //pc2.printf("%s%d%s","as ", vClock.read_ms(), "\n"); 00194 aClock.reset(); 00195 apace_timer->stop(); 00196 int interval = (vClock.read_ms() + AVI >= URI) ? AVI : URI - vClock.read_ms(); 00197 vpace_timer->start(interval); 00198 pFlag1 = 1; 00199 } else if(evt == 0x2 && vClock.read_ms() >= VRP) { //vSignal 00200 osSignalSet(senseTid, 0x2); 00201 //pc2.printf("%s%d%s","vs ", vClock.read_ms(), "\n"); 00202 vClock.reset(); 00203 vpace_timer->start(LRI); 00204 apace_timer->start(LRI-AVI); 00205 } else if (evt == 0x3) { //aPace 00206 pFlag1 = 1; 00207 } 00208 } 00209 pFlag1 = 0; 00210 00211 while(!pFlag2) { 00212 osEvent ext_signal = osSignalWait(0, osWaitForever); 00213 int evt = ext_signal.value.signals; 00214 00215 if (evt == 0x1 && aClock.read_ms() >= ARP) { //aSignal 00216 osSignalSet(senseTid, 0x1); 00217 //pc2.printf("%s%d%s","as ", vClock.read_ms(), "\n"); 00218 aClock.reset(); 00219 } else if(evt == 0x2) { //vSignal 00220 osSignalSet(senseTid, 0x2); 00221 //pc2.printf("%s%d%s","vs ", vClock.read_ms(), "\n"); 00222 vClock.reset(); 00223 apace_timer->start(LRI-AVI); 00224 vpace_timer->start(LRI); 00225 pFlag2 = 1; 00226 } else if (evt == 0x4) { //vPace 00227 pFlag2 = 1; 00228 } 00229 } 00230 pFlag2 = 0; 00231 } 00232 } 00233 00234 00235 void PaceSense(void const *args) 00236 { 00237 int pFlag1 = 0; 00238 int pFlag2 = 0; 00239 while(1) { 00240 while (!pFlag1) { 00241 osEvent ext_signal = osSignalWait(0, osWaitForever); 00242 int evt = ext_signal.value.signals; 00243 00244 //lcd.printf("%d",evt); 00245 00246 if (evt == 0x1) { //aSense 00247 toggleLed(evt); 00248 pFlag1 = 1; 00249 } else if(evt == 0x2) { //vSense 00250 toggleLed(evt); 00251 heart_beats++; 00252 } else if (evt == 0x3) { //aPace 00253 pFlag1 = 1; 00254 } 00255 00256 } 00257 pFlag1 = 0; 00258 while(!pFlag2) { 00259 osEvent ext_signal = osSignalWait(0, osWaitForever); 00260 int evt = ext_signal.value.signals; 00261 00262 //lcd.printf("%d",evt); // 4096, 256, 16, 1 00263 00264 if (evt == 0x1) { //aSense 00265 toggleLed(evt); 00266 } else if(evt == 0x2) { //vSignal 00267 toggleLed(evt); 00268 heart_beats++; 00269 pFlag2 = 1; 00270 } else if (evt == 0x4) { //vPace 00271 pFlag2 = 1; 00272 } 00273 } 00274 pFlag2 = 0; 00275 } 00276 } 00277 00278 osThreadDef(PaceSignal, osPriorityNormal, DEFAULT_STACK_SIZE); 00279 osThreadDef(PaceSense, osPriorityNormal, DEFAULT_STACK_SIZE); 00280 osThreadDef(displayThread, osPriorityNormal, DEFAULT_STACK_SIZE); 00281 00282 int main() 00283 { 00284 senseTid = osThreadCreate(osThread(PaceSense), NULL); 00285 signalTid = osThreadCreate(osThread(PaceSignal), NULL); 00286 displayTid = osThreadCreate(osThread(displayThread), NULL); 00287 00288 vsignal.rise(&vsignal_irq); //rising edge of timer 00289 asignal.rise(&asignal_irq); 00290 00291 Callback<void()> apaceTimerTask((void*)NULL, (void (*)(void*))&a_pace); 00292 Callback<void()> vpaceTimerTask((void*)NULL, (void (*)(void*))&v_pace); 00293 apace_timer = new RtosTimer(apaceTimerTask); 00294 vpace_timer = new RtosTimer(vpaceTimerTask); 00295 00296 lcd.cls(); 00297 00298 00299 // 'n' for normal mode (default) 00300 // 's' for sleep mode 00301 // 'e' for exercise mode 00302 // 'm' for manual mode 00303 // 'o' to change the observation interval 00304 00305 key = 'n'; 00306 00307 while(true) { 00308 Thread::wait(100); 00309 while(pc.readable()) { 00310 key = pc.getc(); 00311 switch(key) { 00312 //pvarp = 0.3s 00313 case('n'): 00314 mode = 'n'; 00315 upperBound = 100; //beats per msecond 00316 lowerBound = 40; //beats per msecond 00317 //lcd.printf("N"); 00318 initialize_intervals(); 00319 break; 00320 case('s'): 00321 mode = 's'; 00322 upperBound = 60; //beats per msecond 00323 lowerBound = 30; //beats per msecond v-v 0.5s 00324 //lcd.printf("S"); 00325 ratio = (60.00/100.00 + 30.00/40.00) / 2.00; 00326 initialize_intervals(); 00327 LRI /= ratio; 00328 URI /= ratio; 00329 VRP /= ratio; 00330 ARP /= ratio; 00331 AVI /= ratio; 00332 PVARP /= ratio; 00333 // lcd.printf("%lf", LRI); 00334 break; 00335 case('e'): 00336 mode = 'e'; 00337 upperBound = 175; //beats per msecond 00338 lowerBound = 100; //beats per msecond 00339 //lcd.printf("E"); 00340 ratio = (175.00/100.00 + 100.00/40.00) / 2.00; 00341 initialize_intervals(); 00342 LRI /= ratio; 00343 URI /= ratio; 00344 VRP /= ratio; 00345 ARP /= ratio; 00346 AVI /= ratio; 00347 PVARP /= ratio; 00348 // lcd.printf("%lf", LRI); 00349 break; 00350 case('m'): 00351 mode = 'm'; 00352 upperBound = 175; //beats per msecond 00353 lowerBound = 30; //beats per msecond 00354 //lcd.printf("M"); 00355 // LRI = 1000; 00356 // URI = 700; 00357 // PVARP = 300; 00358 manual_mode = 1; 00359 break; 00360 case('o'): 00361 isChangingObsInt = 1; 00362 //lcd.printf("O"); 00363 break; 00364 } 00365 ///////manual pacing 00366 if(manual_mode) { 00367 key = pc.getc(); 00368 if(key == 'v') { 00369 v_pace(NULL); 00370 } else if(key == 'a') { 00371 a_pace(NULL); 00372 } else if(key == 'q') { 00373 manual_mode = 0; 00374 } 00375 } 00376 00377 00378 00379 ///////observation interval 00380 int i = 0; 00381 while(isChangingObsInt) { 00382 // wait(1); 00383 key = pc.getc(); 00384 // lcd.printf("0"); 00385 if(key != '\r' && (int)key > 47 && (int)key < 58) { 00386 //use atoi - asci to integer to convert input key to 0 - 10 00387 newObsInt[i] = key; 00388 i++; 00389 //lcd.printf("1"); 00390 } else if(key == '\r') { 00391 newObsInt[i] = '\0'; 00392 int obsint; 00393 sscanf(newObsInt, "%d", &obsint); 00394 observation_interval = obsint; 00395 //lcd.printf("%d", observation_interval); 00396 isChangingObsInt = 0; 00397 } 00398 } 00399 } 00400 } 00401 00402 00403 }
Generated on Tue Aug 23 2022 01:12:22 by
1.7.2
