the complete model of the heart model

Dependencies:   TextLCD mbed-rtos mbed

Fork of heart by William Archer

main.cpp

Committer:
shengtiz
Date:
2016-11-30
Revision:
4:453a2f967f52
Parent:
3:5941bb3c4fc2

File content as of revision 4:453a2f967f52:

#include "mbed.h"
#include "rtos.h"
#include "TextLCD.h"
#include <time.h>
#include <stdlib.h>

//use screen /dev/tty.. on mac in terminal to receive input

TextLCD lcd(p15,p16,p17,p18,p19,p20,TextLCD::LCD16x2);
Serial pc(USBTX, USBRX); //set up serial
DigitalOut natAPace(LED1); //leds for pacing
DigitalOut natVPace(LED2);
DigitalOut aPace(LED3);
DigitalOut vPace(LED4);
DigitalOut a_signal(p6); //connected to pm
DigitalOut v_signal(p7); //connected to pm
DigitalIn apace_signal(p8); //connected to pm
DigitalIn vpace_signal(p9); //connected to pm

Timer atimer;   //timer for atrial event
Timer vtimer;   //timer for ventricular event

unsigned int a_time = 0;
unsigned int v_time = 0;

int mode = 0; //0 = random, 1 = manual, 2 = test
int modeInManul = -1; //0 = manualmode apace, 1 = manualmode vpace
bool modeSwitch = false;

//the following flags indicate pacing signals either from the heart or the pacemaker
bool natural_apace = false;
bool natural_vpace = false;
bool apace = false;
bool vpace = false;

//constants
const int minwait_A = 100; //in miliseconds
const int minwait_V = 200; //in miliseconds
/*
//so far no use of the following in the heart model
const int LRI = 1000;
const int VRP = 400;
const int PVARP = 500;
const int URI = 1000;
const int AVI = 100;
*/

void switch_modes() {
    switch(mode) {
        case 0:
            break;
        case 1:
            break;
        case 2:
            break;
        
    }    
}

void send_signal(int type) { //type=0 a_signal, type=1 v_signal
        
        switch(type) {
            case 0:
                a_signal = 1;
            case 1:
                v_signal = 1;
        }
}

void modeSwitchDelay(){
    //srand(time(NULL));
    //int time = rand()%9700 + 300;
    Thread::wait(1000);   
}

void heart_keyboard() {
    while(true) { //thread is continuously running
            if(pc.readable()) {
                char c = pc.getc();
                
                switch(c) {
                    case 'r': //set to random mode
                        mode = 0;
                        modeSwitch = true;
                        break;
                    case 'm': //mset to manual mode
                        mode = 1;
                        modeSwitch = true;
                        break;
                    case 't': //set to test mode
                        mode = 2;
                        modeSwitch = true;
                        break;
                    case 'a': //asignal
                        if(mode == 1) { //only if in manual (heart_mode == 1)
                            modeInManul = 0;
                        }
                        break;
                    case 'v': //vsignal
                        if(mode == 1) { //only if in manual (heart_mode == 1)
                            modeInManul = 1;
                        }
                        break; 
                    default: //erroneous key get rid of it
                        break;
                }
            }
    }
}

void tick() {
    a_time++;
    v_time++;   
}
// Blink functions gets called when there is an Atrial/V entricular event.
void natApaceBlink(){
    natAPace = 1;
    Thread::wait(50);
    natAPace = 0;
    Thread::wait(50);
}

void natVpaceBlink(){
    natVPace = 1;
    Thread::wait(50);
    natVPace = 0;
    Thread::wait(50);
}

void ApaceBlink(){
    aPace = 1;
    Thread::wait(50);
    aPace = 0;
    Thread::wait(50);
}

void VpaceBlink(){
    vPace = 1;
    Thread::wait(50);
    vPace = 0;
    Thread::wait(50);
}

void performModeDelay(){
    if(modeSwitch == true){
        modeSwitchDelay();
        modeSwitch = false;
    }
}

//generate the time the next atrial event will happen
int Atrial_generate(){
    srand(time(NULL));
    return rand()%2000 + minwait_A;
}

//generate the time the next ventricular event will happen. 
int Ventricular_generate(){
    srand(time(NULL));
    return rand()%2000 + minwait_V;
}

//The following two modules random_sensing and random_pacing are two components of the random mode.
void random_sensing(){
    int aTime = 0; //the time that the next atrial event will happen, 
                   //if the time exceeds the expected limit, then it will be regarded as heart malfunction
                   //and the signal from the pacemaker will take effect.
    int vTime = 0; //the time that the next ventricular event will happen, 
                   //if the time exceeds the expected limit, then it will be regarded as heart malfunction
                   //and the signal from the pacemaker will take effect.
    while(1){
        if(mode == 0){
            performModeDelay();
            //use random functions to generate the sensing signals.
            //asense time generate
            //detect if there is an apace signal from the pacemaker, if there is, reset asense clock
            //otherwise natural apace
            //and go into vsense.
            aTime = Atrial_generate();
            atimer.start();
            while(1){
                //the case when the hearth functions correctly
                 //this condition means the moment when vtimer passes aTime, the limit, and we still
                // did not receive apace_signal, then, it means the heart is working correctly.
                if(atimer.read_ms() >= aTime && !apace_signal){
                    atimer.stop();
                    atimer.reset();
                    send_signal(0);
                    natural_apace = true;
                    break;
                }
                
                //the case when the heart malfunctions in the Atrial
                if((atimer.read_ms () <= aTime) && apace_signal){
                    atimer.stop();
                    atimer.reset();
                    apace = true;
                    break;
                }
            }

            //detect if there is a vpace signal from the pacemaker, if there is, reset the vsense clock.
            //otherwise natural vpace
            vTime = Ventricular_generate();
            vtimer.start();
            while(1){
                //the case when the hearth functions correctly
                //this condition means the moment when vtimer passes vTime, the limit, and we still
                // did not receive vpace_signal, then, it means the heart is working correctly.
                if(vtimer.read_ms() >= vTime && !vpace_signal){
                    vtimer.stop();
                    vtimer.reset();
                    send_signal(1);
                    natural_vpace = true;
                    break;
                }
                
                //the case when the heart malfunctions in the Atrial
                if((vtimer.read_ms () <= vTime) && vpace_signal){
                    vtimer.stop();
                    vtimer.reset();
                    vpace = true;
                    break;
                }
            }
        }    
    }
}

void random_pacing(){
    while(1){
        if(mode == 0){
            performModeDelay();
            if(natural_apace){
                natApaceBlink();
                natural_apace = false;
            }
            
            if(natural_vpace){
                natVpaceBlink();
                natural_vpace = false;
            }
            
            if(apace){
                ApaceBlink();
                apace = false;
            }
            
            if(vpace){
                VpaceBlink();
                vpace = false;
            }
        }    
    }
}


//Heart Modes: Random, Manual, Test
void Random(){
    //TODO: heart behaviour in random mode
    Thread s(random_sensing);
    Thread p(random_pacing);
    while(1);
}

void Manual(){
    //TODO: heart behaviour in manual mode
    while(1){
        if(mode == 1){
            performModeDelay();
            //natVpaceBlink();
            if(modeInManul == 0){
                ApaceBlink();
                modeInManul = -1;
            }
            
            if(modeInManul == 1){
                VpaceBlink();
                modeInManul = -1;
            }
        }
    }   
}

void Test(){
    //TODO: heart behaviour in test mode
    while(1){
        if(mode == 2){
            performModeDelay();
            //ApaceBlink();
        }
    }
}

int main() {
    //TODO: Set up threads
    Thread keyboard(heart_keyboard);
    //Note: only one of the following threads will be on duty when heart runs
    //and it is done through checking the mode the heart is in.
    Thread random_(Random);
    Thread manual_(Manual);
    Thread test_(Test);
    while(1);
}