Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: TextLCD mbed-rtos mbed
Fork of PacemakerController by
PacemakerController.cpp.orig
- Committer:
- amiche
- Date:
- 2015-12-02
- Revision:
- 49:62ffd451b1c7
- Parent:
- 23:08456978fb78
File content as of revision 49:62ffd451b1c7:
#include "mbed.h"
#include "LPC17xx.h"
#include "TextLCD.h"
#include "rtos.h"
#include "Thread.h"
using namespace rtos;
// This is for the pacemaker
volatile unsigned short timer_count;
Serial pc(USBTX, USBRX);
TextLCD lcd(p15, p16, p17, p18, p19, p20, TextLCD::LCD20x4); // rs, e, d4-d7
int keyboard_needs_numeric = 0; // boolean - is in middle of interval input?
int h_clock;
int pm_clock;
Timer avi_clock;
int LRI = 1000;
int AVI = 150;
int PVARP = 300;
int VRP = 200;
// constants
int MAX_PM_RT = 180;
int MIN_PM_RT = 40;
enum mode {NORMAL, SLEEP, EXERCISE, MANUAL};
// counters
int beats = 0;
// state variables
int upper_bound = 100;
int lower_bound = 40;
int obs_int = 10;
mode curr_mode = NORMAL;
// alarms
DigitalOut led_apace(LED1);
DigitalOut led_vpace(LED2);
DigitalOut Asense(LED3);
DigitalOut Vsense(LED4);
DigitalOut apace(p22):
DigitalOut vpace(p21):
// hardware interrupt handler, adapted from code in piazza post by Dagaen
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
timer_count++; //increment timer_count
}
}
// init the hardware interrupt (timer0), adapted same as above
void timer0_init(void)
{
LPC_SC->PCONP |=1<1; //timer0 power on
LPC_SC-> PCLKSEL0 |= 1 << 2; // set timer clock to CCLCK nondivided (1 clock cycle = 1 increment)
LPC_TIM0->MR0 = 1000000; //100mhz clock cycle, 1 cycle = 10ns, 10ms = 10 000 000 ns = 1M cycles
LPC_TIM0->MCR = 3; //interrupt and reset control
//3 = Interrupt & reset timer0 on match (111) sets all three bits
NVIC_EnableIRQ(TIMER0_IRQn); //enable timer0 interrupt
}
void PM_ALARM(void const *argument)
{
// min hr alarm
if( beats < MIN_PM_RT) {
lcd.locate(0,1);
lcd.printf("!<");
}
// max hr alarm
if(beats > MAX_PM_RT) {
lcd.locate(0,1);
lcd.printf("!>");
}
}
// hw interrupt callback, deal with the keyboard input from PC
void keyboard_handler()
{
// get the char, put it on the PC command line
char a = pc.getc();
if (keyboard_needs_numeric) {
if (a >= '0' && a <= '9') {
// update observation interval
obs_int = (a - '0' + 1) * 5;
} else {
pc.printf("Expected numeric key\n");
}
} else if(a == 'N') {
// if the char is N, update bounds to normal mode
curr_mode = NORMAL;
upper_bound = 100;
lower_bound = 40;
pc.printf("MODE IS N\n");
// if the char is S, set bounds to sleep
} else if (a == 'S') {
curr_mode = SLEEP;
upper_bound = 60;
lower_bound = 30;
pc.printf("MODE IS S\n");
// if the char is E, set bounds to exercise
} else if (a == 'E') {
curr_mode = EXERCISE;
upper_bound = 175;
lower_bound = 100;
pc.printf("MODE IS E\n");
beats = 2;
// if the char is M, set to manual
} else if (a == 'M') {
curr_mode = MANUAL;
upper_bound = 175;
lower_bound = 30;
beats = 300;
pc.printf("MODE IS MANUAL\n");
// check for A if mode is manual
} else if (a == 'A') {
if(curr_mode == MANUAL) {
pc.printf("MODE IS MANUAL GOT APACE\n");
}
// check for V is mode is manual
} else if (a == 'V') {
if(curr_mode == MANUAL) {
pc.printf("MODE IS MANUAL GOT VPACE\n");
}
} else if (a == 'O') {
keyboard_needs_numeric = 1;
} else {
// do nothing for invalid char
}
}
void pm_sense()
{
while(1) {
if (timer_count >= VRP) {
//wait for Vget;
timer_count = 0;
// do something with Vsense!
} else if (timer_count < VRP) {
// wait for Vget
}
if (timer_count < PVARP) {
// wait for Aget?
} else if (timer_count >= PVARP) {
// wait for Aget?
// do something with Asense!
}
}
}
void pm_response()
{
while(1) {
if (timer_count >= LRI-AVI) {
// PM_A! sets the LED high
led_apace = 1;
// avi_clk = 0
avi_clk.reset();
apace();
// At Atrial Event State
while (avi_clk.read() < AVI);
// Ventricular Event
timer_count = 0;
// PM_V! sets the LED high
led_vpace = 1;
timer_count = 0;
vpace();
} else if (timer_count < LRI - AVI) {
// avi_clk = 0
avi_clk.reset();
// wait for Asense? naaah
}
}
}
void apace()
{
apace = 1;
led_apace = 1;
Thread::wait(10);
apace = 0;
}
void vpace()
{
vpace = 1;
led_vpace = 1;
Thread::wait(10);
vpace = 0;
}
int main()
{
// https://developer.mbed.org/users/chadnach1/code/PacemakerController/
// connect the serial device (PC keybd) to the interrupt
pc.attach(&keyboard_handler);
// Start LED's Off
led_apace = 0;
led_vpace = 0;
// Start the avi_clock
avi_clk.start();
Thread t3(pm_sense);
Thread t4(pm_response);
Thread t2(PM_ALARM);
Thread t5();
}
