Lucas Tai-MacArthur / Mbed 2 deprecated PMController

Dependencies:   TextLCD mbed-rtos mbed

Fork of PacemakerController by Chad Nachiappan

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers PacemakerController.cpp Source File

PacemakerController.cpp

00001 #include "mbed.h"
00002 #include "LPC17xx.h"
00003 #include "TextLCD.h"
00004 #include "rtos.h"
00005 #include "Thread.h"
00006 using namespace rtos;
00007 
00008 // This is for the pacemaker
00009 volatile unsigned short timer_count;
00010 Serial pc(USBTX, USBRX);
00011 TextLCD lcd(p15, p16, p17, p18, p19, p20, TextLCD::LCD20x4); // rs, e, d4-d7
00012 
00013 Ticker rate_monitor;
00014 // counters
00015 volatile int beats = 0;
00016 volatile double bpm = 0;
00017 int keyboard_needs_numeric = 0; // boolean - is in middle of interval input?
00018 
00019 int h_clock;
00020 int pm_clock;
00021 Timer avi_clk;
00022 Timer sense_clk;
00023 Timer pulse_clk;
00024 
00025 int LRI = 1000;
00026 int AVI = 300;
00027 int PVARP = 150;
00028 int VRP = 100;
00029 
00030 // constants
00031 int MAX_PM_RT = 180;
00032 int MIN_PM_RT = 40;
00033 enum mode {NORMAL, SLEEP, EXERCISE, MANUAL};
00034 
00035 // state variables
00036 int upper_bound = 100;
00037 int lower_bound = 40;
00038 int obs_int = 10;
00039 mode curr_mode = NORMAL;
00040 
00041 // alarms
00042 DigitalOut led_apace(LED1);
00043 DigitalOut led_vpace(LED2);
00044 DigitalOut led_asense(LED3);
00045 DigitalOut led_vsense(LED4);
00046 
00047 DigitalIn  agetSignal(p24);
00048 DigitalIn  vgetSignal(p23);
00049 DigitalOut apaceSignal(p22);
00050 DigitalOut vpaceSignal(p21);
00051 
00052 bool v_sense;
00053 bool a_sense;
00054 
00055 void asense()
00056 {
00057     a_sense = 1;
00058     led_asense = 1;
00059     Thread::wait(10);
00060     led_asense = 0;
00061     a_sense = 0;
00062 }
00063 
00064 void vsense()
00065 {
00066     v_sense = 1;
00067     led_vsense = 1;
00068     Thread::wait(10);
00069     led_vsense = 0;
00070     v_sense = 0;
00071 }
00072 
00073 void apace()
00074 {
00075     apaceSignal = 1;
00076     led_apace = 1;
00077     Thread::wait(10);
00078     led_apace = 0;
00079     apaceSignal = 0;
00080 
00081 }
00082 
00083 void vpace()
00084 {
00085     vpaceSignal = 1;
00086     led_vpace = 1;
00087     Thread::wait(10);
00088     led_vpace = 0;
00089     vpaceSignal = 0;
00090 
00091 }
00092 
00093 void PM_ALARM(void const *args)
00094 {
00095     while (1) {
00096         // min hr alarm
00097         if( bpm < lower_bound) {
00098             lcd.locate(0,1);
00099             lcd.printf("!<");
00100             pc.printf("BPM low: %.1f   ", bpm);
00101         }
00102 
00103         // max hr alarm
00104         else if(beats > upper_bound) {
00105             lcd.locate(0,1);
00106             lcd.printf("!>");
00107             pc.printf("BPM high: %.1f   ", bpm);
00108         } else {
00109             lcd.locate(0,1);
00110             lcd.printf("  ");
00111            
00112         }
00113         
00114         lcd.locate(0,0);
00115         lcd.printf("BPM: %.1f   ", bpm);
00116     }
00117 }
00118 
00119 // hw interrupt callback, deal with the keyboard input from PC
00120 
00121 void pm_sense(void const *args)
00122 {
00123 
00124     while(1) {       
00125 
00126         if (sense_clk.read_ms() >= VRP && vgetSignal == 1) {
00127             
00128             // Valid_V state
00129             sense_clk.reset();
00130             vsense();
00131 
00132         } else if (sense_clk.read_ms() < VRP  && vgetSignal == 1) {
00133             // Invalid_V state
00134         }
00135 
00136         if (sense_clk.read_ms() < PVARP && agetSignal == 1) {
00137             // Invalid_A state
00138             
00139         } else if (sense_clk.read_ms() >= PVARP && agetSignal == 1) {
00140             // Valid_A state
00141             asense();
00142         }
00143     }
00144 }
00145 
00146 void pm_response(void const *args)
00147 {
00148     while(1) {
00149 
00150         bool goInitialState = 1;
00151         if (pulse_clk.read_ms() >= LRI - AVI) {
00152             
00153             goInitialState = 0;
00154             
00155             avi_clk.reset();
00156 
00157             // PM_A! sets the LED high
00158             apace();
00159             
00160             // At Atrial Event State
00161             while (avi_clk.read_ms() < AVI) {
00162 
00163                 if (v_sense == 1) {
00164                     beats++;
00165                     //sensed valid ventricular event
00166                     goInitialState = 1;
00167                     pulse_clk.reset();
00168                     break;
00169                 }
00170             }
00171             if (!goInitialState) {
00172                 // Ventricular Event
00173                 pulse_clk.reset();
00174                 sense_clk.reset();
00175                 
00176                 // PM_V! sets the LED high
00177                 beats++;
00178                 vpace();
00179             }
00180         } else if (pulse_clk.read_ms() < LRI - AVI) {
00181 
00182             // if Asense, move on to atrial event
00183             if (a_sense == 1) {
00184                 goInitialState = 0;
00185                 
00186                 avi_clk.reset();
00187 
00188                 // At Atrial Event State
00189                 while (avi_clk.read() < AVI) {
00190                     if (v_sense == 1) {
00191                         beats++;
00192                         pulse_clk.reset();
00193                         goInitialState = 1;
00194                         break;
00195                     }
00196                 }
00197                 if (!goInitialState) {
00198                     // Ventricular Event
00199                     beats++;
00200                     sense_clk.reset();
00201                     pulse_clk.reset();
00202     
00203                     vpace();
00204                 }
00205             }
00206         }
00207     }
00208 }
00209 
00210 /* Every observation interval, calculate beats per minute and display
00211  *
00212  */
00213 void update_display() {
00214     bpm = beats / (double) obs_int * 60;
00215     //reset count
00216     beats = 0;
00217 }
00218 
00219 int main()
00220 {
00221     // https://developer.mbed.org/users/chadnach1/code/PacemakerController/
00222     // connect the serial device (PC keybd) to the interrupt
00223 
00224     // Start LED's Off
00225     led_apace = 0;
00226     led_vpace = 0;
00227 
00228     // Start the avi_clock
00229     avi_clk.start();
00230     avi_clk.reset();
00231 
00232     Thread t1(pm_sense, (void *)"");
00233     Thread t2(pm_response, (void *)"");
00234     Thread t3(PM_ALARM, (void *)"");
00235     sense_clk.start();
00236     pulse_clk.start();
00237     
00238     //update_display
00239     rate_monitor.attach(&update_display, obs_int);
00240     
00241     while(1) {
00242         if (pc.readable()) {
00243     
00244             char a = pc.getc();
00245     
00246             // Handle different keyboard inputs
00247             if (keyboard_needs_numeric) {
00248                 if (a >= '0' && a <= '9') {
00249                     // update observation interval
00250                     obs_int = (a - '0' + 1) * 5;
00251                     keyboard_needs_numeric = 0;
00252                     rate_monitor.attach(&update_display, obs_int);
00253                     pc.printf("Set observation interval to %d seconds\n", obs_int);
00254                 } else {
00255                     pc.printf("Expected numeric key\n");
00256                 }
00257             }  else if(a == 'N') {
00258                 // if the char is N, update bounds to normal mode
00259                 curr_mode = NORMAL;
00260                 upper_bound = 100;
00261                 LRI = 600;
00262                 lower_bound = 40;
00263                 pc.printf("MODE IS N\n");
00264                 // if the char is S, set bounds to sleep
00265             } else if (a == 'S') {
00266                 curr_mode = SLEEP;
00267                 upper_bound = 60;
00268                 LRI = 1000;
00269                 lower_bound = 30;
00270                 pc.printf("MODE IS S\n");
00271                 // if the char is E, set bounds to exercise
00272             } else if (a == 'E') {
00273                 curr_mode = EXERCISE;
00274                 upper_bound = 175;
00275                 LRI = 343;
00276                 lower_bound = 100;
00277                 pc.printf("MODE IS E\n");
00278                 // if the char is M, set to manual
00279             } else if (a == 'M') {
00280                 curr_mode = MANUAL;
00281                 upper_bound = 175;
00282                 LRI = 1750;
00283                 lower_bound = 30;
00284                 pc.printf("MODE IS MANUAL\n");
00285                 // check for A if mode is manual
00286             } else if (a == 'A') {
00287                 if(curr_mode == MANUAL) {
00288                     pc.printf("MODE IS MANUAL SENT APACE\n");
00289                     apace();
00290                 }
00291                 // check for V is mode is manual
00292             } else if (a == 'V') {
00293                 if(curr_mode == MANUAL) {
00294                     pc.printf("MODE IS MANUAL SENT VPACE\n");
00295                     vpace();
00296                 }
00297             } else if (a == 'O') {
00298                 keyboard_needs_numeric = 1;
00299             } else {
00300                 // do nothing for invalid char
00301             }
00302         }
00303     }
00304 }