Part of the Pacemaker Project; this models the Pacemaker.

Dependencies:   mbed TextLCD mbed-rtos

Committer:
lucastai
Date:
Mon Nov 30 21:47:20 2015 +0000
Revision:
23:08456978fb78
testing random heart;

Who changed what in which revision?

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