heart modes, send, receive

Dependencies:   Terminal TextLCD mbed-rtos mbed

Fork of Heartnew by CIS541

Files at this revision

API Documentation at this revision

Comitter:
sanjeet25
Date:
Wed Dec 02 05:39:01 2015 +0000
Parent:
6:cc4fcc38b9f0
Commit message:
heartwork

Changed in this revision

heart.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/heart.cpp	Wed Dec 02 04:03:46 2015 +0000
+++ b/heart.cpp	Wed Dec 02 05:39:01 2015 +0000
@@ -1,518 +1,763 @@
 #include "mbed.h"
-#include "TextLCD.h"
 #include "rtos.h"
-
-TextLCD lcd(p15, p16, p17, p18, p19, p20);
-Serial pc(USBTX, USBRX);
+#include "Terminal.h"
 
-InterruptIn APace(p23);
-InterruptIn VPace(p24);
+DigitalOut led1(LED1);          //asense
+DigitalOut led2(LED2);          //vsense
+DigitalOut led3(LED3);          //apace 
+DigitalOut led4(LED4);          //vpace
+DigitalOut aSense(p23);
+DigitalOut vSense(p24);
+InterruptIn APace(p25);
+InterruptIn VPace(p26);
 
-DigitalOut ASignal(p25);
-DigitalOut VSignal(p26);
-
-DigitalOut APaceReceive(LED1);
-DigitalOut VPaceReceive(LED2);
+Terminal console(USBTX, USBRX);
 
-DigitalOut ASignal1(LED3);
-DigitalOut VSignal1(LED4);
-
-const int minwait_A=50;
-const int minwait_V=50;
+int heartRate, avgHeartRate, observationInterval, rateCoefficient, observationRate, waitCount, senseWaitTime, testCase, changeModeTo;
+int heartMode;                             //0 - Normal, 1 - Manual, 2 - Test
+bool observationChange, digitOneReceived, paceReceived, synchDone, testOn, testResult[10]={false}, digitTwoReceived, changeMode, receivedVPace;
+char ch;
+char modeString[10];
 
-volatile int t=0;
-volatile int k=0;
-int m=0;
-int s=0;
-int ms=0;
-int heartInterval;
-char key_input;
-int testNumber;
-bool test_result;
-const int prop_delay=15;
-int flag_key=0;
-Mutex heartmut, keymutex;
+const int nLRI=1500, nAVI = 60, nPVARP = 150, nURI = 600, nVRP = 100;   //timing constraints for Normal Mode of the Pacemaker
+const int delta=20;
+
+osMutexId displayMutex;
+osMutexDef (displayMutex);
+osMutexId observationChangeMutex;
+osMutexDef(obserationChangeMutex);
+osMutexId heartRateMutex;
+osMutexDef (heartRateMuex);
 
-int LRI=1500;
-int URI=600;
-int heartRate;
-volatile bool Areceived=false;
-volatile bool Vreceived=false;
-bool test=false;
-int low[4] = {30,40,100,30};
-int high[4] = {60,100,175,175};
-int modeset;
-int pulses;
-//int test;
-int flag;
-int delta=15;
-int observationInterval=10000;
-const int vrp=100;
-const int pvarp=150;
-const int avi=65;
-const int pvab=10;
-
-const int sleepModeURI = 1000;
-const int sleepModeLRI = 2000;
-
-const int normalModeURI = 600;
-const int normalModeLRI = 1500;
+Thread *SerialThreadPTR;
+Thread *HeartSensePTR;
+Thread *TestModePTR;
+Thread *TestDisplayPTR;
+RtosTimer *KeyTimeOutTimer;
+RtosTimer *SenseWaitTimer;
+//testCode
+Timer t;
 
-const int sportsModeURI = 343;
-const int sportsModeLRI = 600;
-
-const int manualModeURI = 343;
-const int manualModeLRI = 2000;
-
-int lri=normalModeLRI;
-int uri=normalModeURI;
-int flagr=0;
+void resetDisplay()
+{
+    osMutexWait(displayMutex, osWaitForever);
+    console.cls();
+    console.locate(30, 6);
+    console.printf("Heart Display");
+    console.locate(30, 10);
+    console.printf("Heart Rate :  %04d bpm", avgHeartRate);
+    console.locate(30, 12);
+    console.printf("Observation Interval :  %02d seconds", observationInterval/1000);
+    console.locate(30, 14);
+    console.printf("Mode :  %s", modeString);
+    osMutexRelease(displayMutex);
+}
 
-typedef enum Modes {
-    Test,
-    Normal,
-    Sleep,
-    Random,
-    Sports,
-    Manual,
-    Observer
-};
-Modes mode;
-
-Mutex HeartMutex;
-
-Thread *heartreceive;
-Thread *heartsend;
-Thread *heartkeyboard;
-Thread *testmode;
-Thread *hmode;
+void updateDisplay()
+{
+    osMutexWait(displayMutex, osWaitForever);
+    console.locate(44, 10);
+    console.printf("%04d", avgHeartRate);
+    console.locate(54, 12);
+    console.printf("%02d", observationInterval/1000);
+    osMutexRelease(displayMutex);
+}   
 
 
-void resett();
-void resetk();
-void VPacereceived();
-void APacereceived();
-void ASignalsend();
-void VSignalsend();
-void HeartReceive();
-void HeartSend();
-void HeartKeyBoardModeSwitch();
-void sound_lowAlarm();
-void sound_highAlarm();
-void Testmode();
-
-
-extern "C" void TIMER0_IRQHandler (void)
-{
-    if((LPC_TIM0->IR & 0x01) == 0x01) { // if MR0 interrupt, proceed
-        LPC_TIM0->IR |= 1 << 0;         // Clear MR0 interrupt flag
-        t++;
-        k++;
-    }
-}
-
-//Initializing the timer 0
-void timer0_init(void)
+void heartSense(const void *args)
 {
-
-    LPC_SC->PCONP |=1<1;            //Timer0 Power On
-    LPC_TIM0->MR0 = 23990;         //1 msec
-    LPC_TIM0->MCR = 3;              //interrupt and reset control
-    NVIC_EnableIRQ(TIMER1_IRQn);    //Enable timer0 interrupt
-    LPC_TIM0->TCR = 1;              //enable Timer0
-    t = 0;
-    k = 0;
-}
-
-void resett()
-{
-    t=0;
-}
-
-void resetk()
-{
-    k=0;
-}
-
-void sound_lowAlarm()
-{
-    pc.printf("lowalarm");
-}
-void sound_highAlarm()
-{
-    pc.printf("highalarm");
-}
-void VPacereceived()
-{
-    pc.printf("VPace received");
-    VPaceReceive=1;
-    wait(0.002);
-    APaceReceive=0;
-    //pulses++;
-    Vreceived=true;
-    Areceived=false;
-    if(mode == Test && flag==0) {
-        (*testmode).signal_set(0x04);
-    }
-    if(mode == Test && test) {
-        if(testNumber == 2 || testNumber == 0 || testNumber == 3 || testNumber == 1) {
-            test_result = false;
-        } else if(testNumber == 6 || testNumber == 4) {
-            test_result = true;
+    while(1)
+    {
+        if(heartMode>0)
+        {
+            Thread::signal_wait(0x02);
+        }
+        //Thread::wait(500);              //chnage this
+        senseWaitTime=50+(rand()%2000);
+        SenseWaitTimer->start(senseWaitTime);
+        Thread::signal_wait(0x03);
+        if(rand()%2==0)
+        {
+            led1=1;
+            aSense=1;
+            Thread::wait(1);
+            aSense=0;
+            led1=0;
+        }
+        else
+        {
+            led2=1;
+            vSense=1;
+            Thread::wait(1);
+            vSense=0;
+            led2=0;
+            osMutexWait(heartRateMutex, osWaitForever);
+            heartRate++;
+            osMutexRelease(heartRateMutex);
+            
         }
     }
 }
 
-void APacereceived()
-{
-    pc.printf("APace received");
-    APaceReceive=1;
-    wait(0.002);
-    APaceReceive=0;
-    Areceived=true;
-    if(mode == Test && test) {
-        if(testNumber == 0) {
-            test_result = false;
-        } else if(testNumber == 4 || testNumber == 7 || testNumber == 3 || testNumber == 1) {
-            test_result = true;
-        }
-    }
-}
-
-void ASignalsend()
+void display(const void *args)
 {
-    ASignal=1;
-    ASignal1=1;
-    wait(0.02);
-    Thread::wait(1);
-    ASignal1=0;
-    ASignal=0;
-}
-
-void VSignalsend()
-{
-    VSignal=1;
-    VSignal1=1;
-    wait(0.02);
-    Thread::wait(1);
-    VSignal1=0;
-    VSignal==0;
-}
-
-void updateHeart()
-{
-    int temp = 60/heartInterval;
-    heartmut.lock();
-    heartRate = heartRate + temp;
-    heartmut.lock();
-}
-void HeartReceive(void const* args)
-{
-    while(1) {
-        pc.printf("HR");
-        while(Areceived==false||Vreceived==false);
-        if(Vreceived==true) {
-            resett();
-
-        } else if(Areceived==true) {
-            resett();
+    while(1)
+    {
+        Thread::wait(observationInterval);
+        if(heartMode!=2)
+        {
+            waitCount++;
+            if(!observationChange)
+            {
+                avgHeartRate=heartRate*rateCoefficient/waitCount;
+                osMutexWait(heartRateMutex, osWaitForever);
+                heartRate=0;
+                osMutexRelease(heartRateMutex);
+                if(observationRate!=(observationInterval/1000))
+                {
+                    resetDisplay();
+                    //update observationrate after the current interval stats  are displayed
+                    observationInterval=observationRate*1000;           
+                    rateCoefficient=(60000/observationInterval);
+                } 
+                else
+                {
+                    updateDisplay();
+                }
+                waitCount=0;   
+            }        
         }
     }
 }
 
-void HeartSend(void const* args)
+void senseWait(const void *args)
+{
+    (*HeartSensePTR).signal_set(0x03);
+}
+
+void keyTimeOut(const void *args)
 {
-    while(1) {
-        if(flagr==1){
-        int r = rand() % 2;
-        pc.printf("HS");
-        while(t<minwait_V && mode!=Random && (mode==Test || mode==Manual));
-        pc.printf("%u",t);
-        if(r==0 && mode!=Test) {
-            VSignalsend();
-            pc.printf("Vsignal");
-            resett();
-        } else if(r==1&&mode!=Test) {
-            ASignalsend();
-            pc.printf("ASignal");
-            resett();
-        }}
+    if(digitOneReceived)
+    {
+        observationChange=false;
     }
-    //keymutex.unlock();
-    // }
+    else
+    {
+        observationChange=false;
+    }
+    resetDisplay();
 }
-void HeartKeyBoardModeSwitch(void const* args)
+
+void testMode(const void *args)
 {
-    while(1) {
-        keymutex.lock();
-        if((key_input=='r'||key_input=='R')&&flag_key==1) {
-            mode=Random;
-            pc.printf("Random");
-            flagr=1;
-                HeartSend("s");     
-            flag_key=0;
-        } else if((key_input=='m'||key_input=='M')&&flag_key) {
-            mode=Manual;
-            pc.printf("Manual");
-            flag_key=0;
-            
-        } else if(mode==Manual&&(key_input=='v'||key_input=='V')&&flag_key==1) {
-            mode=Manual;
-            VSignalsend();
-            pc.printf("Ventricular");
-            flag_key=0;
+    while(1)
+    {
+        if(heartMode!=2)
+        {
+            Thread::signal_wait(0x04);  
+        }
+        else
+        {
+            osMutexWait(displayMutex, osWaitForever);
+            console.cls();
+            osMutexRelease(displayMutex);
+            //synch with PM
+            //TestCase 1 - Asense at PVARP+; No Vpace within URI-PVARP (detected within URI-PVARP+delta) 
+            testCase=0;
+            testResult[testCase]=true;
+            osMutexWait(displayMutex, osWaitForever);
+            console.locate(20,testCase);
+            osMutexRelease(displayMutex);
+            synchDone=false;
+            Thread::signal_wait(0x05);
+            synchDone=true;
+            t.reset();
+            t.start();
+            Thread::wait(nPVARP);
+            led1=1;
+            aSense=1;
+            Thread::wait(1);
+            aSense=0;
+            led1=0;
+            osMutexWait(displayMutex, osWaitForever);
+            console.printf("AS : %d      ",t.read_ms());
+            osMutexRelease(displayMutex);
+            testOn=true;
+            Thread::wait(nURI-nPVARP-delta);
+            testOn=false;
+            if(testResult[testCase])
+            {
+                osMutexWait(displayMutex, osWaitForever);
+                console.locate(0,testCase);
+                console.printf("test %d pass",testCase+1);
+                osMutexRelease(displayMutex);
+            }
+            else
+            {
+                osMutexWait(displayMutex, osWaitForever);
+                console.locate(0,testCase);
+                console.printf("test %d fail",testCase+1);
+                osMutexRelease(displayMutex);                
+            }
             
-        } else if(mode==Manual&&flag_key==1&&(key_input=='a'||key_input=='A')) {
-            mode=Manual;
-            ASignalsend();
-            pc.printf("Atrial");
-            flag_key=0;
-        } else if((key_input=='o'||key_input=='O')&&flag_key==1) {
-            int a = 10 + rand() % 80;
-            mode=Observer;
-            pc.printf("Observer and %u",a);
-            heartInterval =a;
-            HeartSend("s");
-            flag_key=0;
+            //synch with PM
+            //TestCase 2 - Asense at URI+; Vpace within AVI+delta
+            testCase=1;
+            osMutexWait(displayMutex, osWaitForever);
+            console.locate(20,testCase);
+            osMutexRelease(displayMutex);
+            synchDone=false;
+            Thread::signal_wait(0x05);
+            synchDone=true;
+            t.reset();
+            Thread::wait(nURI);
+            led1=1;
+            aSense=1;
+            Thread::wait(1);
+            aSense=0;
+            led1=0;
+            osMutexWait(displayMutex, osWaitForever);
+            console.printf("AS : %d      ",t.read_ms());
+            osMutexRelease(displayMutex);
+            testOn=true;
+            Thread::wait(nAVI+delta);
+            testOn=false;
+            if(testResult[testCase])
+            {
+                osMutexWait(displayMutex, osWaitForever);
+                console.locate(0,testCase);
+                console.printf("test %d pass",testCase+1);
+                osMutexRelease(displayMutex);
+            }
+            else
+            {
+                osMutexWait(displayMutex, osWaitForever);
+                console.locate(0,testCase);
+                console.printf("test %d fail",testCase+1);
+                osMutexRelease(displayMutex);                
+            }     
+            //synch with PM
+            //TestCase 3 - Asense at URI+; Vsense at AVI-; No pace detected; run this 4 times
+            testCase=2;
+            testResult[testCase]=true;
+            synchDone=false;
+            Thread::signal_wait(0x05);
+            synchDone=true;
+            t.reset();
+            Thread::wait(nURI);
+            testOn=true;
+            for(int i=0;i<5;i++)
+            {
+                /*osMutexWait(displayMutex, osWaitForever);
+                console.locate(20,testCase);
+                osMutexRelease(displayMutex);*/
+                led1=1;
+                aSense=1;
+                Thread::wait(1);
+                aSense=0;
+                led1=0;
+                /*osMutexWait(displayMutex, osWaitForever);
+                console.printf("AS : %d      ",t.read_ms());
+                osMutexRelease(displayMutex);*/
+                Thread::wait(nAVI-delta);
+                led2=1;
+                vSense=1;
+                Thread::wait(1);
+                vSense=0;
+                led2=0;  
+                /*osMutexWait(displayMutex, osWaitForever);
+                console.printf("VS : %d      ",t.read_ms());
+                osMutexRelease(displayMutex);*/
+                Thread::wait(nLRI-nAVI-delta);                             
+            }
+            testOn=false;
+            if(testResult[testCase])
+            {
+                osMutexWait(displayMutex, osWaitForever);
+                console.locate(0,testCase);
+                console.printf("test %d pass",testCase+1);
+                osMutexRelease(displayMutex);
+            }
+            else
+            {
+                osMutexWait(displayMutex, osWaitForever);
+                console.locate(0,testCase);
+                console.printf("test %d fail",testCase+1);
+                osMutexRelease(displayMutex);                
+            }
+            //synch with PM
+            //TestCase 4 - No sensing;Only pacing;
+            testCase=3;
+            synchDone=false;
+            Thread::signal_wait(0x05);
+            synchDone=true;
+            t.reset();
+            testOn=true;
+            for(int i=0;i<1;i++)
+            {
+                osMutexWait(displayMutex, osWaitForever);
+                console.locate(20,testCase);
+                osMutexRelease(displayMutex);
+                t.reset();
+                testResult[testCase]=false;
+                Thread::wait(nLRI-nAVI+delta);
+                if(!testResult[testCase])
+                {
+                    console.printf("Here");
+                    break;
+                }
+                testResult[testCase]=false;           
+                Thread::wait(nAVI);    
+                if(!testResult[testCase])
+                {
+                    console.printf("There");
+                    break;
+                }
+            }
+            testOn=false;
+            if(testResult[testCase])
+            {
+                osMutexWait(displayMutex, osWaitForever);
+                console.locate(0,testCase);
+                console.printf("test %d pass",testCase+1);
+                osMutexRelease(displayMutex);
+            }
+            else
+            {
+                osMutexWait(displayMutex, osWaitForever);
+                console.locate(0,testCase);
+                console.printf("test %d fail",testCase+1);
+                osMutexRelease(displayMutex);                
+            }
+
+            //synch with PM
+            //TestCase 5 - Vsense at VRP+; APace at LRI-AVI+delta
+            testCase=4;
+            testResult[testCase]=false;
+            osMutexWait(displayMutex, osWaitForever);
+            console.locate(20,testCase);
+            osMutexRelease(displayMutex);
+            synchDone=false;
+            Thread::signal_wait(0x05);
+            synchDone=true;
+            t.reset();
+            Thread::wait(nPVARP);
+            led2=1;
+            vSense=1;
+            Thread::wait(1);
+            vSense=0;
+            led2=0;
+            osMutexWait(displayMutex, osWaitForever);
+            console.printf("VS : %d      ",t.read_ms());
+            osMutexRelease(displayMutex);
+            testOn=true;
+            Thread::wait(nLRI-nAVI+delta);
+            testOn=false;
+            if(testResult[testCase])
+            {
+                osMutexWait(displayMutex, osWaitForever);
+                console.locate(0,testCase);
+                console.printf("test %d pass",testCase+1);
+                osMutexRelease(displayMutex);
+            }
+            else
+            {
+                osMutexWait(displayMutex, osWaitForever);
+                console.locate(0,testCase);
+                console.printf("test %d fail",testCase+1);
+                osMutexRelease(displayMutex);                
+            }
             
-
-        } else if(flag_key==1&&(key_input=='t'||key_input=='T')) {
-            mode=Test;
-            (*testmode).signal_set(0x03);
-            pc.printf("Test");
-            flag_key=0;
+            //synch with PM
+            //TestCase 6 - Asense at VRP+ (within PVARP); A pace should come at LRI-AVI+delta and no VPace should come
+            testCase=5;
+            testResult[testCase]=false;
+            osMutexWait(displayMutex, osWaitForever);
+            console.locate(20,testCase);
+            osMutexRelease(displayMutex);
+            synchDone=false;
+            Thread::signal_wait(0x05);
+            synchDone=true;
+            t.reset();
+            Thread::wait(nVRP);
+            led1=1;
+            aSense=1;
+            Thread::wait(1);
+            aSense=0;
+            led1=0;
+            osMutexWait(displayMutex, osWaitForever);
+            console.printf("AS : %d      ",t.read_ms());
+            osMutexRelease(displayMutex);
+            testOn=true;
+            Thread::wait(nLRI-nAVI-nVRP+delta);
+            testOn=false;
+            if(testResult[testCase])
+            {
+                osMutexWait(displayMutex, osWaitForever);
+                console.locate(0,testCase);
+                console.printf("test %d pass",testCase+1);
+                osMutexRelease(displayMutex);
+            }
+            else
+            {
+                osMutexWait(displayMutex, osWaitForever);
+                console.locate(0,testCase);
+                console.printf("test %d fail",testCase+1);
+                osMutexRelease(displayMutex);                
+            }
+            
+            //synch with PM
+            //TestCase 7 - Vsense at VRP-; Asense should come at LRI-AVI+delta; Asense does not come after that, which would happen if Vsense was accepted
+            testCase=6;
+            testResult[testCase]=false;
+            osMutexWait(displayMutex, osWaitForever);
+            console.locate(20,testCase);
+            osMutexRelease(displayMutex);
+            synchDone=false;
+            Thread::signal_wait(0x05);
+            synchDone=true;
+            t.reset();
+            Thread::wait(nVRP-delta-10);            //give vSense within VRP
+            led2=1;
+            vSense=1;
+            Thread::wait(1);
+            vSense=0;
+            led2=0;
+            osMutexWait(displayMutex, osWaitForever);
+            console.printf("VS : %d      ",t.read_ms());
+            osMutexRelease(displayMutex);
+            testOn=true;
+            Thread::wait(nLRI-nAVI-nVRP+(2*delta)+10);
+            testOn=false;
+            if(testResult[testCase])
+            {
+                osMutexWait(displayMutex, osWaitForever);
+                console.locate(0,testCase);
+                console.printf("test %d pass",testCase+1);
+                osMutexRelease(displayMutex);
+            }
+            else
+            {
+                osMutexWait(displayMutex, osWaitForever);
+                console.locate(0,testCase);
+                console.printf("test %d fail",testCase+1);
+                osMutexRelease(displayMutex);                
+            }
+            t.stop();
+            //synch with PM
+            //TestCase 8 - Alarm High case; generate Asense and Vsense at very high rate
+            testCase=7;
+            testResult[testCase]=false;
+            osMutexWait(displayMutex, osWaitForever);
+            console.locate(0,testCase);
+            console.printf("Alarm High");
+            osMutexRelease(displayMutex);
+            synchDone=false;
+            Thread::signal_wait(0x05);
+            synchDone=true;
+            for(int i=0;i<5000;i++)
+            {
+                led1=1;
+                aSense=1;
+                Thread::wait(1);
+                aSense=0;
+                led1=0;
+                led2=1;
+                vSense=1;
+                Thread::wait(1);
+                vSense=0;
+                led2=0;                            
+            }
+            osMutexWait(displayMutex, osWaitForever);
+            console.locate(0,testCase+1);
+            console.printf("Testing Complete");
+            osMutexRelease(displayMutex);
             
         }
-        keymutex.unlock();
-    }
-}
-
-
-void display(void const* args)
-{
-    while(1) {
-        Thread::wait(observationInterval/1000);
-//        if(mode!=Test) {
-//            if(mode!= changeobservationinterval) {
-//                avgHeartRate=pulseCount*60000/(obsInterval);
-//                pulseCount = 0;
-//                updateDisplay();
-//
-//            }
-//        }
-        if(!Test) {
-            heartmut.lock();
-            pc.printf("Avg Heart Rate: %02d bpm", heartRate);
-            heartmut.unlock();
-            while(!Vreceived||!VSignal==0) {
-                updateHeart();
+        if(changeMode)
+        {
+            changeMode=false;
+            if(changeModeTo==0)
+            {
+                heartMode=0;
+                strcpy(modeString,"Random");
+                osMutexWait(displayMutex, osWaitForever);
+                console.cls();
+                console.locate(30, 10);
+                console.printf("Heart Rate :  %03d bpm", avgHeartRate);
+                console.locate(30, 12);
+                console.printf("Observation Interval :  %02d seconds", observationInterval/1000);
+                console.locate(30, 14);
+                console.printf("Mode :  %s", modeString);
+                osMutexRelease(displayMutex);
+                (*HeartSensePTR).signal_set(0x02);
             }
-            while(k<=heartInterval*1000);
-            if(heartRate>high[mode]) {
-                sound_highAlarm();
-                heartmut.lock();
-                heartRate=0;
-                heartmut.unlock();
-                resetk();
-            } else if(heartRate<low[mode]) {
-                sound_lowAlarm();
-                heartmut.lock();
-                heartRate=0;
-                heartmut.unlock();
-                resetk();
-            } else if(heartRate  >= low[mode]  && heartRate  <= high[mode]) {
-                heartmut.lock();
-                heartRate=0;
-                heartmut.unlock();
-                resetk();
+            else
+            {
+                heartMode=1;
+                strcpy(modeString,"Manual");
+                osMutexWait(displayMutex, osWaitForever);
+                console.cls();
+                console.locate(30, 10);
+                console.printf("Heart Rate :  %03d bpm", avgHeartRate);
+                console.locate(30, 12);
+                console.printf("Observation Interval :  %02d seconds", observationInterval/1000);
+                console.locate(30, 14);
+                console.printf("Mode :  %s", modeString);
+                osMutexRelease(displayMutex);
             }
-
-
+            
         }
     }
 }
 
-
-void Testmode(void const* args)
+void aPace()
 {
-    Thread::wait(0x03);
-    test = true;
-    switch(test) {
-        case 1:
-            flag=0;
-            Thread::signal_wait(0x04);
-            flag=1;
-            t = 0;
-            Thread::wait(vrp);
-            ASignalsend();
-            test = true;
-            Thread::wait(lri-avi-vrp);
-            test_result=false;
-            if(test_result) {
-                pc.printf("Test %u passed",test);
-                test=2;
-            } else {
-                pc.printf("Test %u failed",test);
-                test=2;
-            }
-            break;
-
-        case 2:
-            flag=0;
-            Thread::signal_wait(0x04); //Send A after PVARP
-            flag=1;
-            t = 0;
-            Thread::wait(pvarp);
-            ASignalsend();
-
-            Thread::wait(uri-pvarp-delta);
-
-            if(test_result) {
-                pc.printf("Test %u passed", &test_result);
-                test=3;
-            } else {
-                pc.printf("Test %u failed", &test_result);
-                test=3;
-            }
-            break;
-
-        case 3:
-            flag=0;
-            Thread::signal_wait(0x04);
-            flag=1;
-            t = 0;
-            Thread::wait(uri);
-            for(int i = 0; i<7; i++) {
-                ASignalsend();
-                Thread::wait(avi-delta);
-                VSignalsend();
-                Thread::wait(lri-avi-delta);
-            }
-            if(test_result) {
-                pc.printf("Test %u passed", &test_result);
-                test=4;
-            } else {
-                pc.printf("Test %u failed", &test_result);
-                test=4;
-            }
-            break;
-        case 4:
-            flag=0;
-            Thread::signal_wait(0x04); //Send A after PVARP
-            flag=1;
-            t = 0;
-            Thread::wait(pvarp);
-            ASignalsend();
-
-            Thread::wait(uri-pvarp-delta);
+    if(heartMode==0)
+    {
+        SenseWaitTimer->start(50+(rand()%2000));         //TODO move this
+    }
+    led3=1;
+    wait(0.01);
+    led3=0;
+    if(heartMode==2 && testOn)
+    {
+         receivedVPace=false;
+        (*TestDisplayPTR).signal_set(0x06);
+        if(testCase==2)
+        {
+            testResult[testCase]=false;            
+        }
+        else if(testCase==3 || testCase==4 || testCase==5 || testCase==6)
+        {
+             testResult[testCase]=true;   
+        }
+    }
+}
 
-            if(test_result) {
-                pc.printf("Test %u passed", &test_result);
-                test=5;
-            } else {
-                pc.printf("Test %u failed", &test_result);
-                test=5;
-            }
-            break;
-        case 5:
-            flag=0;
-            Thread::signal_wait(0x04); //Heart is dead
-            flag=1;
-            t = 0;
-
-            Thread::wait(lri);
-            Thread::wait(lri);
-            test = false;
-            if(test_result) {
-                pc.printf("Test %u passed", &test_result);
-                test=6;
-            } else {
-                pc.printf("Test %u failed", &test_result);
-                test=6;
-            }
-            break;
-
-        case 6:
-            flag=0;
-            Thread::signal_wait(0x04); //Heart beating very fast. ASig, VSig
-            flag=1;
-            t = 0;
-            for(int i = 0; i<50; i++) {
-                ASignalsend();
-                VSignalsend();
-            }
-            if(test_result) {
-                pc.printf("Test %u passed", &test_result);
-                test=7;
-            } else {
-                pc.printf("Test %u failed", &test_result);
-                test=7;
-            }
-            break;
-
-        case 7:
-            flag=0;
-            Thread::signal_wait(0x04); //Wait for VPace to be received
-            flag=1;
-            t= 0;
-            Thread::wait(uri);
-            ASignalsend();
-            Thread::wait(avi+delta);
-            if(test_result) {
-                pc.printf("Test %u passed", &test_result);
-                test=8;
-            } else {
-                pc.printf("Test %u failed", &test_result);
-                test=8;
-            }
-
-            break;
-
-        case 8:
-            flag=0;
-            Thread::signal_wait(0x04); //Send an extra V to see if LRI starts then
-            flag=1;
-            t = 0;
-            Thread::wait(pvarp);
-            VSignalsend();
-            Thread::wait(lri-avi-delta);
-            if(test_result) {
-                pc.printf("Test %u passed", &test_result);
-                test=0;
-            } else {
-                pc.printf("Test %u failed", &test_result);
-                test=0;
-            }
-            break;
-
+void vPace()
+{
+    if(heartMode==0)
+    {
+        SenseWaitTimer->start(50+(rand()%2000));         //TODO move this
+    }
+    led4=1;
+    wait(0.01);
+    led4=0;
+    osMutexWait(heartRateMutex, osWaitForever);
+    heartRate++;
+    osMutexRelease(heartRateMutex);
+    if(heartMode==2 && !synchDone)
+    {
+        (*TestModePTR).signal_set(0x05);
+    }
+    if(heartMode==2 && testOn)
+    {
+        receivedVPace=true;
+        (*TestDisplayPTR).signal_set(0x06);
+        if(testCase==0 || testCase==2 || testCase==5 || testCase==6)
+        {
+            testResult[testCase]=false;            
+        }
+        else if(testCase==1 || testCase==3)
+        {
+            testResult[testCase]=true;
+        }
     }
 }
 
+void testDisplay(const void *args)
+{
+    while(1)
+    {
+        Thread::signal_wait(0x06);
+        if(receivedVPace)
+        {
+            osMutexWait(displayMutex, osWaitForever);
+            console.printf("VP : %d      ",t.read_ms());
+            osMutexRelease(displayMutex);
+        }
+        else
+        {
+            osMutexWait(displayMutex, osWaitForever);
+            console.printf("AP : %d      ",t.read_ms());
+            osMutexRelease(displayMutex);           
+        }
+    }
+}
+        
+
+void serialThread(const void *args)
+{
+    while(1)
+    {
+        Thread::signal_wait(0x01);
+        if((((ch=='a')||(ch=='A')) && heartMode==1) && !observationChange)
+        {
+            //fire A Signal
+            led1=1;
+            aSense=1;
+            Thread::wait(1);
+            led1=0;
+            aSense=0;
+        }
+        else if((((ch=='v')||(ch=='V')) && heartMode==1) && !observationChange)
+        {
+            //fire V Signal
+            led2=1;
+            vSense=1;
+            Thread::wait(1);
+            vSense=0;
+            led2=0;
+            osMutexWait(heartRateMutex, osWaitForever);
+            heartRate++;
+            osMutexRelease(heartRateMutex);
+        }
+        else if(((((ch=='r')||(ch=='R'))&& heartMode!=0) && !observationChange) && !changeMode)
+        {
+            if(heartMode==2)
+            {
+                changeMode=true;
+                changeModeTo=0;
+                console.locate(30, 14);
+                console.printf("Mode :  %s (Pending - Random)", modeString);                
+            }
+            else
+            {                
+                heartMode=0;
+                strcpy(modeString,"Random");
+                resetDisplay();
+                (*HeartSensePTR).signal_set(0x02);
+            }
+        }
+        else if(((((ch=='m')||(ch=='M')) && heartMode!=1) && !observationChange) && !changeMode)
+        {
+            if(heartMode==2)
+            {
+                changeMode=true;
+                changeModeTo=1;
+                console.locate(30, 14);
+                console.printf("Mode :  %s (Pending - Manual)", modeString);
+            }
+            else
+            {
+                heartMode=1;
+                strcpy(modeString,"Manual");
+                resetDisplay();
+            }
+        }
+        else if((((ch=='t')||(ch=='T')) && heartMode!=2) && !observationChange)
+        {
+            heartMode=2;            //spawn Test Thread
+            strcpy(modeString,"Test");
+            resetDisplay();
+            (*TestModePTR).signal_set(0x04);
+        }
+        else if((((ch=='o')||(ch=='O')) && !observationChange) && heartMode!=2)
+        {
+            observationChange=true;
+            digitOneReceived=false;
+            digitTwoReceived=false;
+            //spawn a timer for  3 seconds
+            osMutexWait(displayMutex, osWaitForever);
+            console.locate(29, 16);
+            console.printf("Observation Interval change : -- seconds");
+            osMutexRelease(displayMutex);
+            KeyTimeOutTimer=new RtosTimer(keyTimeOut, osTimerOnce, (void *)0);
+            KeyTimeOutTimer->start(3000);
+        }
+        else if((observationChange) && ((ch>=48) && (ch<=57)) && !digitTwoReceived)
+        {
+            if(!digitOneReceived)
+            {
+                KeyTimeOutTimer->start(3000);                       //key time out is 3 seconds
+                osMutexWait(observationChangeMutex, osWaitForever);         //mutex to be released either on time out or if 2 digits are received
+                observationRate=ch-'0';
+                osMutexRelease(observationChangeMutex);
+                digitOneReceived=true;
+                osMutexWait(displayMutex, osWaitForever);
+                console.locate(60, 16);
+                console.printf("%02d", observationRate);
+                osMutexRelease(displayMutex);
+            }
+            else
+            {
+                KeyTimeOutTimer->stop();
+                digitTwoReceived=true;
+                osMutexWait(observationChangeMutex, osWaitForever);
+                observationRate=(observationRate*10)+(ch-'0');
+                osMutexRelease(observationChangeMutex);
+                observationChange=false;
+                osMutexWait(displayMutex, osWaitForever);
+                console.locate(60, 16);
+                console.printf("%02d", observationRate);
+                osMutexRelease(displayMutex);
+            }
+        }                
+    }
+}
+
+// Interupt Routine to read in data from serial port and call the serial thread
+void Rx_interrupt() 
+{
+    if(console.readable())
+    {
+        ch=LPC_UART0->RBR;                  //read uart buffer data and clear the interrupt flag
+        (*SerialThreadPTR).signal_set(0x01);     //initiate the serial thread to change the state of the timer
+    }
+    
+}
 
 
-int main()
+int main() 
 {
-    pc.baud(9600);
-    VPace.rise(&VPacereceived);
-    APace.rise(&APacereceived);
-    timer0_init();
-    Thread heartreceive(HeartReceive);
-    Thread heartsend(HeartSend);
-    Thread heartkeyboard(HeartKeyBoardModeSwitch);
-    hmode = &heartkeyboard;
-    Thread disPlay(display);
-    Thread tmode(Testmode);
-    testmode = &tmode;
-
-    while(1) {
-        if(pc.readable()) {
-            key_input=pc.getc();                  //read uart buffer data and clear the interrupt flag
-            //initiate the serial thread to change the state of the timer
-            pc.printf("setting");
-            flag_key=1;
-            if(key_input=='o'||key_input=='O'||key_input=='m'||key_input=='M'||key_input=='t'||key_input=='T')
-            flagr=0;
-            pc.printf("set");
-        }
-    }
+    console.attach(&Rx_interrupt, Serial::RxIrq);        //attach a uart interrupt for uart
+    console.cls();
+    console.locate(30, 6);
+    console.printf("Heart Display");
+    console.locate(30, 10);
+    console.printf("Heart Rate :  ---- bpm");
+    console.locate(30, 12);
+    console.printf("Observation Interval :  -- seconds");
+    console.locate(30, 14);
+    console.printf("Mode :  Random ");
+    
+    //initialize variables
+    heartMode=0;
+    heartRate=0;
+    avgHeartRate=0;
+    waitCount=0;
+    observationInterval=5000;
+    rateCoefficient=(60000/observationInterval);
+    observationChange=false;
+    observationRate=5;
+    digitOneReceived=false;
+    strcpy(modeString,"Random");
+    synchDone=true;
+    testCase=0;
+    testOn=false;
+    digitTwoReceived=false;
+    changeMode=false;
+    changeModeTo=0;
+    receivedVPace=false;
+    
+    SenseWaitTimer=new RtosTimer(senseWait, osTimerOnce, (void *)0);
+    Thread SerialThread(serialThread);
+    SerialThreadPTR=&SerialThread;
+    SerialThread.set_priority(osPriorityRealtime);
+    Thread HeartSense(heartSense);
+    HeartSensePTR=&HeartSense;
+    HeartSense.set_priority(osPriorityHigh);
+    Thread Display(display);
+    Display.set_priority(osPriorityAboveNormal);
+    Thread TestMode(testMode);
+    TestModePTR=&TestMode;
+    TestMode.set_priority(osPriorityAboveNormal);
+    Thread TestDisplay(testDisplay);
+    TestDisplayPTR=&TestDisplay;
+    TestDisplay.set_priority(osPriorityHigh);
+    APace.fall(&aPace);
+    VPace.fall(&vPace);
+    
+    while(1);
 }
\ No newline at end of file