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 pacemaker_SINGLETIMER_v1 by
main.cpp
- Committer:
- jfields
- Date:
- 2014-12-03
- Revision:
- 1:ea01c3232c4a
- Parent:
- 0:3afa00a23ce2
- Child:
- 2:3773afd2256c
File content as of revision 1:ea01c3232c4a:
#include "mbed.h"
#include "rtos.h"
#include "TextLCD.h"
#include <stdio.h>
#include <stdlib.h>
#define RUN 0x1
TextLCD lcd(p15, p16, p17, p18, p19, p20, TextLCD::LCD16x2);
Serial pc (USBTX, USBRX);
// ports
DigitalIn VGet(p11);
DigitalIn AGet(p12);
DigitalOut VPace(p13);
DigitalOut APace(p14);
// LEDs
DigitalOut leds[] = {LED1, LED2, LED3, LED4};
// 1 = VP
// 2 = AP
// 3 = VS
// 4 = AS
// global clocks
Timer ta; // time since a event
Timer tv; // time since v event
// mutexes
Mutex t_mutex; // protect reading of ta, tv
Mutex status_mutex; // protect reading of
Mutex input_mutex; // protects reading input
// input stuff
char input;
// heart rate global vars
int HR = 0;
int beats = 0;
int sampleRate = 10000; // default 10 seconds
int firstSample = 1;
// Normal Values
const int N_PVARP = 325; // ms
const int N_VRP = 300; // ms
const int N_LRI = 857; // ms (= about 70ppm)
const int N_AVI = 65; // ms
const int N_UB = 100; // 100ppm
const int N_LB = 40; // 40ppm
// Exercise Values
const int E_PVARP = 175; // ms
const int E_VRP = 150; // ms
const int E_LRI = 428; // ms (= about 140ppm)
const int E_AVI = 30; // ms
const int E_UB = 175; // 175ppm
const int E_LB = 100; // 100ppm
// Sleep Values
const int S_PVARP = 500; // ms
const int S_VRP = 475; // ms
const int S_LRI = 1333; // ms (= about 45ppm)
const int S_AVI = 100; // ms
const int S_UB = 60; // 60ppm
const int S_LB = 30; // 30ppm
// Heart Values - Normal Mode is default
int PVARP = N_PVARP;
int VRP = N_VRP;
int LRI = N_LRI;
int AVI = N_AVI;
int UB = N_UB;
int LB = N_LB;
// status flags
int isVRP = 0;
int isPVARP = 0;
int waitingForV = 1;
// functions
void VP_func(void const *args);
void AP_func(void const *args);
void VS_func(void const *args);
void AS_func(void const *args);
void manage_flags(void const *i);
void send_Apace();
void send_Vpace();
void listen_Aget(void const *args);
void listen_Vget(void const *args);
void flashLED(int i);
void blind();
void Aevent();
void calcHR(void const *args);
void disp(void const *args);
void input_func(void const *args);
void setVals(char c);
// threads
Thread * VS_thread;
Thread * AS_thread;
Thread * VP_thread;
Thread * AP_thread;
Thread * VG_thread;
Thread * AG_thread;
Thread * input_thread;
Thread * disp_thread;
// rtos timers
RtosTimer * VRP_timer;
RtosTimer * PVARP_timer;
RtosTimer * HR_timer;
int main() {
// start global timer
tv.start();
ta.start();
tv.stop();
// init threads
disp_thread = new Thread(disp);
VS_thread = new Thread(VS_func);
AS_thread = new Thread(AS_func);
VP_thread = new Thread(VP_func);
AP_thread = new Thread(AP_func);
VG_thread = new Thread(listen_Vget);
AG_thread = new Thread(listen_Aget);
input_thread = new Thread(input_func);
// init timers
VRP_timer = new RtosTimer(manage_flags, osTimerOnce, (void *)1);
PVARP_timer = new RtosTimer(manage_flags, osTimerOnce, (void *)2);
HR_timer = new RtosTimer(calcHR, osTimerPeriodic, (void *)0);
// start display and heart rate sample
HR_timer->start(sampleRate);
disp_thread->signal_set(RUN);
// main thread
while (1) {
}
}
void input_func(void const *args) {
while (1) {
input_mutex.lock();
input=pc.getc();
if (input == 'n') setVals('n');
if (input == 's') setVals('s');
if (input == 'e') setVals('e');
input_mutex.unlock();
}
}
void calcHR(void const *args) {
if (firstSample == 1) {
HR = beats*(60000/sampleRate);
firstSample = 0;
}
else {
HR = (beats*60000/sampleRate+HR)/2;
}
disp_thread->signal_set(RUN);
}
void disp(void const *args) {
while (1) {
Thread::signal_wait(RUN,osWaitForever);
lcd.printf("HR = %d ppm\nCyle = %d s\n",HR,sampleRate/1000);
beats = 0;
}
}
void manage_flags(void const *i) {
status_mutex.lock();
if ((int)i==1) isVRP = 0;
if ((int)i==2) isPVARP = 0;
status_mutex.unlock();
}
void AP_func(void const *args) {
while (1) {
t_mutex.lock();
if (tv.read_ms() >= (LRI-AVI)) {
Aevent();
send_Apace();
flashLED(2);
}
t_mutex.unlock();
}
}
void VP_func(void const *args) {
while (1) {
t_mutex.lock();
if (ta.read_ms() >= AVI) {
blind();
send_Vpace();
flashLED(1);
}
t_mutex.unlock();
}
}
void AS_func(void const *args) {
while (1) {
Thread::signal_wait(RUN,osWaitForever);
t_mutex.lock();
Aevent();
flashLED(4);
t_mutex.unlock();
}
}
void VS_func(void const *args) {
while (1) {
Thread::signal_wait(RUN,osWaitForever);
t_mutex.lock();
blind();
flashLED(3);
t_mutex.unlock();
}
}
void listen_Vget(void const *args) {
while (1) {
if (VGet==1) {
status_mutex.lock();
if (!isVRP && waitingForV) VS_thread->signal_set(RUN);
status_mutex.unlock();
while(VGet == 1);
}
}
}
void listen_Aget(void const *args) {
while (1) {
if (AGet == 1) {
status_mutex.lock();
if (!isPVARP && !waitingForV) AS_thread->signal_set(RUN);
status_mutex.unlock();
while(AGet == 1);
}
}
}
void flashLED(int i) {
leds[i-1] = 1;
wait(0.01);
leds[i-1] = 0;
}
void blind() {
tv.start();
ta.reset();
ta.stop();
status_mutex.lock();
isVRP = 1;
isPVARP = 1;
waitingForV = 0;
status_mutex.unlock();
VRP_timer->start(VRP);
PVARP_timer->start(PVARP);
beats++;
}
void Aevent() {
ta.start();
tv.reset();
tv.stop();
status_mutex.lock();
waitingForV = 1;
status_mutex.unlock();
}
void send_Apace() {
APace = 1;
Thread::wait(2);
APace = 0;
}
void send_Vpace() {
VPace = 1;
Thread::wait(2);
VPace = 0;
}
void setVals(char c) {
if (c == 'n') {
PVARP = N_PVARP;
VRP = N_VRP;
LRI = N_LRI;
AVI = N_AVI;
UB = N_UB;
LB = N_LB;
}
if (c == 's') {
PVARP = S_PVARP;
VRP = S_VRP;
LRI = S_LRI;
AVI = S_AVI;
UB = S_UB;
LB = S_LB;
}
if (c == 'e') {
PVARP = E_PVARP;
VRP = E_VRP;
LRI = E_LRI;
AVI = E_AVI;
UB = E_UB;
LB = E_LB;
}
}
