here it is

Dependencies:   TextLCD mbed-rtos mbed

Fork of 541-pacemaker by Terry Fang

main.cpp

Committer:
terryfan
Date:
2016-12-02
Revision:
0:dac187b013e0
Child:
1:e6f6471e2c00

File content as of revision 0:dac187b013e0:

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