Eric Stahl / Mbed 2 deprecated pm_pacemaker

Dependencies:   TextLCD mbed-rtos mbed

Fork of pm_pacemaker by Phil Perilstein

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

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 }