fork the master

Dependencies:   TextLCD mbed-rtos mbed

Fork of Pacemaker by pacemaker team

Committer:
mfrede
Date:
Mon Dec 01 23:36:53 2014 +0000
Revision:
14:94f1b9e3eb43
Parent:
13:0a430559b488
Child:
15:4cd550c14f97
Child:
16:a1c97cd207eb
fixed observation interval

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mfrede 0:6d04b1860ecf 1 /*
mfrede 0:6d04b1860ecf 2 * Pacemaker MBED code
mfrede 0:6d04b1860ecf 3 *
mfrede 0:6d04b1860ecf 4 * CIS541 Embedded Systems for Life Critical Applications
mfrede 8:ce2565cfe709 5 * Author: Jing Qiu
mfrede 8:ce2565cfe709 6 * Michael Frederick
mfrede 0:6d04b1860ecf 7 *
mfrede 1:e37d0cad77e2 8 */
Jing_Qiu 3:34e9766539fe 9
mfrede 1:e37d0cad77e2 10 #include "mbed.h"
mfrede 1:e37d0cad77e2 11 #include "LPC17xx.h"
mfrede 1:e37d0cad77e2 12 #include "TextLCD.h"
mfrede 1:e37d0cad77e2 13 #include "rtos.h"
mfrede 11:dd278ffcb31f 14 #include <ctype.h>
mfrede 1:e37d0cad77e2 15
Jing_Qiu 3:34e9766539fe 16 #define AVI_h 100
Jing_Qiu 3:34e9766539fe 17 #define AVI_l 30
Jing_Qiu 3:34e9766539fe 18 #define PVARP_h 500
Jing_Qiu 3:34e9766539fe 19 #define PVARP_l 150
Jing_Qiu 3:34e9766539fe 20
Jing_Qiu 3:34e9766539fe 21 #define VRP_h 500
Jing_Qiu 3:34e9766539fe 22 #define VRP_l 150
Jing_Qiu 3:34e9766539fe 23 #define BM(x) (1<<(x))
Jing_Qiu 3:34e9766539fe 24 #define PULSE_WIDTH_V 200
Jing_Qiu 3:34e9766539fe 25 #define PULSE_WIDTH_A 100
Jing_Qiu 3:34e9766539fe 26
Jing_Qiu 5:376358077dc8 27
Jing_Qiu 3:34e9766539fe 28 int LRI_h = 1666;
Jing_Qiu 3:34e9766539fe 29 int LRI_l = 666;
Jing_Qiu 5:376358077dc8 30 int observation_interval=10000; //ms
mfrede 8:ce2565cfe709 31 bool setObservation = false;
Jing_Qiu 3:34e9766539fe 32
mfrede 1:e37d0cad77e2 33 Serial pc(USBTX, USBRX);
mfrede 1:e37d0cad77e2 34 TextLCD myPanel(p15,p16,p17,p18,p19,p20,TextLCD::LCD16x2);
mfrede 1:e37d0cad77e2 35 char mode = 'N';
Jing_Qiu 3:34e9766539fe 36
mfrede 1:e37d0cad77e2 37 int a_clock;
mfrede 1:e37d0cad77e2 38 int v_clock;
mfrede 6:6bc5e65ada4e 39 bool setobservation = false;
mfrede 1:e37d0cad77e2 40
Jing_Qiu 5:376358077dc8 41 int beat;
Jing_Qiu 5:376358077dc8 42
Jing_Qiu 3:34e9766539fe 43 InterruptIn atrial_int(p17);
Jing_Qiu 3:34e9766539fe 44 InterruptIn vent_int(p18);
Jing_Qiu 3:34e9766539fe 45
Jing_Qiu 3:34e9766539fe 46 const int a_pace = 5; //pin 21 a pace output
Jing_Qiu 3:34e9766539fe 47 const int v_pace = 3; //pin 23 v pace output
Jing_Qiu 3:34e9766539fe 48
Jing_Qiu 3:34e9766539fe 49 bool aSensed = 0; // 0 means that we are expecting Apace or Asense next
Jing_Qiu 5:376358077dc8 50 DigitalOut led1(LED1); //apace
Jing_Qiu 5:376358077dc8 51 DigitalOut led2(LED2); //vpace
Jing_Qiu 5:376358077dc8 52 DigitalOut led3(LED3); //asense
Jing_Qiu 5:376358077dc8 53 DigitalOut led4(LED4); //vsense
Jing_Qiu 3:34e9766539fe 54
Jing_Qiu 3:34e9766539fe 55 void initTimer();
Jing_Qiu 3:34e9766539fe 56 void startTimer();
Jing_Qiu 3:34e9766539fe 57 void initGPIO_outputs();
Jing_Qiu 3:34e9766539fe 58 void setGPIO(const int pinName);
Jing_Qiu 3:34e9766539fe 59 void clearGPIO(const int pinName);
Jing_Qiu 3:34e9766539fe 60
Jing_Qiu 3:34e9766539fe 61 void asense();
Jing_Qiu 3:34e9766539fe 62 void vsense();
Jing_Qiu 3:34e9766539fe 63
Jing_Qiu 3:34e9766539fe 64 void apace();
Jing_Qiu 3:34e9766539fe 65 void vpace();
Jing_Qiu 3:34e9766539fe 66
Jing_Qiu 3:34e9766539fe 67
Jing_Qiu 3:34e9766539fe 68 void apace()
Jing_Qiu 3:34e9766539fe 69 {
Jing_Qiu 5:376358077dc8 70 led1 = 1;
Jing_Qiu 3:34e9766539fe 71 setGPIO(a_pace);
Jing_Qiu 3:34e9766539fe 72 wait_us(PULSE_WIDTH_A);
Jing_Qiu 5:376358077dc8 73 clearGPIO(a_pace);
mfrede 8:ce2565cfe709 74 led1 = 0;
mfrede 13:0a430559b488 75 beat++;
Jing_Qiu 5:376358077dc8 76
Jing_Qiu 3:34e9766539fe 77 }
Jing_Qiu 3:34e9766539fe 78
Jing_Qiu 3:34e9766539fe 79 void vpace()
Jing_Qiu 3:34e9766539fe 80 {
Jing_Qiu 5:376358077dc8 81 led2= 1;
Jing_Qiu 3:34e9766539fe 82 setGPIO(v_pace);
Jing_Qiu 3:34e9766539fe 83 wait_us(PULSE_WIDTH_V);
Jing_Qiu 3:34e9766539fe 84 clearGPIO(v_pace);
Jing_Qiu 5:376358077dc8 85 led2 = 0;
Jing_Qiu 3:34e9766539fe 86 }
Jing_Qiu 3:34e9766539fe 87
Jing_Qiu 3:34e9766539fe 88 void initGPIO_outputs()
Jing_Qiu 3:34e9766539fe 89 {
Jing_Qiu 3:34e9766539fe 90 LPC_SC->PCONP |= 1<<15;
Jing_Qiu 3:34e9766539fe 91 LPC_GPIO2->FIODIR |= 1<<5;
Jing_Qiu 3:34e9766539fe 92 LPC_GPIO2->FIODIR |= 1<<3;
Jing_Qiu 3:34e9766539fe 93 LPC_GPIO2->FIODIR &= ~(1<<1);
Jing_Qiu 3:34e9766539fe 94 LPC_GPIO2->FIODIR &= ~(1<<2);
Jing_Qiu 3:34e9766539fe 95 }
Jing_Qiu 3:34e9766539fe 96
Jing_Qiu 3:34e9766539fe 97 void setGPIO(const int pinName)
Jing_Qiu 3:34e9766539fe 98 {
Jing_Qiu 3:34e9766539fe 99 LPC_GPIO2->FIOPIN |= (1<<pinName);
Jing_Qiu 3:34e9766539fe 100 }
Jing_Qiu 3:34e9766539fe 101
Jing_Qiu 3:34e9766539fe 102 void clearGPIO(const int pinName)
Jing_Qiu 3:34e9766539fe 103 {
Jing_Qiu 3:34e9766539fe 104 LPC_GPIO2->FIOPIN &= ~(1<<pinName);
Jing_Qiu 3:34e9766539fe 105 }
Jing_Qiu 3:34e9766539fe 106
Jing_Qiu 3:34e9766539fe 107 void initTimer()
Jing_Qiu 3:34e9766539fe 108 {
Jing_Qiu 3:34e9766539fe 109 // set up OS timer (timer0)
Jing_Qiu 3:34e9766539fe 110 LPC_SC->PCONP |= BM(1); //power up timer0
Jing_Qiu 3:34e9766539fe 111 LPC_SC->PCLKSEL0 |= BM(2); // clock = CCLK (96 MHz)
Jing_Qiu 3:34e9766539fe 112 LPC_TIM0->PR = 48000; // set prescale to 48000 (2048 Hz timer)
Jing_Qiu 3:34e9766539fe 113 LPC_TIM0->MR0 = 1; // match0 compare value (32-bit)
Jing_Qiu 3:34e9766539fe 114 LPC_TIM0->MCR |= BM(0)|BM(1); // interrupt and reset on match0 compare
Jing_Qiu 3:34e9766539fe 115 NVIC_EnableIRQ(TIMER0_IRQn); // enable timer interrupt
Jing_Qiu 3:34e9766539fe 116 }
Jing_Qiu 3:34e9766539fe 117
Jing_Qiu 3:34e9766539fe 118 void startTimer()
Jing_Qiu 3:34e9766539fe 119 {
Jing_Qiu 3:34e9766539fe 120 LPC_TIM0->TCR |= BM(1); // reset timer1
Jing_Qiu 3:34e9766539fe 121 LPC_TIM0->TCR &= ~BM(1); // release reset
Jing_Qiu 3:34e9766539fe 122 LPC_TIM0->TCR |= BM(0); // start timer
Jing_Qiu 3:34e9766539fe 123 }
Jing_Qiu 3:34e9766539fe 124
Jing_Qiu 3:34e9766539fe 125 void resetTimer()
Jing_Qiu 3:34e9766539fe 126 {
Jing_Qiu 3:34e9766539fe 127 LPC_TIM0->TCR |= BM(1); // reset timer0
Jing_Qiu 3:34e9766539fe 128 LPC_TIM0->TCR &= ~BM(1); // release reset
Jing_Qiu 3:34e9766539fe 129 }
Jing_Qiu 3:34e9766539fe 130
Jing_Qiu 3:34e9766539fe 131
Jing_Qiu 3:34e9766539fe 132
mfrede 1:e37d0cad77e2 133 void display_thread_handler(void const *args)
mfrede 1:e37d0cad77e2 134 {
mfrede 1:e37d0cad77e2 135 while(1)
mfrede 1:e37d0cad77e2 136 {
Jing_Qiu 5:376358077dc8 137 wait_ms(observation_interval);
mfrede 13:0a430559b488 138 printf("BPM: %d\r\n",beat*60000/observation_interval);
mfrede 14:94f1b9e3eb43 139 myPanel.printf("BPM: %d\n\n",beat*60000/observation_interval);
Jing_Qiu 5:376358077dc8 140 beat=0;
mfrede 1:e37d0cad77e2 141 }
mfrede 1:e37d0cad77e2 142 }
mfrede 1:e37d0cad77e2 143
mfrede 1:e37d0cad77e2 144
mfrede 1:e37d0cad77e2 145 void asense() {
Jing_Qiu 3:34e9766539fe 146 if (v_clock >= VRP_l) { //Ignore vSense outside this time interval
Jing_Qiu 3:34e9766539fe 147 v_clock = 0;
Jing_Qiu 3:34e9766539fe 148 aSensed = 0;
Jing_Qiu 3:34e9766539fe 149 }
Jing_Qiu 5:376358077dc8 150 led3 = 1;
Jing_Qiu 5:376358077dc8 151
mfrede 1:e37d0cad77e2 152 }
mfrede 1:e37d0cad77e2 153
mfrede 1:e37d0cad77e2 154 void vsense() {
Jing_Qiu 12:53c2af2009d4 155 if ((a_clock >= PVARP_l) && aSensed == 0){
Jing_Qiu 3:34e9766539fe 156 a_clock = 0;
Jing_Qiu 3:34e9766539fe 157 aSensed = 1;
Jing_Qiu 5:376358077dc8 158 beat++;
Jing_Qiu 3:34e9766539fe 159 }
Jing_Qiu 5:376358077dc8 160 led4 = 1;
mfrede 1:e37d0cad77e2 161 }
mfrede 1:e37d0cad77e2 162
mfrede 1:e37d0cad77e2 163 void button_handler(void const *args)
mfrede 1:e37d0cad77e2 164 {
mfrede 8:ce2565cfe709 165 int observation_temp=0;
mfrede 1:e37d0cad77e2 166 while(1)
mfrede 1:e37d0cad77e2 167 {
mfrede 1:e37d0cad77e2 168 char buffer;
mfrede 1:e37d0cad77e2 169 if(pc.readable()) {
mfrede 11:dd278ffcb31f 170 buffer = toupper(pc.getc());
mfrede 1:e37d0cad77e2 171 if (buffer == 'N')
mfrede 10:19a2ce5660ea 172 {
mfrede 1:e37d0cad77e2 173 mode = buffer;
mfrede 10:19a2ce5660ea 174 LRI_h = 1500;
mfrede 10:19a2ce5660ea 175 LRI_l = 600;
mfrede 10:19a2ce5660ea 176 }
mfrede 1:e37d0cad77e2 177 else if (buffer == 'S')
mfrede 10:19a2ce5660ea 178 {
mfrede 1:e37d0cad77e2 179 mode = buffer;
mfrede 10:19a2ce5660ea 180 LRI_h = 2000;
mfrede 10:19a2ce5660ea 181 LRI_l = 1000;
mfrede 10:19a2ce5660ea 182 }
mfrede 1:e37d0cad77e2 183 else if (buffer == 'E')
mfrede 10:19a2ce5660ea 184 {
mfrede 1:e37d0cad77e2 185 mode = buffer;
mfrede 10:19a2ce5660ea 186 LRI_h = 600;
mfrede 10:19a2ce5660ea 187 LRI_l = 342;
mfrede 10:19a2ce5660ea 188 }
mfrede 1:e37d0cad77e2 189 else if (buffer == 'M')
mfrede 10:19a2ce5660ea 190 {
mfrede 1:e37d0cad77e2 191 mode = buffer;
mfrede 10:19a2ce5660ea 192 LRI_h = 2000;
mfrede 10:19a2ce5660ea 193 LRI_l = 342;
mfrede 10:19a2ce5660ea 194 }
mfrede 1:e37d0cad77e2 195 else if (buffer == 'A' && mode == 'M')
mfrede 1:e37d0cad77e2 196 apace();
mfrede 1:e37d0cad77e2 197 else if (buffer == 'V' && mode == 'M')
mfrede 1:e37d0cad77e2 198 vpace();
mfrede 8:ce2565cfe709 199 else if (buffer == 'O') {
mfrede 8:ce2565cfe709 200 setObservation = true;
mfrede 8:ce2565cfe709 201 observation_temp = 0;
mfrede 8:ce2565cfe709 202 }
mfrede 14:94f1b9e3eb43 203 else if (buffer == 13 && setObservation) //newline
mfrede 6:6bc5e65ada4e 204 {
mfrede 8:ce2565cfe709 205 observation_interval = observation_temp*1000;
mfrede 8:ce2565cfe709 206 setObservation = false;
mfrede 14:94f1b9e3eb43 207 // printf("observation interval now: %d\r\n",observation_interval);
mfrede 6:6bc5e65ada4e 208 }
mfrede 8:ce2565cfe709 209 else if (setObservation)
mfrede 6:6bc5e65ada4e 210 {
mfrede 8:ce2565cfe709 211 observation_temp *= 10;
mfrede 14:94f1b9e3eb43 212 observation_temp += buffer-48;
mfrede 1:e37d0cad77e2 213
mfrede 6:6bc5e65ada4e 214 }
mfrede 1:e37d0cad77e2 215 }
mfrede 1:e37d0cad77e2 216 }
mfrede 1:e37d0cad77e2 217 }
mfrede 1:e37d0cad77e2 218
Jing_Qiu 3:34e9766539fe 219 void pacemaker_thread_handler(void const *args)
Jing_Qiu 3:34e9766539fe 220 {
Jing_Qiu 3:34e9766539fe 221 initGPIO_outputs();
Jing_Qiu 3:34e9766539fe 222
Jing_Qiu 3:34e9766539fe 223 /**********************************************************
Jing_Qiu 3:34e9766539fe 224 ************Initialize timer to interrupt every 1 ms*********
Jing_Qiu 3:34e9766539fe 225 ***********************************************************/
Jing_Qiu 3:34e9766539fe 226
Jing_Qiu 3:34e9766539fe 227 initTimer();
Jing_Qiu 3:34e9766539fe 228 startTimer();
Jing_Qiu 3:34e9766539fe 229
Jing_Qiu 3:34e9766539fe 230 atrial_int.rise(&asense);
Jing_Qiu 3:34e9766539fe 231 vent_int.rise(&vsense);
Jing_Qiu 3:34e9766539fe 232 while(1){}
Jing_Qiu 3:34e9766539fe 233
Jing_Qiu 3:34e9766539fe 234 }
Jing_Qiu 3:34e9766539fe 235
Jing_Qiu 3:34e9766539fe 236
Jing_Qiu 3:34e9766539fe 237 /**********************************************************
Jing_Qiu 3:34e9766539fe 238 ************ timer interrupt every 1 ms*********
Jing_Qiu 3:34e9766539fe 239 ***********************************************************/
Jing_Qiu 3:34e9766539fe 240
Jing_Qiu 3:34e9766539fe 241 extern "C" void TIMER0_IRQHandler (void) {
Jing_Qiu 3:34e9766539fe 242 if((LPC_TIM0->IR & 0x01) == 0x01) // if MR0 interrupt
Jing_Qiu 3:34e9766539fe 243 {
Jing_Qiu 3:34e9766539fe 244 LPC_TIM0->IR |= (1 << 0); // Clear MR0 interrupt flag
Jing_Qiu 3:34e9766539fe 245 if (v_clock >= (LRI_h-AVI_l) && aSensed == 0) {
Jing_Qiu 3:34e9766539fe 246 a_clock = 0;
Jing_Qiu 3:34e9766539fe 247 aSensed = 1;
Jing_Qiu 3:34e9766539fe 248 //printf("Apace %d\r\n",v_clk);
Jing_Qiu 3:34e9766539fe 249 apace();
Jing_Qiu 3:34e9766539fe 250 /*
Jing_Qiu 3:34e9766539fe 251 setGPIO(a_pace);
Jing_Qiu 3:34e9766539fe 252 wait_us(PULSE_WIDTH_A);
Jing_Qiu 3:34e9766539fe 253 clearGPIO(a_pace);
Jing_Qiu 3:34e9766539fe 254 */
Jing_Qiu 3:34e9766539fe 255 }
Jing_Qiu 3:34e9766539fe 256 if ((a_clock >= AVI_h) && aSensed == 1) {
Jing_Qiu 3:34e9766539fe 257 v_clock = 0;
Jing_Qiu 3:34e9766539fe 258 aSensed = 0;
Jing_Qiu 5:376358077dc8 259 //led3 = 0;
Jing_Qiu 3:34e9766539fe 260 //printf("Vpace %d\r\n",a_clk);
Jing_Qiu 3:34e9766539fe 261 /*
Jing_Qiu 3:34e9766539fe 262 setGPIO(v_pace);
Jing_Qiu 3:34e9766539fe 263 wait_us(PULSE_WIDTH_V);
Jing_Qiu 3:34e9766539fe 264 clearGPIO(v_pace);
Jing_Qiu 3:34e9766539fe 265 */
Jing_Qiu 3:34e9766539fe 266 vpace();
Jing_Qiu 3:34e9766539fe 267 }
Jing_Qiu 3:34e9766539fe 268 v_clock++;
Jing_Qiu 3:34e9766539fe 269 a_clock++;
Jing_Qiu 5:376358077dc8 270
Jing_Qiu 5:376358077dc8 271 if(v_clock>500) led3 = 0;
Jing_Qiu 5:376358077dc8 272 if(a_clock>500) led4 = 0;
Jing_Qiu 3:34e9766539fe 273 }
Jing_Qiu 3:34e9766539fe 274 }
mfrede 1:e37d0cad77e2 275
mfrede 1:e37d0cad77e2 276
Jing_Qiu 3:34e9766539fe 277 int main (void) {
Jing_Qiu 3:34e9766539fe 278 //TODO set parameters
Jing_Qiu 5:376358077dc8 279
Jing_Qiu 3:34e9766539fe 280
Jing_Qiu 3:34e9766539fe 281 Thread display(display_thread_handler);
Jing_Qiu 3:34e9766539fe 282 Thread keyboard(button_handler);
Jing_Qiu 3:34e9766539fe 283 Thread pacemaker(pacemaker_thread_handler);
Jing_Qiu 3:34e9766539fe 284
Jing_Qiu 3:34e9766539fe 285 while(1){}
Jing_Qiu 3:34e9766539fe 286
Jing_Qiu 3:34e9766539fe 287
mfrede 1:e37d0cad77e2 288 }