
here it is
Dependencies: TextLCD mbed-rtos mbed
Fork of 541-pacemaker by
Diff: main.cpp
- Revision:
- 0:dac187b013e0
- Child:
- 1:e6f6471e2c00
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Fri Dec 02 23:54:09 2016 +0000 @@ -0,0 +1,514 @@ +#include "mbed.h" +#include "rtos.h" +#include "TextLCD.h" +#include <stdio.h> + +InterruptIn vsignal(p7); +InterruptIn asignal(p8); +DigitalOut Vpace(p5); +DigitalOut Apace(p6); + +DigitalOut asense_led(LED1); +DigitalOut vsense_led(LED2); +DigitalOut apace_led(LED3); +DigitalOut vpace_led(LED4); + +Thread *pacemodeThread; + +osThreadId signalTid; +osThreadId senseTid; +osThreadId displayTid; +osThreadId pacemodeTid; + +TextLCD lcd(p15, p16, p17, p18, p19, p20, TextLCD::LCD16x2); +RawSerial pc(USBTX, USBRX); + +Timer vClock; +Timer aClock; //PaceSignal model + +RtosTimer *apace_timer; +RtosTimer *vpace_timer; +//RtosTimer *vpace_timer2; + +double LRI = 1000; +double URI = 700; +double VRP = 200; // V noise interval +double ARP = 50; // A noise interval +double AVI = 150; // A-V max interval +double PVARP = 300; // V-A max interval +double ratio; +int wait_period = 10; // 3a requirement + +int observation_interval = 10000; // In miliseconds +int upperBound; //for mode changes +int lowerBound; //for mode changes +int heart_beats = 0; // Heart-Beats (sensed or paced) since the last observation interval +char mode = 'n'; +int isChangingObsInt = 0; +char key = 'n'; +char newObsInt[8]; +int manual_mode = 0; + +Queue<char,256> mode_q; +Queue<char,256> signal_q; +volatile char c; +volatile int mm = 0; +int mm_flag = 0; + +void initialize_intervals() +{ + LRI = 1000; + URI = 700; + VRP = 200; + ARP = 50; + AVI = 150; + PVARP = 300; +} + +void Rx_interrupt() +{ + while(pc.readable()) { + c = pc.getc(); + if(c == 'm') { + mode_q.put((char*)c); + mm = 1; + } else if(c == 'n' || c == 'e' || c == 's') { + mode_q.put((char*)c); + mm = 0; + } else if((c == 'a' || c == 'v') && mm) { + signal_q.put((char*)c); + } + } +} + + +// Function to toggle the LEDs 1,2,3,4 +void toggleLed(int led) +{ + switch (led) { + case (1): + asense_led = 1; + Thread::wait(wait_period); + asense_led = 0; + break; + case (2): + vsense_led = 1; + Thread::wait(wait_period); + vsense_led = 0; + break; + case (3): + apace_led = 1; + Thread::wait(wait_period); + apace_led = 0; + break; + case (4): + vpace_led = 1; + Thread::wait(wait_period); + vpace_led = 0; + break; + } +} + +void displayThread(void const *args) +{ + while (1) { + Thread::wait(observation_interval); + lcd.cls(); + int hr = (heart_beats*60) / (observation_interval / 1000); + lcd.printf("%s%d%s","HR: ", hr, " bpm"); + + switch(mode) { + case('n'): + if (hr > 100) { + lcd.printf("%s", "\nALARM HIGH"); + } else if (hr < 40) { + lcd.printf("%s", "\nALARM LOW"); + } + break; + case('e'): + if (hr > 175) { + lcd.printf("%s", "\nALARM HIGH"); + } else if (hr < 100) { + lcd.printf("%s", "\nALARM LOW"); + } + break; + case('s'): + if (hr > 60) { + lcd.printf("%s", "\nALARM HIGH"); + } else if (hr < 30) { + lcd.printf("%s", "\nALARM LOW"); + } + break; + case('m'): + if (hr > 175) { + lcd.printf("%s", "\nALARM HIGH"); + } else if (hr < 30) { + lcd.printf("%s", "\nALARM LOW"); + } + break; + } + + heart_beats = 0; + } +} + + +// Incoming signal from the heart +void asignal_irq() +{ + osSignalSet(signalTid, 0x1); +} + +// Incoming signal from the heart +void vsignal_irq() +{ + osSignalSet(signalTid, 0x2); +} + + +// Timer-driven function to pace the Atrial +void a_pace(void const*) +{ + aClock.reset(); + Apace = 1; + toggleLed(3); + Apace = 0; + osSignalSet(signalTid, 0x3); + //osSignalSet(senseTid, 0x3); +} + +// Timer-driven function to pace the ventrical +void v_pace(void const*) +{ + vClock.reset(); + Vpace = 1; + toggleLed(4); + Vpace = 0; + vpace_timer->start(LRI); + apace_timer->start(LRI-AVI); +// vpace_timer2->start(AVI); + osSignalSet(signalTid, 0x4); + //osSignalSet(senseTid, 0x4); + heart_beats++; +} + + + +void PaceSignal(void const *args) +{ + int pFlag1 = 0; + int pFlag2 = 0; + vClock.start(); + aClock.start(); + if(!mm_flag){ + vpace_timer->start(LRI); + apace_timer->start(LRI-AVI); + } +// vpace_timer2->start(AVI); + while(1) { + while (!pFlag1) { + osEvent ext_signal = osSignalWait(0, osWaitForever); + int evt = ext_signal.value.signals; + + //lcd.printf("%d",evt); // 4(Vpace), 3(Apace), 2(Vsignal), 1(Asignal) + + if (evt == 0x1 && vClock.read_ms() >= PVARP) { //aSignal + osSignalSet(senseTid, 0x1); + aClock.reset(); + if(!mm_flag){ + apace_timer->start(LRI-AVI); + } + pFlag1 = 1; + } else if(evt == 0x2 && vClock.read_ms() >= VRP) { //vSignal + osSignalSet(senseTid, 0x2); + vClock.reset(); + if(!mm_flag){ + vpace_timer->start(LRI); + apace_timer->start(LRI-AVI); + } +// vpace_timer2->start(AVI); + } else if (evt == 0x3) { //aPace + aClock.reset(); + if(!mm_flag){ + apace_timer->start(LRI-AVI); + } + pFlag1 = 1; + } + } + pFlag1 = 0; + + while(!pFlag2) { + + osEvent ext_signal = osSignalWait(0, osWaitForever); + int evt = ext_signal.value.signals; + + //lcd.printf("%d",evt); + + if (evt == 0x1 && aClock.read_ms() >= ARP) { //aSignal + osSignalSet(senseTid, 0x1); + aClock.reset(); + if(!mm_flag){ + apace_timer->start(LRI-AVI); + } + Thread::wait(wait_period); + } else if(evt == 0x2) { //vSignal + osSignalSet(senseTid, 0x2); + vClock.reset(); + if(!mm_flag){ + vpace_timer->start(LRI); + apace_timer->start(LRI-AVI); + } +// vpace_timer2->start(AVI); + pFlag2 = 1; + } else if (evt == 0x4) { //vPace + vClock.reset(); + if(!mm_flag){ + vpace_timer->start(LRI); + apace_timer->start(LRI-AVI); + } +// vpace_timer2->start(AVI); + pFlag2 = 1; + } + } + pFlag2 = 0; + } +} + + +void PaceSense(void const *args) +{ + int pFlag1 = 0; + int pFlag2 = 0; + while(1) { + while (!pFlag1) { + osEvent ext_signal = osSignalWait(0, osWaitForever); + int evt = ext_signal.value.signals; + + //lcd.printf("%d",evt); + + if (evt == 0x1) { //aSense + toggleLed(evt); + pFlag1 = 1; + } else if(evt == 0x2) { //vSense + toggleLed(evt); + heart_beats++; + } else if (evt == 0x3) { //aPace + pFlag1 = 1; + } + + } + pFlag1 = 0; + while(!pFlag2) { + osEvent ext_signal = osSignalWait(0, osWaitForever); + int evt = ext_signal.value.signals; + + //lcd.printf("%d",evt); // 4096, 256, 16, 1 + + if (evt == 0x1) { //aSense + toggleLed(evt); + } else if(evt == 0x2) { //vSignal + toggleLed(evt); + heart_beats++; + pFlag2 = 1; + } else if (evt == 0x4) { //vPace + pFlag2 = 1; + } + } + pFlag2 = 0; + } +} + +void normalmode(void const *args) +{ + initialize_intervals(); + mode = 'n'; + lcd.printf("N"); + upperBound = 100; //beats per msecond + lowerBound = 40; //beats per msecond + + vpace_timer->start(LRI); + apace_timer->start(LRI-AVI); +} + +void exercisemode(void const *args) +{ + initialize_intervals(); + mode = 'e'; + lcd.printf("E"); + upperBound = 175; //beats per msecond + lowerBound = 100; //beats per msecond + ratio = (175.00/100.00 + 100.00/40.00) / 2.00; + LRI /= ratio; + URI /= ratio; + VRP /= ratio; + ARP /= ratio; + AVI /= ratio; + PVARP /= ratio; + + vpace_timer->start(LRI); + apace_timer->start(LRI-AVI); +} + +void sleepmode(void const *args) +{ + initialize_intervals(); + mode = 's'; + lcd.printf("S"); + upperBound = 60; //beats per msecond + lowerBound = 30; //beats per msecond v-v 0.5s + ratio = (60.00/100.00 + 30.00/40.00) / 2.00; + LRI /= ratio; + URI /= ratio; + VRP /= ratio; + ARP /= ratio; + AVI /= ratio; + PVARP /= ratio; + + vpace_timer->start(LRI); + apace_timer->start(LRI-AVI); + +} + +void m_vpace(){ + vClock.reset(); + Vpace = 1; + toggleLed(4); + Vpace = 0; + osSignalSet(signalTid, 0x4); + heart_beats++; +} + +void m_apace(){ + aClock.reset(); + Apace = 1; + toggleLed(3); + Apace = 0; + osSignalSet(signalTid, 0x3); +} + +void manualmode(void const *args) +{ + upperBound = 175; //beats per msecond + lowerBound = 30; //beats per msecond + lcd.printf("M"); + mode = 'm'; +// LRI = 1000; +// URI = 700; +// PVARP = 300; + + while(1) { + osEvent evt = signal_q.get(); + if(evt.status == osEventMessage) { + if((char)evt.value.p == 'v') { + m_vpace(); + } else if((char)evt.value.p == 'a') { + m_apace(); + } + } + } +} + + +osThreadDef(PaceSignal, osPriorityNormal, DEFAULT_STACK_SIZE); +osThreadDef(PaceSense, osPriorityNormal, DEFAULT_STACK_SIZE); + +osThreadDef(displayThread, osPriorityNormal, DEFAULT_STACK_SIZE); +osThreadDef(manualmode, osPriorityNormal, DEFAULT_STACK_SIZE); +osThreadDef(normalmode, osPriorityNormal, DEFAULT_STACK_SIZE); +osThreadDef(exercisemode, osPriorityNormal, DEFAULT_STACK_SIZE); +osThreadDef(sleepmode, osPriorityNormal, DEFAULT_STACK_SIZE); + +int main() +{ + senseTid = osThreadCreate(osThread(PaceSense), NULL); + signalTid = osThreadCreate(osThread(PaceSignal), NULL); + displayTid = osThreadCreate(osThread(displayThread), NULL); + pacemodeTid = osThreadCreate(osThread(normalmode), NULL); + + vsignal.rise(&vsignal_irq); //rising edge of timer + asignal.rise(&asignal_irq); + + Callback<void()> apaceTimerTask((void*)NULL, (void (*)(void*))&a_pace); + Callback<void()> vpaceTimerTask((void*)NULL, (void (*)(void*))&v_pace); + apace_timer = new RtosTimer(apaceTimerTask); + vpace_timer = new RtosTimer(vpaceTimerTask); + + lcd.cls(); + + pc.attach(&Rx_interrupt, RawSerial::RxIrq); + + while(true) { + osEvent evt = mode_q.get(); + if(evt.status == osEventMessage) { + switch((char)evt.value.p) { + case('n'): + mm_flag = 0; + osThreadTerminate (pacemodeTid); + pacemodeTid = osThreadCreate(osThread(normalmode), NULL); + break; + case('s'): + mm_flag = 0; + lcd.printf("testingS"); + osThreadTerminate (pacemodeTid); + pacemodeTid = osThreadCreate(osThread(sleepmode), NULL); + + break; + case('e'): + mm_flag = 0; + lcd.printf("testingE"); + osThreadTerminate (pacemodeTid); + pacemodeTid = osThreadCreate(osThread(exercisemode), NULL); + + break; + case('m'): + mm_flag = 1; + osThreadTerminate (pacemodeTid); + apace_timer->stop(); + vpace_timer->stop(); + pacemodeTid = osThreadCreate(osThread(manualmode), NULL); + manual_mode = 1; + break; + case('o'): + isChangingObsInt = 1; + break; + } + + + +///////observation interval +// int i = 0; +// while(isChangingObsInt){ +// // wait(1); +// key = pc.getc(); +//// lcd.printf("0"); +// if(key != '\r' && (int)key > 47 && (int)key < 58){ +// //use atoi - asci to integer to convert input key to 0 - 10 +// newObsInt[i] += key; +// i++; +// lcd.printf("1"); +// } +// else if(key == '\r'){ +// newObsInt[i] = '\0'; +// int obsint; +// sscanf(newObsInt, "%d", &obsint); +// observation_interval = obsint * 1000; +// lcd.printf("%s", obsint); +// isChangingObsInt = 0; +// // lcd.printf("2"); +// observation_interval = newObsInt * 1000; +// atoi(newObsInt[i]) +// strncat +// atoi +// !isChangingObsInt + } + } +// lcd.printf("3"); +// if (isChangingObsInt && (int)key > 47 && (int)key < 58){ +// newObsInt += key; +// lcd.printf("%lf", newObsInt); +// } +// else if (isChangingObsInt && key == '\r') { +// observation_interval = newObsInt * 1000; +// isChangingObsInt = 0; +// } +}