
the complete model of the heart model
Dependencies: TextLCD mbed-rtos mbed
Fork of heart by
main.cpp@4:453a2f967f52, 2016-11-30 (annotated)
- Committer:
- shengtiz
- Date:
- Wed Nov 30 05:39:08 2016 +0000
- Revision:
- 4:453a2f967f52
- Parent:
- 3:5941bb3c4fc2
5th commit
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
williamrchr | 0:08412491e70f | 1 | #include "mbed.h" |
williamrchr | 0:08412491e70f | 2 | #include "rtos.h" |
williamrchr | 0:08412491e70f | 3 | #include "TextLCD.h" |
shengtiz | 1:6ad7b5bf9c27 | 4 | #include <time.h> |
shengtiz | 1:6ad7b5bf9c27 | 5 | #include <stdlib.h> |
williamrchr | 0:08412491e70f | 6 | |
shengtiz | 2:b4551e56cd1c | 7 | //use screen /dev/tty.. on mac in terminal to receive input |
shengtiz | 2:b4551e56cd1c | 8 | |
williamrchr | 0:08412491e70f | 9 | TextLCD lcd(p15,p16,p17,p18,p19,p20,TextLCD::LCD16x2); |
williamrchr | 0:08412491e70f | 10 | Serial pc(USBTX, USBRX); //set up serial |
williamrchr | 0:08412491e70f | 11 | DigitalOut natAPace(LED1); //leds for pacing |
williamrchr | 0:08412491e70f | 12 | DigitalOut natVPace(LED2); |
williamrchr | 0:08412491e70f | 13 | DigitalOut aPace(LED3); |
williamrchr | 0:08412491e70f | 14 | DigitalOut vPace(LED4); |
williamrchr | 0:08412491e70f | 15 | DigitalOut a_signal(p6); //connected to pm |
williamrchr | 0:08412491e70f | 16 | DigitalOut v_signal(p7); //connected to pm |
shengtiz | 4:453a2f967f52 | 17 | DigitalIn apace_signal(p8); //connected to pm |
shengtiz | 4:453a2f967f52 | 18 | DigitalIn vpace_signal(p9); //connected to pm |
shengtiz | 4:453a2f967f52 | 19 | |
shengtiz | 4:453a2f967f52 | 20 | Timer atimer; //timer for atrial event |
shengtiz | 4:453a2f967f52 | 21 | Timer vtimer; //timer for ventricular event |
williamrchr | 0:08412491e70f | 22 | |
williamrchr | 0:08412491e70f | 23 | unsigned int a_time = 0; |
williamrchr | 0:08412491e70f | 24 | unsigned int v_time = 0; |
williamrchr | 0:08412491e70f | 25 | |
williamrchr | 0:08412491e70f | 26 | int mode = 0; //0 = random, 1 = manual, 2 = test |
shengtiz | 2:b4551e56cd1c | 27 | int modeInManul = -1; //0 = manualmode apace, 1 = manualmode vpace |
shengtiz | 2:b4551e56cd1c | 28 | bool modeSwitch = false; |
williamrchr | 0:08412491e70f | 29 | |
shengtiz | 4:453a2f967f52 | 30 | //the following flags indicate pacing signals either from the heart or the pacemaker |
shengtiz | 4:453a2f967f52 | 31 | bool natural_apace = false; |
shengtiz | 4:453a2f967f52 | 32 | bool natural_vpace = false; |
shengtiz | 4:453a2f967f52 | 33 | bool apace = false; |
shengtiz | 4:453a2f967f52 | 34 | bool vpace = false; |
shengtiz | 2:b4551e56cd1c | 35 | |
shengtiz | 4:453a2f967f52 | 36 | //constants |
shengtiz | 4:453a2f967f52 | 37 | const int minwait_A = 100; //in miliseconds |
shengtiz | 4:453a2f967f52 | 38 | const int minwait_V = 200; //in miliseconds |
shengtiz | 2:b4551e56cd1c | 39 | /* |
shengtiz | 4:453a2f967f52 | 40 | //so far no use of the following in the heart model |
williamrchr | 0:08412491e70f | 41 | const int LRI = 1000; |
williamrchr | 0:08412491e70f | 42 | const int VRP = 400; |
williamrchr | 0:08412491e70f | 43 | const int PVARP = 500; |
williamrchr | 0:08412491e70f | 44 | const int URI = 1000; |
williamrchr | 0:08412491e70f | 45 | const int AVI = 100; |
shengtiz | 2:b4551e56cd1c | 46 | */ |
williamrchr | 0:08412491e70f | 47 | |
williamrchr | 0:08412491e70f | 48 | void switch_modes() { |
williamrchr | 0:08412491e70f | 49 | switch(mode) { |
williamrchr | 0:08412491e70f | 50 | case 0: |
williamrchr | 0:08412491e70f | 51 | break; |
williamrchr | 0:08412491e70f | 52 | case 1: |
williamrchr | 0:08412491e70f | 53 | break; |
williamrchr | 0:08412491e70f | 54 | case 2: |
williamrchr | 0:08412491e70f | 55 | break; |
williamrchr | 0:08412491e70f | 56 | |
williamrchr | 0:08412491e70f | 57 | } |
williamrchr | 0:08412491e70f | 58 | } |
williamrchr | 0:08412491e70f | 59 | |
williamrchr | 0:08412491e70f | 60 | void send_signal(int type) { //type=0 a_signal, type=1 v_signal |
williamrchr | 0:08412491e70f | 61 | |
williamrchr | 0:08412491e70f | 62 | switch(type) { |
williamrchr | 0:08412491e70f | 63 | case 0: |
williamrchr | 0:08412491e70f | 64 | a_signal = 1; |
williamrchr | 0:08412491e70f | 65 | case 1: |
williamrchr | 0:08412491e70f | 66 | v_signal = 1; |
williamrchr | 0:08412491e70f | 67 | } |
williamrchr | 0:08412491e70f | 68 | } |
williamrchr | 0:08412491e70f | 69 | |
shengtiz | 2:b4551e56cd1c | 70 | void modeSwitchDelay(){ |
shengtiz | 2:b4551e56cd1c | 71 | //srand(time(NULL)); |
shengtiz | 2:b4551e56cd1c | 72 | //int time = rand()%9700 + 300; |
shengtiz | 2:b4551e56cd1c | 73 | Thread::wait(1000); |
shengtiz | 2:b4551e56cd1c | 74 | } |
shengtiz | 2:b4551e56cd1c | 75 | |
williamrchr | 0:08412491e70f | 76 | void heart_keyboard() { |
williamrchr | 0:08412491e70f | 77 | while(true) { //thread is continuously running |
williamrchr | 0:08412491e70f | 78 | if(pc.readable()) { |
williamrchr | 0:08412491e70f | 79 | char c = pc.getc(); |
williamrchr | 0:08412491e70f | 80 | |
williamrchr | 0:08412491e70f | 81 | switch(c) { |
williamrchr | 0:08412491e70f | 82 | case 'r': //set to random mode |
williamrchr | 0:08412491e70f | 83 | mode = 0; |
shengtiz | 2:b4551e56cd1c | 84 | modeSwitch = true; |
williamrchr | 0:08412491e70f | 85 | break; |
shengtiz | 2:b4551e56cd1c | 86 | case 'm': //mset to manual mode |
williamrchr | 0:08412491e70f | 87 | mode = 1; |
shengtiz | 2:b4551e56cd1c | 88 | modeSwitch = true; |
williamrchr | 0:08412491e70f | 89 | break; |
williamrchr | 0:08412491e70f | 90 | case 't': //set to test mode |
williamrchr | 0:08412491e70f | 91 | mode = 2; |
shengtiz | 2:b4551e56cd1c | 92 | modeSwitch = true; |
williamrchr | 0:08412491e70f | 93 | break; |
williamrchr | 0:08412491e70f | 94 | case 'a': //asignal |
shengtiz | 2:b4551e56cd1c | 95 | if(mode == 1) { //only if in manual (heart_mode == 1) |
shengtiz | 2:b4551e56cd1c | 96 | modeInManul = 0; |
williamrchr | 0:08412491e70f | 97 | } |
williamrchr | 0:08412491e70f | 98 | break; |
williamrchr | 0:08412491e70f | 99 | case 'v': //vsignal |
shengtiz | 2:b4551e56cd1c | 100 | if(mode == 1) { //only if in manual (heart_mode == 1) |
shengtiz | 2:b4551e56cd1c | 101 | modeInManul = 1; |
williamrchr | 0:08412491e70f | 102 | } |
williamrchr | 0:08412491e70f | 103 | break; |
williamrchr | 0:08412491e70f | 104 | default: //erroneous key get rid of it |
williamrchr | 0:08412491e70f | 105 | break; |
williamrchr | 0:08412491e70f | 106 | } |
williamrchr | 0:08412491e70f | 107 | } |
williamrchr | 0:08412491e70f | 108 | } |
williamrchr | 0:08412491e70f | 109 | } |
williamrchr | 0:08412491e70f | 110 | |
williamrchr | 0:08412491e70f | 111 | void tick() { |
williamrchr | 0:08412491e70f | 112 | a_time++; |
williamrchr | 0:08412491e70f | 113 | v_time++; |
williamrchr | 0:08412491e70f | 114 | } |
shengtiz | 1:6ad7b5bf9c27 | 115 | // Blink functions gets called when there is an Atrial/V entricular event. |
shengtiz | 1:6ad7b5bf9c27 | 116 | void natApaceBlink(){ |
shengtiz | 1:6ad7b5bf9c27 | 117 | natAPace = 1; |
shengtiz | 4:453a2f967f52 | 118 | Thread::wait(50); |
shengtiz | 1:6ad7b5bf9c27 | 119 | natAPace = 0; |
shengtiz | 4:453a2f967f52 | 120 | Thread::wait(50); |
shengtiz | 1:6ad7b5bf9c27 | 121 | } |
shengtiz | 1:6ad7b5bf9c27 | 122 | |
shengtiz | 1:6ad7b5bf9c27 | 123 | void natVpaceBlink(){ |
shengtiz | 1:6ad7b5bf9c27 | 124 | natVPace = 1; |
shengtiz | 4:453a2f967f52 | 125 | Thread::wait(50); |
shengtiz | 1:6ad7b5bf9c27 | 126 | natVPace = 0; |
shengtiz | 4:453a2f967f52 | 127 | Thread::wait(50); |
shengtiz | 1:6ad7b5bf9c27 | 128 | } |
shengtiz | 1:6ad7b5bf9c27 | 129 | |
shengtiz | 1:6ad7b5bf9c27 | 130 | void ApaceBlink(){ |
shengtiz | 1:6ad7b5bf9c27 | 131 | aPace = 1; |
shengtiz | 4:453a2f967f52 | 132 | Thread::wait(50); |
shengtiz | 1:6ad7b5bf9c27 | 133 | aPace = 0; |
shengtiz | 4:453a2f967f52 | 134 | Thread::wait(50); |
shengtiz | 1:6ad7b5bf9c27 | 135 | } |
shengtiz | 1:6ad7b5bf9c27 | 136 | |
shengtiz | 1:6ad7b5bf9c27 | 137 | void VpaceBlink(){ |
shengtiz | 1:6ad7b5bf9c27 | 138 | vPace = 1; |
shengtiz | 4:453a2f967f52 | 139 | Thread::wait(50); |
shengtiz | 1:6ad7b5bf9c27 | 140 | vPace = 0; |
shengtiz | 4:453a2f967f52 | 141 | Thread::wait(50); |
shengtiz | 1:6ad7b5bf9c27 | 142 | } |
shengtiz | 1:6ad7b5bf9c27 | 143 | |
shengtiz | 2:b4551e56cd1c | 144 | void performModeDelay(){ |
shengtiz | 2:b4551e56cd1c | 145 | if(modeSwitch == true){ |
shengtiz | 2:b4551e56cd1c | 146 | modeSwitchDelay(); |
shengtiz | 2:b4551e56cd1c | 147 | modeSwitch = false; |
shengtiz | 2:b4551e56cd1c | 148 | } |
shengtiz | 2:b4551e56cd1c | 149 | } |
shengtiz | 2:b4551e56cd1c | 150 | |
shengtiz | 4:453a2f967f52 | 151 | //generate the time the next atrial event will happen |
shengtiz | 4:453a2f967f52 | 152 | int Atrial_generate(){ |
shengtiz | 4:453a2f967f52 | 153 | srand(time(NULL)); |
shengtiz | 4:453a2f967f52 | 154 | return rand()%2000 + minwait_A; |
shengtiz | 4:453a2f967f52 | 155 | } |
shengtiz | 4:453a2f967f52 | 156 | |
shengtiz | 4:453a2f967f52 | 157 | //generate the time the next ventricular event will happen. |
shengtiz | 4:453a2f967f52 | 158 | int Ventricular_generate(){ |
shengtiz | 4:453a2f967f52 | 159 | srand(time(NULL)); |
shengtiz | 4:453a2f967f52 | 160 | return rand()%2000 + minwait_V; |
shengtiz | 4:453a2f967f52 | 161 | } |
shengtiz | 4:453a2f967f52 | 162 | |
shengtiz | 3:5941bb3c4fc2 | 163 | //The following two modules random_sensing and random_pacing are two components of the random mode. |
shengtiz | 3:5941bb3c4fc2 | 164 | void random_sensing(){ |
shengtiz | 4:453a2f967f52 | 165 | int aTime = 0; //the time that the next atrial event will happen, |
shengtiz | 4:453a2f967f52 | 166 | //if the time exceeds the expected limit, then it will be regarded as heart malfunction |
shengtiz | 4:453a2f967f52 | 167 | //and the signal from the pacemaker will take effect. |
shengtiz | 4:453a2f967f52 | 168 | int vTime = 0; //the time that the next ventricular event will happen, |
shengtiz | 4:453a2f967f52 | 169 | //if the time exceeds the expected limit, then it will be regarded as heart malfunction |
shengtiz | 4:453a2f967f52 | 170 | //and the signal from the pacemaker will take effect. |
shengtiz | 2:b4551e56cd1c | 171 | while(1){ |
shengtiz | 2:b4551e56cd1c | 172 | if(mode == 0){ |
shengtiz | 2:b4551e56cd1c | 173 | performModeDelay(); |
shengtiz | 4:453a2f967f52 | 174 | //use random functions to generate the sensing signals. |
shengtiz | 4:453a2f967f52 | 175 | //asense time generate |
shengtiz | 4:453a2f967f52 | 176 | //detect if there is an apace signal from the pacemaker, if there is, reset asense clock |
shengtiz | 4:453a2f967f52 | 177 | //otherwise natural apace |
shengtiz | 4:453a2f967f52 | 178 | //and go into vsense. |
shengtiz | 4:453a2f967f52 | 179 | aTime = Atrial_generate(); |
shengtiz | 4:453a2f967f52 | 180 | atimer.start(); |
shengtiz | 4:453a2f967f52 | 181 | while(1){ |
shengtiz | 4:453a2f967f52 | 182 | //the case when the hearth functions correctly |
shengtiz | 4:453a2f967f52 | 183 | //this condition means the moment when vtimer passes aTime, the limit, and we still |
shengtiz | 4:453a2f967f52 | 184 | // did not receive apace_signal, then, it means the heart is working correctly. |
shengtiz | 4:453a2f967f52 | 185 | if(atimer.read_ms() >= aTime && !apace_signal){ |
shengtiz | 4:453a2f967f52 | 186 | atimer.stop(); |
shengtiz | 4:453a2f967f52 | 187 | atimer.reset(); |
shengtiz | 4:453a2f967f52 | 188 | send_signal(0); |
shengtiz | 4:453a2f967f52 | 189 | natural_apace = true; |
shengtiz | 4:453a2f967f52 | 190 | break; |
shengtiz | 4:453a2f967f52 | 191 | } |
shengtiz | 4:453a2f967f52 | 192 | |
shengtiz | 4:453a2f967f52 | 193 | //the case when the heart malfunctions in the Atrial |
shengtiz | 4:453a2f967f52 | 194 | if((atimer.read_ms () <= aTime) && apace_signal){ |
shengtiz | 4:453a2f967f52 | 195 | atimer.stop(); |
shengtiz | 4:453a2f967f52 | 196 | atimer.reset(); |
shengtiz | 4:453a2f967f52 | 197 | apace = true; |
shengtiz | 4:453a2f967f52 | 198 | break; |
shengtiz | 4:453a2f967f52 | 199 | } |
shengtiz | 4:453a2f967f52 | 200 | } |
shengtiz | 4:453a2f967f52 | 201 | |
shengtiz | 4:453a2f967f52 | 202 | //detect if there is a vpace signal from the pacemaker, if there is, reset the vsense clock. |
shengtiz | 4:453a2f967f52 | 203 | //otherwise natural vpace |
shengtiz | 4:453a2f967f52 | 204 | vTime = Ventricular_generate(); |
shengtiz | 4:453a2f967f52 | 205 | vtimer.start(); |
shengtiz | 4:453a2f967f52 | 206 | while(1){ |
shengtiz | 4:453a2f967f52 | 207 | //the case when the hearth functions correctly |
shengtiz | 4:453a2f967f52 | 208 | //this condition means the moment when vtimer passes vTime, the limit, and we still |
shengtiz | 4:453a2f967f52 | 209 | // did not receive vpace_signal, then, it means the heart is working correctly. |
shengtiz | 4:453a2f967f52 | 210 | if(vtimer.read_ms() >= vTime && !vpace_signal){ |
shengtiz | 4:453a2f967f52 | 211 | vtimer.stop(); |
shengtiz | 4:453a2f967f52 | 212 | vtimer.reset(); |
shengtiz | 4:453a2f967f52 | 213 | send_signal(1); |
shengtiz | 4:453a2f967f52 | 214 | natural_vpace = true; |
shengtiz | 4:453a2f967f52 | 215 | break; |
shengtiz | 4:453a2f967f52 | 216 | } |
shengtiz | 4:453a2f967f52 | 217 | |
shengtiz | 4:453a2f967f52 | 218 | //the case when the heart malfunctions in the Atrial |
shengtiz | 4:453a2f967f52 | 219 | if((vtimer.read_ms () <= vTime) && vpace_signal){ |
shengtiz | 4:453a2f967f52 | 220 | vtimer.stop(); |
shengtiz | 4:453a2f967f52 | 221 | vtimer.reset(); |
shengtiz | 4:453a2f967f52 | 222 | vpace = true; |
shengtiz | 4:453a2f967f52 | 223 | break; |
shengtiz | 4:453a2f967f52 | 224 | } |
shengtiz | 4:453a2f967f52 | 225 | } |
shengtiz | 3:5941bb3c4fc2 | 226 | } |
shengtiz | 3:5941bb3c4fc2 | 227 | } |
shengtiz | 3:5941bb3c4fc2 | 228 | } |
shengtiz | 3:5941bb3c4fc2 | 229 | |
shengtiz | 3:5941bb3c4fc2 | 230 | void random_pacing(){ |
shengtiz | 3:5941bb3c4fc2 | 231 | while(1){ |
shengtiz | 3:5941bb3c4fc2 | 232 | if(mode == 0){ |
shengtiz | 3:5941bb3c4fc2 | 233 | performModeDelay(); |
shengtiz | 4:453a2f967f52 | 234 | if(natural_apace){ |
shengtiz | 4:453a2f967f52 | 235 | natApaceBlink(); |
shengtiz | 4:453a2f967f52 | 236 | natural_apace = false; |
shengtiz | 4:453a2f967f52 | 237 | } |
shengtiz | 4:453a2f967f52 | 238 | |
shengtiz | 4:453a2f967f52 | 239 | if(natural_vpace){ |
shengtiz | 4:453a2f967f52 | 240 | natVpaceBlink(); |
shengtiz | 4:453a2f967f52 | 241 | natural_vpace = false; |
shengtiz | 4:453a2f967f52 | 242 | } |
shengtiz | 4:453a2f967f52 | 243 | |
shengtiz | 4:453a2f967f52 | 244 | if(apace){ |
shengtiz | 4:453a2f967f52 | 245 | ApaceBlink(); |
shengtiz | 4:453a2f967f52 | 246 | apace = false; |
shengtiz | 4:453a2f967f52 | 247 | } |
shengtiz | 4:453a2f967f52 | 248 | |
shengtiz | 4:453a2f967f52 | 249 | if(vpace){ |
shengtiz | 4:453a2f967f52 | 250 | VpaceBlink(); |
shengtiz | 4:453a2f967f52 | 251 | vpace = false; |
shengtiz | 4:453a2f967f52 | 252 | } |
shengtiz | 3:5941bb3c4fc2 | 253 | } |
shengtiz | 1:6ad7b5bf9c27 | 254 | } |
shengtiz | 1:6ad7b5bf9c27 | 255 | } |
shengtiz | 1:6ad7b5bf9c27 | 256 | |
shengtiz | 3:5941bb3c4fc2 | 257 | |
shengtiz | 3:5941bb3c4fc2 | 258 | //Heart Modes: Random, Manual, Test |
shengtiz | 3:5941bb3c4fc2 | 259 | void Random(){ |
shengtiz | 3:5941bb3c4fc2 | 260 | //TODO: heart behaviour in random mode |
shengtiz | 3:5941bb3c4fc2 | 261 | Thread s(random_sensing); |
shengtiz | 3:5941bb3c4fc2 | 262 | Thread p(random_pacing); |
shengtiz | 3:5941bb3c4fc2 | 263 | while(1); |
shengtiz | 3:5941bb3c4fc2 | 264 | } |
shengtiz | 3:5941bb3c4fc2 | 265 | |
shengtiz | 1:6ad7b5bf9c27 | 266 | void Manual(){ |
shengtiz | 1:6ad7b5bf9c27 | 267 | //TODO: heart behaviour in manual mode |
shengtiz | 2:b4551e56cd1c | 268 | while(1){ |
shengtiz | 2:b4551e56cd1c | 269 | if(mode == 1){ |
shengtiz | 2:b4551e56cd1c | 270 | performModeDelay(); |
shengtiz | 2:b4551e56cd1c | 271 | //natVpaceBlink(); |
shengtiz | 2:b4551e56cd1c | 272 | if(modeInManul == 0){ |
shengtiz | 2:b4551e56cd1c | 273 | ApaceBlink(); |
shengtiz | 2:b4551e56cd1c | 274 | modeInManul = -1; |
shengtiz | 2:b4551e56cd1c | 275 | } |
shengtiz | 2:b4551e56cd1c | 276 | |
shengtiz | 2:b4551e56cd1c | 277 | if(modeInManul == 1){ |
shengtiz | 2:b4551e56cd1c | 278 | VpaceBlink(); |
shengtiz | 2:b4551e56cd1c | 279 | modeInManul = -1; |
shengtiz | 2:b4551e56cd1c | 280 | } |
shengtiz | 2:b4551e56cd1c | 281 | } |
shengtiz | 1:6ad7b5bf9c27 | 282 | } |
shengtiz | 1:6ad7b5bf9c27 | 283 | } |
shengtiz | 1:6ad7b5bf9c27 | 284 | |
shengtiz | 1:6ad7b5bf9c27 | 285 | void Test(){ |
shengtiz | 1:6ad7b5bf9c27 | 286 | //TODO: heart behaviour in test mode |
shengtiz | 2:b4551e56cd1c | 287 | while(1){ |
shengtiz | 2:b4551e56cd1c | 288 | if(mode == 2){ |
shengtiz | 2:b4551e56cd1c | 289 | performModeDelay(); |
shengtiz | 2:b4551e56cd1c | 290 | //ApaceBlink(); |
shengtiz | 2:b4551e56cd1c | 291 | } |
shengtiz | 1:6ad7b5bf9c27 | 292 | } |
shengtiz | 1:6ad7b5bf9c27 | 293 | } |
shengtiz | 1:6ad7b5bf9c27 | 294 | |
williamrchr | 0:08412491e70f | 295 | int main() { |
williamrchr | 0:08412491e70f | 296 | //TODO: Set up threads |
shengtiz | 1:6ad7b5bf9c27 | 297 | Thread keyboard(heart_keyboard); |
shengtiz | 1:6ad7b5bf9c27 | 298 | //Note: only one of the following threads will be on duty when heart runs |
shengtiz | 1:6ad7b5bf9c27 | 299 | //and it is done through checking the mode the heart is in. |
shengtiz | 2:b4551e56cd1c | 300 | Thread random_(Random); |
shengtiz | 2:b4551e56cd1c | 301 | Thread manual_(Manual); |
shengtiz | 2:b4551e56cd1c | 302 | Thread test_(Test); |
shengtiz | 2:b4551e56cd1c | 303 | while(1); |
williamrchr | 0:08412491e70f | 304 | } |