yay!
Dependencies: TextLCD mbed-rtos mbed
Fork of 541_Pacermaker by
main.cpp
- Committer:
- adamvan101
- Date:
- 2015-12-02
- Revision:
- 1:d1c452f164d4
- Parent:
- 0:6c085ebcb2d5
- Child:
- 2:3d47bb081502
File content as of revision 1:d1c452f164d4:
#include "mbed.h" #include "rtos.h" //#include "TextLCD.h" #define NORMAL 1 #define EXERCISE 2 #define SLEEP 3 #define MANUAL 4 #define LRI_const 1 #define URI_const 2 #define AVI_const 3 #define VRP_const 4 #define PVAB_const 5 #define PVARP_const 6 DigitalOut vpaceLED(LED1); DigitalOut apaceLED(LED2); DigitalOut vsenseLED(LED3); DigitalOut asenseLED(LED4); DigitalOut buzzer(p9); DigitalOut aPace(p7); DigitalOut vPace(p8); InterruptIn ASignal(p5); InterruptIn VSignal(p6); Serial pc(USBTX, USBRX); int32_t signal1 = 0x01; int32_t signal2 = 0x02; int32_t signal3 = 0x03; int32_t signal4 = 0x04; bool waitASignal, waitVSignal, paceA, observationChange, digitOneReceived, modeChanged, canPaceV, paceVPending, ringAlarm, ringingAlarm, timerRunning, aSenseOccurred, digitTwoReceived; int heartRate, observationInterval, observationRate, waitCount, avgHeartRate, rateCoefficient, heartRateHeart, sec, avgHeartRateHeart; int paceMakerMode=1; //1 - Normal, 2 - Exercise, 3 - Sleep, 4 - Manual int uriTimeOutStatus=4; char ch; int timeConstraint; const int normalModeLRI= 1500; const int normalModeAVI = 65; const int normalModePVARP = 150; const int normalModeURI = 600; const int normalModeVRP = 100; const int normalModePVAB = 10; const int sleepModeLRI= 2000; const int sleepModeAVI = 65; const int sleepModePVARP = 150; const int sleepModeURI = 1000; const int sleepModeVRP = 100; const int sleepModePVAB = 10; const int exerciseModeLRI=1000; const int exerciseModeAVI = 65; const int exerciseModePVARP = 150; const int exerciseModeURI = 400; const int exerciseModeVRP = 100; const int exerciseModePVAB = 10; int LRI; int VRP; int PVARP; int AVI; int URI; int PVAB; Mutex displayMutex; Mutex observationChangeMutex; Mutex expectAMutex; Mutex expectVMutex; Mutex timeOutStatusMutex; Mutex heartRateMutex; Thread *SerialThreadPTR; Thread *PacePTR; Thread *ModeChangePTR; Thread *PMSensePTR; RtosTimer *TimeOutTimer; RtosTimer *URITimeOutTimer; RtosTimer *KeyTimeOutTimer; RtosTimer *SecondsTimer; void println(const char *c) { pc.printf(c); pc.printf("\r\n"); } void switchToNormal() { LRI = normalModeLRI; AVI = normalModeAVI; PVARP = normalModePVARP; URI = normalModeURI; VRP = normalModeVRP; PVAB = normalModePVAB; } void switchToExercise() { LRI = exerciseModeLRI; AVI = exerciseModeAVI; PVARP = exerciseModePVARP; URI = exerciseModeURI; VRP = exerciseModeVRP; PVAB = exerciseModePVAB; } void switchToSleep() { LRI = sleepModeLRI; AVI = sleepModeAVI; PVARP = sleepModePVARP; URI = sleepModeURI; VRP = sleepModeVRP; PVAB = sleepModePVAB; } void resetDisplay() { displayMutex.lock(); println("Pace Maker Display"); pc.printf("Heart Rate : %04d bpm\r\n", avgHeartRate); pc.printf("Observation Interval : %02d seconds\r\n", observationInterval/1000); pc.printf("Heart Beat Rate : %04d bpm\r\n", (heartRateHeart*(60/sec))); displayMutex.unlock(); ringingAlarm=false; } void updateDisplay() { displayMutex.lock(); pc.printf("%04d\r\n", avgHeartRate); pc.printf("%02d\r\n", observationInterval/1000); pc.printf("%04d\r\n", (heartRateHeart*(60/sec))); displayMutex.unlock(); } void changeMode() { switch(paceMakerMode) { default: case NORMAL: { switchToNormal(); break; } case EXERCISE: { switchToExercise(); break; } case SLEEP: { switchToSleep(); break; } case MANUAL: { break; } } modeChanged=false; resetDisplay(); } void modeChange(const void *args) { while(1) { Thread::signal_wait(signal3); if(modeChanged) { changeMode(); } } } void aSense() { if(waitASignal) { asenseLED=1; wait(0.001); println("ASense Received"); asenseLED=0; if(modeChanged) { (*ModeChangePTR).signal_set(signal3); } aSenseOccurred=true; (*PMSensePTR).signal_set(signal4); } } void vSense() { heartRateHeart++; if(waitVSignal) { vsenseLED=1; println("VSense Received"); wait(0.001); vsenseLED=0; if(modeChanged) { (*ModeChangePTR).signal_set(signal3); } canPaceV=false; aSenseOccurred=false; (*PMSensePTR).signal_set(signal4); } } void seconds(const void *args) { sec++; if(sec>=60) { avgHeartRateHeart=heartRateHeart; heartRateHeart=0; sec=0; } } void timeOut(const void *args) { // check which time out has occurred // generate appropriate pace signal // reset timer to new value //apaceLED=1; if(timeConstraint==AVI_const) { //generate VPace if(canPaceV) { paceA=false; (*PacePTR).signal_set(signal1); } else { canPaceV=true; } } else if(timeConstraint==PVAB_const) { expectVMutex.lock(); waitVSignal=true; expectVMutex.unlock(); timeOutStatusMutex.lock(); timeConstraint=AVI_const; timeOutStatusMutex.unlock(); timerRunning=true; TimeOutTimer->start(AVI-PVAB); } else if(timeConstraint==VRP_const) { //now we can sense a Ventrival event, but not an atrial event as PVARP is not over //restart timer for PVARP expectVMutex.lock(); waitVSignal=true; expectVMutex.unlock(); timeOutStatusMutex.lock(); timeConstraint=PVARP_const; timeOutStatusMutex.unlock(); timerRunning=true; TimeOutTimer->start(PVARP-VRP); } else if(timeConstraint==PVARP_const) { //now we can sense Atrial events as well expectAMutex.lock(); waitASignal=true; expectAMutex.unlock(); timeOutStatusMutex.lock(); timeConstraint=LRI_const; timeOutStatusMutex.unlock(); timerRunning=true; TimeOutTimer->start(LRI-PVARP-AVI); } else if(timeConstraint==LRI_const) { //generate APace paceA=true; (*PacePTR).signal_set(signal1); } } void uriTimeOut(const void *args) { // uri is over //check is a vpace has to be generated; If yes then generate the pace; else enable a flag that lets the thread generate the pace if(paceVPending || canPaceV) { //pace V as a pace occurred during URI paceA=false; paceVPending=false; (*PacePTR).signal_set(signal1); } else { canPaceV=true; //allow the PM to pace V as URI is now over } } void keyTimeOut(const void *args) { if(digitOneReceived) { observationChange=false; } else { observationChange=false; } resetDisplay(); } void pmSense(const void *args) { while(1) { Thread::signal_wait(signal4); if(timerRunning) { TimeOutTimer->stop(); timerRunning=false; } if(aSenseOccurred) { expectAMutex.lock(); waitASignal=false; expectAMutex.unlock(); expectVMutex.lock(); waitVSignal=true; expectVMutex.unlock(); timerRunning=true; timeOutStatusMutex.lock(); timeConstraint=AVI_const; timeOutStatusMutex.unlock(); TimeOutTimer->start(AVI);//500); } else { heartRateMutex.lock(); heartRate++; heartRateMutex.unlock(); expectVMutex.lock(); waitVSignal=false; expectVMutex.unlock(); expectAMutex.lock(); waitASignal=false; expectAMutex.unlock(); canPaceV=false; URITimeOutTimer->start(URI); timerRunning=true; timeOutStatusMutex.lock(); timeConstraint=VRP_const; timeOutStatusMutex.unlock(); TimeOutTimer->start(VRP); } } } void pace(const void *args) { while(1) { Thread::signal_wait(signal1); if(paceA) { println("APace Sent"); apaceLED=1; aPace=1; Thread::wait(1); aPace=0; apaceLED=0; if(modeChanged) { changeMode(); } // start AVI Timer expectAMutex.lock(); waitASignal=false; expectAMutex.unlock(); expectVMutex.lock(); waitVSignal=false; expectVMutex.unlock(); timeOutStatusMutex.lock(); timeConstraint=PVAB_const; timeOutStatusMutex.unlock(); timerRunning=true; TimeOutTimer->start(PVAB); //generate the APace pulse } else { println("VPace Sent"); vpaceLED=1; vPace=1; Thread::wait(1); vPace=0; vpaceLED=0; if(modeChanged) { changeMode(); } // start VRP and URI timers expectVMutex.lock(); waitVSignal=false; expectVMutex.unlock(); expectAMutex.lock(); waitASignal=false; expectAMutex.unlock(); heartRateMutex.lock(); heartRate++; heartRateMutex.unlock(); canPaceV=false; URITimeOutTimer->start(URI); timeOutStatusMutex.lock(); timeConstraint=VRP_const; timeOutStatusMutex.unlock(); timerRunning=true; TimeOutTimer->start(VRP); //generate the VPace pulse } } } void serialThread(const void *args) { while(1) { Thread::signal_wait(signal2); if((((ch=='a')||(ch=='A')) && paceMakerMode==MANUAL) && !observationChange) { //fire A Pace paceA=true; (*PacePTR).signal_set(signal1); } else if((((ch=='v')||(ch=='V')) && paceMakerMode==MANUAL) && !observationChange) { //fire V Pace if(canPaceV) { paceA=false; paceVPending=false; (*PacePTR).signal_set(signal1); } else { paceVPending=true; } } else if(((((ch=='n')||(ch=='N'))&& paceMakerMode!=NORMAL) && !observationChange) && !modeChanged) { paceMakerMode=NORMAL; modeChanged=true; } else if(((((ch=='e')||(ch=='E')) && paceMakerMode!=EXERCISE) && !observationChange) && !modeChanged) { paceMakerMode=EXERCISE; modeChanged=true; } else if(((((ch=='s')||(ch=='S')) && paceMakerMode!=SLEEP) && !observationChange) && !modeChanged) { paceMakerMode=SLEEP; modeChanged=true; } else if(((((ch=='b')||(ch=='B')) ) && !observationChange) ) { ringAlarm=!ringAlarm; } else if(((((ch=='m')||(ch=='M')) && paceMakerMode!=MANUAL) && !observationChange) && !modeChanged) { paceMakerMode=MANUAL; modeChanged=true; } else if(((((ch=='o')||(ch=='O')) && !observationChange) && !modeChanged)) { observationChange=true; digitOneReceived=false; digitTwoReceived=false; //spawn a timer for 3 seconds displayMutex.lock(); displayMutex.unlock(); KeyTimeOutTimer=new RtosTimer(keyTimeOut, osTimerOnce, (void *)0); KeyTimeOutTimer->start(3000); } else if((observationChange) && ((ch>=48) && (ch<=57))) { if(!digitOneReceived) { KeyTimeOutTimer->start(3000); observationChangeMutex.lock(); observationRate=ch-'0'; observationChangeMutex.unlock(); digitOneReceived=true; displayMutex.lock(); pc.printf("%02d\r\n", observationRate); displayMutex.unlock(); } else { KeyTimeOutTimer->stop(); digitTwoReceived=true; observationChangeMutex.lock(); observationRate=(observationRate*10)+(ch-'0'); observationChangeMutex.unlock(); observationChange=false; displayMutex.lock(); pc.printf("%02d\r\n", observationRate); displayMutex.unlock(); } } } } void alarm(const void *args) { while(1) { Thread::wait(1000); while(((heartRateHeart*(60/sec))>(60000/URI)) && ringAlarm) { buzzer=1; Thread::wait(5); buzzer=0; Thread::wait(5); if(!ringingAlarm) { displayMutex.lock(); println("Alarm : HeartRate too high"); displayMutex.unlock(); ringingAlarm=true; } } while(((heartRateHeart*(60/sec))<(60000/LRI)) && ringAlarm) { buzzer=1; Thread::wait(10); buzzer=0; Thread::wait(10); if(!ringingAlarm) { displayMutex.lock(); println("Alarm : HeartRate too Low"); displayMutex.unlock(); ringingAlarm=true; } } if(ringingAlarm) { ringingAlarm=false; resetDisplay(); } } } void display(const void *args) { while(1) { Thread::wait(observationInterval); waitCount++; if(!observationChange) { avgHeartRate=heartRate*rateCoefficient/waitCount; heartRateMutex.lock(); heartRate=0; heartRateMutex.unlock(); if(observationRate!=(observationInterval/1000)) { resetDisplay(); observationInterval=observationRate*1000; rateCoefficient=(60000/observationInterval); } waitCount=0; } } } int main() { //initialize variables expectAMutex.lock(); waitASignal=true; expectAMutex.unlock(); expectVMutex.lock(); waitVSignal=true; expectVMutex.unlock(); switchToNormal(); heartRate=0; avgHeartRate=0; paceMakerMode=1; observationInterval=5000; observationRate=5; waitCount=0; rateCoefficient=12; paceA=false; observationChange=false; digitOneReceived=false; digitTwoReceived=false; modeChanged=false; canPaceV=true; paceVPending=false; buzzer=0; ringAlarm=true; heartRateHeart=0; sec=0; avgHeartRateHeart=0; ringingAlarm=false; timerRunning=false; aSenseOccurred=true; ASignal.fall(&aSense); VSignal.fall(&vSense); TimeOutTimer=new RtosTimer(timeOut, osTimerOnce, (void*)0); URITimeOutTimer=new RtosTimer(uriTimeOut, osTimerOnce, (void *)0); SecondsTimer=new RtosTimer(seconds, osTimerPeriodic, (void *)0); //timer that over runs every 1 second and is used to reset the heart rate count coming from the heart SecondsTimer->start(1000); //start the timer to run for every 1 second Thread Pace(pace); PacePTR=&Pace; Pace.set_priority(osPriorityHigh); Thread PMSense(pmSense); PMSensePTR=&PMSense; PMSense.set_priority(osPriorityAboveNormal); Thread Alarm(alarm); Alarm.set_priority(osPriorityAboveNormal); Thread ModeChange(modeChange); ModeChangePTR=&ModeChange; ModeChange.set_priority(osPriorityAboveNormal); Thread Display(display); Thread SerialThread(serialThread); SerialThreadPTR=&SerialThread; SerialThread.set_priority(osPriorityRealtime); Display.set_priority(osPriorityAboveNormal); timeOutStatusMutex.lock(); timeConstraint=VRP_const; timeOutStatusMutex.unlock(); TimeOutTimer->start(VRP); while(1) { if(pc.readable()) { ch=pc.getc(); (*SerialThreadPTR).signal_set(signal2); //initiate the serial thread to change the state of the timer } } }