Part of the Pacemaker Project; this models the Pacemaker.

Dependencies:   mbed TextLCD mbed-rtos

Committer:
chadnach1
Date:
Wed Dec 02 00:37:37 2015 +0000
Revision:
27:2c5aefcf3000
Parent:
24:81cd9ef5c4f6
Child:
29:5cec671cb80d
Fixed bugs in PacemakerController.cpp, but still won't compile?

Who changed what in which revision?

UserRevisionLine numberNew contents of line
chadnach1 0:d92e0b71c6b5 1 #include "mbed.h"
lucastai 2:5e9c4d83d038 2 #include "LPC17xx.h"
lucastai 2:5e9c4d83d038 3 #include "TextLCD.h"
lucastai 2:5e9c4d83d038 4 #include "rtos.h"
lucastai 2:5e9c4d83d038 5 #include "Thread.h"
lucastai 2:5e9c4d83d038 6 using namespace rtos;
chadnach1 0:d92e0b71c6b5 7
amiche 19:f3615321b5c4 8
chadnach1 0:d92e0b71c6b5 9 // This is for the pacemaker
lucastai 2:5e9c4d83d038 10 volatile unsigned short timer_count;
lucastai 2:5e9c4d83d038 11 Serial pc(USBTX, USBRX);
lucastai 2:5e9c4d83d038 12 TextLCD lcd(p15, p16, p17, p18, p19, p20, TextLCD::LCD20x4); // rs, e, d4-d7
lucastai 2:5e9c4d83d038 13
mhowar 5:9eee15818b0e 14 int keyboard_needs_numeric = 0; // boolean - is in middle of interval input?
chadnach1 0:d92e0b71c6b5 15
chadnach1 0:d92e0b71c6b5 16 int h_clock;
amiche 3:44d132582373 17 int pm_clock;
chadnach1 27:2c5aefcf3000 18 Timer avi_clk;
chadnach1 0:d92e0b71c6b5 19
chadnach1 4:f04eb7f96f4b 20 int LRI = 1000;
chadnach1 4:f04eb7f96f4b 21 int AVI = 150;
chadnach1 4:f04eb7f96f4b 22 int PVARP = 300;
chadnach1 4:f04eb7f96f4b 23 int VRP = 200;
lucastai 2:5e9c4d83d038 24
lucastai 2:5e9c4d83d038 25 // constants
lucastai 2:5e9c4d83d038 26 int MAX_PM_RT = 180;
lucastai 2:5e9c4d83d038 27 int MIN_PM_RT = 40;
lucastai 2:5e9c4d83d038 28 enum mode {NORMAL, SLEEP, EXERCISE, MANUAL};
lucastai 2:5e9c4d83d038 29
lucastai 2:5e9c4d83d038 30 // counters
lucastai 2:5e9c4d83d038 31 int beats = 0;
lucastai 2:5e9c4d83d038 32
lucastai 2:5e9c4d83d038 33 // state variables
lucastai 2:5e9c4d83d038 34 int upper_bound = 100;
lucastai 2:5e9c4d83d038 35 int lower_bound = 40;
lucastai 2:5e9c4d83d038 36 int obs_int = 10;
lucastai 2:5e9c4d83d038 37 mode curr_mode = NORMAL;
lucastai 2:5e9c4d83d038 38
amiche 19:f3615321b5c4 39 // alarms
lucastai 14:a16b636c2bbc 40 DigitalOut led_apace(LED1);
lucastai 14:a16b636c2bbc 41 DigitalOut led_vpace(LED2);
lucastai 2:5e9c4d83d038 42 DigitalOut Asense(LED3);
lucastai 2:5e9c4d83d038 43 DigitalOut Vsense(LED4);
lucastai 2:5e9c4d83d038 44
chadnach1 27:2c5aefcf3000 45 DigitalIn agetSignal(p24);
chadnach1 27:2c5aefcf3000 46 DigitalIn vgetSignal(p23);
chadnach1 27:2c5aefcf3000 47 DigitalOut apaceSignal(p22);
chadnach1 27:2c5aefcf3000 48 DigitalOut vpaceSignal(p21);
chadnach1 27:2c5aefcf3000 49
chadnach1 27:2c5aefcf3000 50 bool v_sense;
chadnach1 27:2c5aefcf3000 51 bool a_sense;
chadnach1 27:2c5aefcf3000 52
chadnach1 27:2c5aefcf3000 53 void asense()
chadnach1 27:2c5aefcf3000 54 {
chadnach1 27:2c5aefcf3000 55 a_sense = 1;
chadnach1 27:2c5aefcf3000 56 Thread::wait(10);
chadnach1 27:2c5aefcf3000 57 a_sense = 0;
chadnach1 27:2c5aefcf3000 58 }
lucastai 18:d4cd9d12345e 59
chadnach1 27:2c5aefcf3000 60 void vsense()
chadnach1 27:2c5aefcf3000 61 {
chadnach1 27:2c5aefcf3000 62 v_sense = 1;
chadnach1 27:2c5aefcf3000 63 Thread::wait(10);
chadnach1 27:2c5aefcf3000 64 v_sense = 0;
chadnach1 27:2c5aefcf3000 65 }
chadnach1 27:2c5aefcf3000 66
chadnach1 27:2c5aefcf3000 67 void apace()
chadnach1 27:2c5aefcf3000 68 {
chadnach1 27:2c5aefcf3000 69
chadnach1 27:2c5aefcf3000 70 apaceSignal = 1;
chadnach1 27:2c5aefcf3000 71 led_apace = 1;
chadnach1 27:2c5aefcf3000 72 Thread::wait(10);
chadnach1 27:2c5aefcf3000 73 apaceSignal = 0;
chadnach1 27:2c5aefcf3000 74
chadnach1 27:2c5aefcf3000 75 }
chadnach1 27:2c5aefcf3000 76
chadnach1 27:2c5aefcf3000 77 void vpace()
chadnach1 27:2c5aefcf3000 78 {
chadnach1 27:2c5aefcf3000 79
chadnach1 27:2c5aefcf3000 80 vpaceSignal = 1;
chadnach1 27:2c5aefcf3000 81 led_vpace = 1;
chadnach1 27:2c5aefcf3000 82 Thread::wait(10);
chadnach1 27:2c5aefcf3000 83 vpaceSignal = 0;
chadnach1 27:2c5aefcf3000 84
chadnach1 27:2c5aefcf3000 85 }
amiche 24:81cd9ef5c4f6 86
lucastai 2:5e9c4d83d038 87 // hardware interrupt handler, adapted from code in piazza post by Dagaen
amiche 24:81cd9ef5c4f6 88 extern "C" void TIMER0_IRQHandler (void)
lucastai 2:5e9c4d83d038 89 {
amiche 19:f3615321b5c4 90 if((LPC_TIM0->IR & 0x01) == 0x01) { // if MR0 interrupt, proceed
amiche 19:f3615321b5c4 91 LPC_TIM0->IR |= 1 << 0; // Clear MR0 interrupt flag
amiche 19:f3615321b5c4 92 timer_count++; //increment timer_count
lucastai 2:5e9c4d83d038 93 }
lucastai 2:5e9c4d83d038 94 }
amiche 19:f3615321b5c4 95
lucastai 2:5e9c4d83d038 96 // init the hardware interrupt (timer0), adapted same as above
lucastai 2:5e9c4d83d038 97 void timer0_init(void)
lucastai 2:5e9c4d83d038 98 {
lucastai 2:5e9c4d83d038 99 LPC_SC->PCONP |=1<1; //timer0 power on
lucastai 2:5e9c4d83d038 100 LPC_SC-> PCLKSEL0 |= 1 << 2; // set timer clock to CCLCK nondivided (1 clock cycle = 1 increment)
lucastai 2:5e9c4d83d038 101 LPC_TIM0->MR0 = 1000000; //100mhz clock cycle, 1 cycle = 10ns, 10ms = 10 000 000 ns = 1M cycles
lucastai 2:5e9c4d83d038 102 LPC_TIM0->MCR = 3; //interrupt and reset control
amiche 19:f3615321b5c4 103 //3 = Interrupt & reset timer0 on match (111) sets all three bits
lucastai 2:5e9c4d83d038 104 NVIC_EnableIRQ(TIMER0_IRQn); //enable timer0 interrupt
chadnach1 0:d92e0b71c6b5 105 }
chadnach1 0:d92e0b71c6b5 106
lucastai 2:5e9c4d83d038 107
chadnach1 27:2c5aefcf3000 108 void PM_ALARM(void const *args)
amiche 19:f3615321b5c4 109 {
amiche 19:f3615321b5c4 110
lucastai 2:5e9c4d83d038 111 // min hr alarm
amiche 19:f3615321b5c4 112 if( beats < MIN_PM_RT) {
lucastai 2:5e9c4d83d038 113 lcd.locate(0,1);
amiche 19:f3615321b5c4 114 lcd.printf("!<");
lucastai 2:5e9c4d83d038 115 }
amiche 19:f3615321b5c4 116
lucastai 2:5e9c4d83d038 117 // max hr alarm
amiche 19:f3615321b5c4 118 if(beats > MAX_PM_RT) {
lucastai 2:5e9c4d83d038 119 lcd.locate(0,1);
amiche 19:f3615321b5c4 120 lcd.printf("!>");
amiche 19:f3615321b5c4 121 }
amiche 19:f3615321b5c4 122
chadnach1 0:d92e0b71c6b5 123 }
chadnach1 0:d92e0b71c6b5 124
lucastai 2:5e9c4d83d038 125 // hw interrupt callback, deal with the keyboard input from PC
amiche 19:f3615321b5c4 126 void keyboard_handler()
amiche 19:f3615321b5c4 127 {
amiche 19:f3615321b5c4 128
lucastai 2:5e9c4d83d038 129 // get the char, put it on the PC command line
lucastai 2:5e9c4d83d038 130 char a = pc.getc();
lucastai 2:5e9c4d83d038 131
mhowar 5:9eee15818b0e 132 if (keyboard_needs_numeric) {
mhowar 5:9eee15818b0e 133 if (a >= '0' && a <= '9') {
mhowar 5:9eee15818b0e 134 // update observation interval
mhowar 9:fd8477284185 135 obs_int = (a - '0' + 1) * 5;
mhowar 5:9eee15818b0e 136 } else {
amiche 19:f3615321b5c4 137 pc.printf("Expected numeric key\n");
mhowar 5:9eee15818b0e 138 }
amiche 19:f3615321b5c4 139 } else if(a == 'N') {
mhowar 5:9eee15818b0e 140 // if the char is N, update bounds to normal mode
lucastai 2:5e9c4d83d038 141 curr_mode = NORMAL;
lucastai 2:5e9c4d83d038 142 upper_bound = 100;
lucastai 2:5e9c4d83d038 143 lower_bound = 40;
amiche 19:f3615321b5c4 144 pc.printf("MODE IS N\n");
amiche 19:f3615321b5c4 145 // if the char is S, set bounds to sleep
amiche 19:f3615321b5c4 146 } else if (a == 'S') {
lucastai 2:5e9c4d83d038 147 curr_mode = SLEEP;
lucastai 2:5e9c4d83d038 148 upper_bound = 60;
lucastai 2:5e9c4d83d038 149 lower_bound = 30;
amiche 19:f3615321b5c4 150 pc.printf("MODE IS S\n");
amiche 19:f3615321b5c4 151 // if the char is E, set bounds to exercise
amiche 19:f3615321b5c4 152 } else if (a == 'E') {
lucastai 2:5e9c4d83d038 153 curr_mode = EXERCISE;
lucastai 2:5e9c4d83d038 154 upper_bound = 175;
lucastai 2:5e9c4d83d038 155 lower_bound = 100;
amiche 19:f3615321b5c4 156 pc.printf("MODE IS E\n");
lucastai 2:5e9c4d83d038 157 beats = 2;
amiche 19:f3615321b5c4 158 // if the char is M, set to manual
amiche 19:f3615321b5c4 159 } else if (a == 'M') {
lucastai 2:5e9c4d83d038 160 curr_mode = MANUAL;
lucastai 2:5e9c4d83d038 161 upper_bound = 175;
lucastai 2:5e9c4d83d038 162 lower_bound = 30;
lucastai 2:5e9c4d83d038 163 beats = 300;
amiche 19:f3615321b5c4 164 pc.printf("MODE IS MANUAL\n");
amiche 19:f3615321b5c4 165 // check for A if mode is manual
amiche 19:f3615321b5c4 166 } else if (a == 'A') {
amiche 19:f3615321b5c4 167 if(curr_mode == MANUAL) {
amiche 19:f3615321b5c4 168 pc.printf("MODE IS MANUAL GOT APACE\n");
lucastai 2:5e9c4d83d038 169 }
amiche 19:f3615321b5c4 170 // check for V is mode is manual
amiche 19:f3615321b5c4 171 } else if (a == 'V') {
amiche 19:f3615321b5c4 172 if(curr_mode == MANUAL) {
amiche 19:f3615321b5c4 173 pc.printf("MODE IS MANUAL GOT VPACE\n");
amiche 19:f3615321b5c4 174 }
amiche 19:f3615321b5c4 175 } else if (a == 'O') {
mhowar 5:9eee15818b0e 176 keyboard_needs_numeric = 1;
amiche 19:f3615321b5c4 177 } else {
lucastai 2:5e9c4d83d038 178 // do nothing for invalid char
lucastai 2:5e9c4d83d038 179 }
amiche 19:f3615321b5c4 180
lucastai 2:5e9c4d83d038 181 }
lucastai 2:5e9c4d83d038 182
chadnach1 27:2c5aefcf3000 183 void pm_sense(void const *args)
amiche 19:f3615321b5c4 184 {
amiche 19:f3615321b5c4 185
chadnach1 4:f04eb7f96f4b 186 while(1) {
amiche 19:f3615321b5c4 187
chadnach1 27:2c5aefcf3000 188 if (timer_count >= VRP && vgetSignal == 1) {
amiche 24:81cd9ef5c4f6 189 // Valid_V state
amiche 24:81cd9ef5c4f6 190
amiche 19:f3615321b5c4 191 timer_count = 0;
amiche 24:81cd9ef5c4f6 192 vsense();
amiche 19:f3615321b5c4 193 // do something with Vsense!
amiche 24:81cd9ef5c4f6 194
chadnach1 27:2c5aefcf3000 195 } else if (timer_count < VRP && vgetSignal == 1) {
chadnach1 20:dc272bfaa276 196 // Invalid_V state
chadnach1 4:f04eb7f96f4b 197 }
amiche 19:f3615321b5c4 198
chadnach1 27:2c5aefcf3000 199 if (timer_count < PVARP && agetSignal == 1) {
chadnach1 20:dc272bfaa276 200 // Invalid_A state
chadnach1 27:2c5aefcf3000 201 } else if (timer_count >= PVARP && agetSignal == 1) {
chadnach1 20:dc272bfaa276 202 // Valid_A state
amiche 24:81cd9ef5c4f6 203 asense();
chadnach1 4:f04eb7f96f4b 204 // do something with Asense!
chadnach1 4:f04eb7f96f4b 205 }
amiche 19:f3615321b5c4 206
chadnach1 4:f04eb7f96f4b 207 }
amiche 3:44d132582373 208 }
amiche 3:44d132582373 209
chadnach1 27:2c5aefcf3000 210 void pm_response(void const *args)
amiche 19:f3615321b5c4 211 {
chadnach1 4:f04eb7f96f4b 212 while(1) {
chadnach1 27:2c5aefcf3000 213 bool goInitalState = 1;
amiche 19:f3615321b5c4 214 if (timer_count >= LRI-AVI) {
chadnach1 27:2c5aefcf3000 215 goInitalState = 0;
amiche 19:f3615321b5c4 216 // PM_A! sets the LED high
amiche 19:f3615321b5c4 217 led_apace = 1;
amiche 19:f3615321b5c4 218
amiche 19:f3615321b5c4 219 // avi_clk = 0
amiche 19:f3615321b5c4 220 avi_clk.reset();
amiche 19:f3615321b5c4 221
amiche 19:f3615321b5c4 222 apace();
amiche 19:f3615321b5c4 223 // At Atrial Event State
amiche 24:81cd9ef5c4f6 224 while (avi_clk.read() < AVI) {
chadnach1 27:2c5aefcf3000 225 if (v_sense == 1) {
chadnach1 27:2c5aefcf3000 226 goInitalState = 1;
amiche 24:81cd9ef5c4f6 227 break;
amiche 24:81cd9ef5c4f6 228 }
amiche 24:81cd9ef5c4f6 229 }
chadnach1 27:2c5aefcf3000 230 if (!goInitalState) {
amiche 24:81cd9ef5c4f6 231 // Ventricular Event
amiche 24:81cd9ef5c4f6 232 timer_count = 0;
amiche 19:f3615321b5c4 233
amiche 24:81cd9ef5c4f6 234 // PM_V! sets the LED high
amiche 24:81cd9ef5c4f6 235 led_vpace = 1;
amiche 19:f3615321b5c4 236
amiche 24:81cd9ef5c4f6 237 timer_count = 0;
amiche 24:81cd9ef5c4f6 238 vpace();
amiche 24:81cd9ef5c4f6 239 }
amiche 19:f3615321b5c4 240 } else if (timer_count < LRI - AVI) {
amiche 24:81cd9ef5c4f6 241 // if Asense, move on to atrial event
chadnach1 27:2c5aefcf3000 242 if (a_sense == 1) {
chadnach1 27:2c5aefcf3000 243 goInitalState = 0;
chadnach1 27:2c5aefcf3000 244
amiche 24:81cd9ef5c4f6 245 // avi_clk = 0
amiche 24:81cd9ef5c4f6 246 avi_clk.reset();
amiche 19:f3615321b5c4 247
amiche 24:81cd9ef5c4f6 248 // At Atrial Event State
amiche 24:81cd9ef5c4f6 249 while (avi_clk.read() < AVI) {
chadnach1 27:2c5aefcf3000 250 if (v_sense == 1) {
chadnach1 27:2c5aefcf3000 251 goInitalState = 1;
amiche 24:81cd9ef5c4f6 252 break;
amiche 24:81cd9ef5c4f6 253 }
amiche 24:81cd9ef5c4f6 254 }
amiche 19:f3615321b5c4 255
amiche 24:81cd9ef5c4f6 256 // Ventricular Event
amiche 24:81cd9ef5c4f6 257 timer_count = 0;
amiche 24:81cd9ef5c4f6 258
amiche 24:81cd9ef5c4f6 259 // PM_V! sets the LED high
amiche 24:81cd9ef5c4f6 260 led_vpace = 1;
amiche 24:81cd9ef5c4f6 261
amiche 24:81cd9ef5c4f6 262 timer_count = 0;
amiche 24:81cd9ef5c4f6 263 vpace();
amiche 24:81cd9ef5c4f6 264 }
amiche 19:f3615321b5c4 265 }
amiche 19:f3615321b5c4 266 }
amiche 3:44d132582373 267 }
lucastai 2:5e9c4d83d038 268
amiche 19:f3615321b5c4 269 int main()
amiche 19:f3615321b5c4 270 {
chadnach1 16:ae9df4194011 271 // https://developer.mbed.org/users/chadnach1/code/PacemakerController/
lucastai 2:5e9c4d83d038 272 // connect the serial device (PC keybd) to the interrupt
mhowar 5:9eee15818b0e 273 pc.attach(&keyboard_handler);
amiche 19:f3615321b5c4 274
chadnach1 16:ae9df4194011 275 // Start LED's Off
chadnach1 17:c89cddf30925 276 led_apace = 0;
chadnach1 17:c89cddf30925 277 led_vpace = 0;
amiche 19:f3615321b5c4 278
chadnach1 16:ae9df4194011 279 // Start the avi_clock
chadnach1 16:ae9df4194011 280 avi_clk.start();
amiche 19:f3615321b5c4 281
chadnach1 27:2c5aefcf3000 282 Thread t2(PM_ALARM);
amiche 3:44d132582373 283 Thread t3(pm_sense);
amiche 3:44d132582373 284 Thread t4(pm_response);
chadnach1 17:c89cddf30925 285 }