here it is

Dependencies:   TextLCD mbed-rtos mbed

Fork of 541-pacemaker by Terry Fang

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;
+//            }
+}