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 PacemakerController by
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 }
Generated on Tue Jul 26 2022 07:29:25 by
1.7.2
