yay!

Dependencies:   TextLCD mbed-rtos mbed

Fork of 541_Pacermaker by CIS541

main.cpp

Committer:
sanjeet25
Date:
2015-12-02
Revision:
6:a1a3e73d90f3
Parent:
4:8e3dc7e73627

File content as of revision 6:a1a3e73d90f3:

#include "PacemakerLibrary.h"
#include "TextLCD.h"

TextLCD lcd(p15,p16,p17,p18,p19,p20);

int i=0;

void incrementHeartRate()
{
    heartRateMutex.lock();
    heartRate++;
    heartRateMutex.unlock();
}

void setVSignal(bool state)
{
    VMutex.lock();
    waitVSignal = state;
    VMutex.unlock();
}

void setASignal(bool state)
{
    AMutex.lock();
    waitASignal = state;
    AMutex.unlock();
}

void setTimeConstraint(int i)
{
    timeConstraintMutex.lock();
    timeConstraint = i;
    timeConstraintMutex.unlock();
}

void printToLCD()
{
    displayMutex.lock();
//    pc.printf("%04d\r\n", avgHeartRate);
//    pc.printf("%02d\r\n", pacemakerIntervalInMs/1000);
//    pc.printf("%04d\r\n", (heartRateHeart*(60/sec)));
    lcd.cls();
    lcd.locate(0,0);
    lcd.printf("Rate: %.2f BPM", avgHeartRate);
    lcd.locate(0,1);
    switch(pacemakerMode) {
        default:
        case NORMAL: {
            lcd.printf("NORMAL");
            break;
        }
        case EXERCISE: {
            lcd.printf("EXERCISE");
            break;
        }
        case SLEEP: {
            lcd.printf("SLEEP (ZZZ)");
            break;
        }
        case MANUAL: {
            lcd.printf("MANUAL");
            break;
        }
    }
    displayMutex.unlock();
}

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 changeMode()
{
    switch(pacemakerMode) {
        default:
        case NORMAL: {
            switchToNormal();
            break;
        }
        case EXERCISE: {
            switchToExercise();
            break;
        }
        case SLEEP: {
            switchToSleep();
            break;
        }
        case MANUAL: {
            break;
        }
    }
    changePacemakerMode=false;
}

void pacemakerModeSwitch(const void *args)
{
    while(1) {
        Thread::signal_wait(signal3);
        if(changePacemakerMode) {
            changeMode();
        }
    }
}

void aSense()
{
    if(waitASignal) {
        asenseLED=1;
        wait(0.001);
//        pc.printf("ASense Received at %d ms\r\n", globalTimer.read_ms());
        asenseLED=0;
        if(changePacemakerMode) {
            (*P_PacemakerModeSwitch).signal_set(signal3);
        }
        ASenseReceived=true;
        (*P_PacemakerReceive).signal_set(signal4);
    }
}

void vSense()
{
    if(waitVSignal) {
        vsenseLED=1;
//        pc.printf("VSense Received at %d ms\r\n", globalTimer.read_ms());
        wait(0.001);
        vsenseLED=0;
        if(changePacemakerMode) {
            (*P_PacemakerModeSwitch).signal_set(signal3);
        }
        waitVPace=false;
        ASenseReceived=false;
        (*P_PacemakerReceive).signal_set(signal4);
    }
}

void timeConstraintTimeout(const void *args)
{
    if(timeConstraint==AVI_const) {
        //trigger vpace
        if(waitVPace) {
            
            APace=false;
            (*P_PacemakerSend).signal_set(signal1);
            AVI+=AVISTEP;
            Dynamic_AVI=1;
            Thread::wait(1);
                Dynamic_AVI=0;
                
            if(AVI==AVI_MAX) {
                
                AVI=60;
                
            }
            pc.printf("AVI : %u",AVI);
        } else {
            waitVPace=true;
        }
    } else if(timeConstraint==PVAB_const) {
        setVSignal(true);
        setTimeConstraint(AVI_const);
        TimeConstTimerOn=true;
        TimeConstTimer->start(AVI-PVAB);
    } else if(timeConstraint==VRP_const) {
        setVSignal(true);
        setTimeConstraint(PVARP_const);;
        TimeConstTimerOn=true;
        TimeConstTimer->start(PVARP-VRP);
    } else if(timeConstraint==PVARP_const) {
        setASignal(true);
        setTimeConstraint(LRI_const);
        TimeConstTimerOn=true;
        TimeConstTimer->start(LRI-PVARP-AVI);
    } else if(timeConstraint==LRI_const) {
        //trigger apace
        APace=true;
        (*P_PacemakerSend).signal_set(signal1);
    }
}

void atrialEventTimeout(const void *args)
{
    if(VPaceNotReceived || waitVPace) {
        APace=false;
        VPaceNotReceived=false;
        (*P_PacemakerSend).signal_set(signal1);
    } else {
        waitVPace=true;
    }
}

void pacemakerReceive(const void *args)
{
    while(1) {
        Thread::signal_wait(signal4);
        if(TimeConstTimerOn) {
            TimeConstTimer->stop();
            TimeConstTimerOn=false;
        }
        if(ASenseReceived) {
            setASignal(false);
            setVSignal(true);
            TimeConstTimerOn=true;
            setTimeConstraint(AVI_const);
            TimeConstTimer->start(AVI);
        } else {
            incrementHeartRate();
            setVSignal(false);
            setASignal(false);
            waitVPace=false;
            AtrialEventTimer->start(URI);
            TimeConstTimerOn=true;
            setTimeConstraint(VRP_const);
            TimeConstTimer->start(VRP);
        }
    }
}

void pacemakerSend(const void *args)
{
    while(1) {
        Thread::signal_wait(signal1);
        if(APace) {
            pc.printf("APace Sent at %d ms\r\n", globalTimer.read_ms());
            apaceLED=1;
            aPace=1;
            Thread::wait(1);
            aPace=0;
            apaceLED=0;
            if(changePacemakerMode) {
                changeMode();
            }

            setASignal(false);
            setVSignal(false);
            setTimeConstraint(PVAB_const);
            if (pacemakerMode != MANUAL) {
                TimeConstTimerOn=true;
                TimeConstTimer->start(PVAB);
            }
        } else {
            pc.printf("VPace Sent at %d ms\r\n", globalTimer.read_ms());
            vpaceLED=1;
            vPace=1;
            Thread::wait(1);
            vPace=0;
            vpaceLED=0;
            if(changePacemakerMode) {
                changeMode();
            }

            setVSignal(false);
            setASignal(false);
            incrementHeartRate();
            waitVPace=false;
            AtrialEventTimer->start(URI);
            setTimeConstraint(VRP_const);
            TimeConstTimerOn=true;
            if (pacemakerMode != MANUAL) {
                TimeConstTimerOn=true;
                TimeConstTimer->start(VRP);
            }
        }
    }
}

void readInt()
{
    char c = pc.getc();
    int input = c-48;
    c = pc.getc();
    while (c != '\r') {
        input *= 10;
        input += c-48;
        c = pc.getc();
    }

    if (input >= 10 && input <= 90) {
        pacemakerInterval=input;
        pacemakerIntervalInMs = pacemakerInterval*1000;
        displayTimer.reset();
        heartRateMutex.lock();
        heartRate=0;
        heartRateMutex.unlock();
        pc.printf("Obs Int Changed: %d\r\n", pacemakerInterval);
    } else {
        pc.printf("Bad Obs Int: %d\r\n", input);
    }
}

void pacemakerKeyboard(const void *args)
{
    while(1) {
        Thread::signal_wait(signal2);
        if (char_read == 'a' && pacemakerMode == MANUAL) {
            APace=true;
            (*P_PacemakerSend).signal_set(signal1);
        } else if (char_read == 'v' && pacemakerMode == MANUAL) {
            if(waitVPace) {
                APace=false;
                VPaceNotReceived=false;
                (*P_PacemakerSend).signal_set(signal1);
            } else {
                VPaceNotReceived=true;
            }
        } else if (char_read == 'n' && pacemakerMode != NORMAL && !changePacemakerMode) {
            if (pacemakerMode == MANUAL) {
                // restart A/V timers
                TimeConstTimerOn=true;
                TimeConstTimer->start(VRP);
            }
            pacemakerMode=NORMAL;
            changePacemakerMode=true;
        } else if (char_read == 'e' && pacemakerMode != EXERCISE && !changePacemakerMode) {
            if (pacemakerMode == MANUAL) {
                // restart A/V timers
                TimeConstTimer->start(VRP);
            }
            pacemakerMode=EXERCISE;
            changePacemakerMode=true;
        } else if (char_read == 's' && pacemakerMode != SLEEP && !changePacemakerMode) {
            if (pacemakerMode == MANUAL) {
                // restart A/V timers
                TimeConstTimer->start(VRP);
            }
            pacemakerMode=SLEEP;
            changePacemakerMode=true;
        } else if (char_read == 'm' && pacemakerMode != MANUAL && !changePacemakerMode) {
            pacemakerMode=MANUAL;
            changePacemakerMode=true;
        } else if (char_read == 'o' && !changePacemakerMode) {
            // blocks, reading characters, until "return" is pressed
            observationMutex.lock();
            readInt();
            observationMutex.unlock();
        }
    }
}

void pacemakerAlarm(const void *args)
{
    while(1) {
        Thread::signal_wait(signal5);
        while(avgHeartRate > (60000/URI)) {
            buzzer=1;
            Thread::wait(5);
            buzzer=0;
            Thread::wait(5);
            if(!alarmPrinted) {
                displayMutex.lock();
                println("!!!***Alarm High***!!!");
                displayMutex.unlock();
                alarmPrinted=true;
            }
        }
        while(avgHeartRate < (60000/LRI)) {
            buzzer=1;
            Thread::wait(10);
            buzzer=0;
            Thread::wait(10);
            if(!alarmPrinted) {
                displayMutex.lock();
                println("!!!***Alarm Low***!!!");
                displayMutex.unlock();
                alarmPrinted=true;
            }
        }
        if(alarmPrinted) {
            alarmPrinted=false;
//            resetDisplay();
        }
    }
}

void display(const void *args)
{
    displayTimer.start();

    while(1) {
        observationMutex.lock();
        if (displayTimer.read_ms() >= pacemakerIntervalInMs) {
            displayTimer.reset();
            printToLCD();
            avgHeartRate=heartRate*(60.0/pacemakerInterval);
            heartRateMutex.lock();
            heartRate=0;
            heartRateMutex.unlock();
            observationMutex.unlock();
            (*P_PacemakerAlarm).signal_set(signal5);
        } else {
            printToLCD();
            observationMutex.unlock();
            Thread::wait(100);
        }
    }
}

int main()
{
    setVSignal(true);
    setVSignal(true);
    switchToNormal();

    ASignal.rise(&aSense);
    VSignal.rise(&vSense);

    TimeConstTimer = new RtosTimer(timeConstraintTimeout, osTimerOnce, (void*)0);
    AtrialEventTimer = new RtosTimer(atrialEventTimeout, osTimerOnce, (void *)0);

    Thread PacemakerSend(pacemakerSend);
    P_PacemakerSend=&PacemakerSend;
    PacemakerSend.set_priority(osPriorityHigh);

    Thread PacemakerReceive(pacemakerReceive);
    P_PacemakerReceive=&PacemakerReceive;
    PacemakerReceive.set_priority(osPriorityAboveNormal);

    Thread PacemakerModeSwitch(pacemakerModeSwitch);
    P_PacemakerModeSwitch=&PacemakerModeSwitch;
    PacemakerModeSwitch.set_priority(osPriorityAboveNormal);

    Thread PacemakerKeyboard(pacemakerKeyboard);
    P_PacemakerKeyboard=&PacemakerKeyboard;
    PacemakerKeyboard.set_priority(osPriorityRealtime);

    Thread Display(display);
    Display.set_priority(osPriorityAboveNormal);

    Thread PacemakerAlarm(pacemakerAlarm);
    P_PacemakerAlarm = &PacemakerAlarm;
    PacemakerAlarm.set_priority(osPriorityAboveNormal);

    setTimeConstraint(VRP_const);
    TimeConstTimer->start(VRP);

    globalTimer.start();

    while(1) {
        if(pc.readable()) {
            char_read = pc.getc();
            (*P_PacemakerKeyboard).signal_set(signal2);
        }
    }
}