Almost Done!

Dependencies:   TextLCD mbed-rtos mbed

main.cpp

Committer:
haphilip
Date:
2016-12-01
Revision:
0:b27d866ee3b3

File content as of revision 0:b27d866ee3b3:

#include "mbed.h"
#include "rtos.h"
#include "TextLCD.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;

TextLCD lcd(p15, p16, p17, p18, p19, p20, TextLCD::LCD16x2);
Serial pc(USBTX, USBRX);
RawSerial pc2(USBTX, USBRX);

Timer vClock;
Timer aClock;               //PaceSignal model

RtosTimer *apace_timer;
RtosTimer *vpace_timer;

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 in miliseconds

int upperBound; //for mode changes
int lowerBound; //for mode changes

int observation_interval = 10; // In seconds
int heart_beats = 0; // Heart-Beats (sensed or paced) since the last observation interval

int isChangingObsInt = 0;
char key = 'n';
char newObsInt[8];
int manual_mode = 0;
char mode = 'n';



void initialize_intervals()
{
    LRI = 1000;
    URI = 700;
    VRP = 200;
    ARP = 50;
    AVI = 150;
    PVARP = 300;
}


// 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 * 1000);
        lcd.cls();
        int hr = (heart_beats*60) / (observation_interval);
        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 a signal from the heart
void asignal_irq()
{
    osSignalSet(signalTid, 0x1);
}

// Incoming v signal from the heart
void vsignal_irq()
{
    osSignalSet(signalTid, 0x2);
}


// Timer-driven function to pace the Atria
void a_pace(void const*)
{
    Apace = 1;
    aClock.reset();
    apace_timer->stop();
    toggleLed(3);
    Apace = 0;
    osSignalSet(signalTid, 0x3);
}

// Timer-driven function to pace the ventricle
void v_pace(void const*)
{
    Vpace = 1;
    vClock.reset();
    vpace_timer->start(LRI);
    apace_timer->start(LRI-AVI);
    toggleLed(4);
    Vpace = 0;
    osSignalSet(signalTid, 0x4);
    heart_beats++;
}



void PaceSignal(void const *args)
{
    int pFlag1 = 0;
    int pFlag2 = 0;
    vClock.start();
    aClock.start();
    vpace_timer->start(LRI);
    apace_timer->start(LRI-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);
                //pc2.printf("%s%d%s","as ", vClock.read_ms(), "\n");
                aClock.reset();
                apace_timer->stop();
                int interval = (vClock.read_ms() + AVI >= URI) ? AVI : URI - vClock.read_ms();
                vpace_timer->start(interval);
                pFlag1 = 1;
            } else if(evt == 0x2 && vClock.read_ms() >= VRP) { //vSignal
                osSignalSet(senseTid, 0x2);
                //pc2.printf("%s%d%s","vs ", vClock.read_ms(), "\n");
                vClock.reset();
                vpace_timer->start(LRI);
                apace_timer->start(LRI-AVI);
            } else if (evt == 0x3) { //aPace
                pFlag1 = 1;
            }
        }
        pFlag1 = 0;

        while(!pFlag2) {
            osEvent ext_signal = osSignalWait(0, osWaitForever);
            int evt = ext_signal.value.signals;

            if (evt == 0x1 && aClock.read_ms() >= ARP) { //aSignal
                osSignalSet(senseTid, 0x1);
                //pc2.printf("%s%d%s","as ", vClock.read_ms(), "\n");
                aClock.reset();
            } else if(evt == 0x2) { //vSignal
                osSignalSet(senseTid, 0x2);
                //pc2.printf("%s%d%s","vs ", vClock.read_ms(), "\n");
                vClock.reset();
                apace_timer->start(LRI-AVI);
                vpace_timer->start(LRI);
                pFlag2 = 1;
            } else if (evt == 0x4) { //vPace
                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;
    }
}

osThreadDef(PaceSignal, osPriorityNormal, DEFAULT_STACK_SIZE);
osThreadDef(PaceSense, osPriorityNormal, DEFAULT_STACK_SIZE);
osThreadDef(displayThread, osPriorityNormal, DEFAULT_STACK_SIZE);

int main()
{
    senseTid = osThreadCreate(osThread(PaceSense), NULL);
    signalTid = osThreadCreate(osThread(PaceSignal), NULL);
    displayTid = osThreadCreate(osThread(displayThread), 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();


//    'n' for normal mode (default)
//    's' for sleep mode
//    'e' for exercise mode
//    'm' for manual mode
//    'o' to change the observation interval

    key = 'n';

    while(true) {
        Thread::wait(100);
        while(pc.readable()) {
            key = pc.getc();
            switch(key) {
                    //pvarp = 0.3s
                case('n'):
                    mode = 'n';
                    upperBound = 100; //beats per msecond
                    lowerBound = 40; //beats per msecond
                    lcd.printf("N");
                    initialize_intervals();
                    break;
                case('s'):
                    mode = 's';
                    upperBound = 60; //beats per msecond
                    lowerBound = 30; //beats per msecond v-v 0.5s
                    lcd.printf("S");
                    ratio = (60.00/100.00 + 30.00/40.00) / 2.00;
                    initialize_intervals();
                    LRI /= ratio;
                    URI /= ratio;
                    VRP /= ratio;
                    ARP /= ratio;
                    AVI /= ratio;
                    PVARP /= ratio;
//                    lcd.printf("%lf", LRI);
                    break;
                case('e'):
                    mode = 'e';
                    upperBound = 175; //beats per msecond
                    lowerBound = 100; //beats per msecond
                    lcd.printf("E");
                    ratio = (175.00/100.00 + 100.00/40.00) / 2.00;
                    initialize_intervals();
                    LRI /= ratio;
                    URI /= ratio;
                    VRP /= ratio;
                    ARP /= ratio;
                    AVI /= ratio;
                    PVARP /= ratio;
//                    lcd.printf("%lf", LRI);
                    break;
                case('m'):
                    mode = 'm';
                    upperBound = 175; //beats per msecond
                    lowerBound = 30; //beats per msecond
                    lcd.printf("M");
//                    LRI = 1000;
//                    URI = 700;
//                    PVARP = 300;
                    manual_mode = 1;
                    break;
                case('o'):

                    isChangingObsInt = 1;
                    lcd.printf("O");
                    break;
            }
///////manual pacing
            if(manual_mode) {
                key = pc.getc();
                if(key == 'v') {
                    v_pace(NULL);
                } else if(key == 'a') {
                    a_pace(NULL);
                } else if(key == 'q') {
                    manual_mode = 0;
                }
            }



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


}