Bsp software Pulsuhr
Aus der Mikrocontroller.net Artikelsammlung, mit Beiträgen verschiedener Autoren (siehe Versionsgeschichte)
- ->Pulsuhrempfänger mit AVR Butterfly
- Source Code
/*
*/
char PROG_NAME[] = "Handy Board HRM ";
char PROG_DATE[] = "29-Jan-2003";
/*
Handy Board HRM was created to demonstrate how to
interface my HRM receiver circuit to a microcontroller.
This code requires the receiver to be connected to the
Handy Board's analog port 0. The algorithm used is
simplistic, but is sufficient to show how to detect the
transmitted heart beat signal and calculate a heart
rate. There are, however, some important limitations
to the algorithm and the code implementing it. Here
are some particular limitations you should be aware of
and some experiments you might try to better understand
their consequences:
1) Heart beats are detected with a simple fixed
trigger level. Consequently, magnetic noise in the
environment can cause erroneously high heart rates
to be calculated. Try this experiment, hold the
HRM receiver up to a computer CRT or even up close
to the Handy Board's own LCD. What happens to the
displayed heart rate? Try changing the DEAD_TIME
parameter in the code, now what heart rate is
displayed when you hold the HRM receiver up to the
Handy Board LCD?
2) The heart rate is recalculated at each heart
beat, so the displayed heart rate can vary
considerably with each beat. Try this experiment,
watch your heart beat displayed on the Handy Board
LCD as you slowly breath in and out. Is there a
pattern? Set a commercial HRM wrist style receiver
next to the Handy Board, how often is the
commercial unit's display being updated -- what
algorithm does the commercial unit seem to be
using?
3) The magnetic pulses generated by the HRM chest
strap transmitters are fairly short, typically
around 5 milliseconds. Since the algorithm is
implemented in a fairly high level language, the
code loop which waits for the next heart beat to be
triggered must be carefully crafted to ensure that
it runs fast enough and doesn't miss any beats.
Try this experiment, add some more code to this
loop, say a call to msleep(). What happens? Can
you suggest a way to measure the frequency at which
this loop runs? Can you suggest a better method
for implementing the algorithm?
*/
/*
Algorithm Parameters
*/
int TRIGGER_LEVEL = 80;
long DEAD_TIME = 100L;/* milliseconds */
long MAX_BEAT_WAIT = 5000L;/* milliseconds */
void
main()
{
/*
State Variables
state: 0 -> no signal detected
1 -> 1 heart beat detected
2 -> 2 or more heart beats detected
*/
int state;
long this_time;
long last_time;
/*
Temporary Variables
*/
long wait_time;
int heart_rate;/* beats/minute */
/*
Turn off all system interrupt features,
except LCD printfs.
*/
poke( 0x39, 1 );
/*
Flash the program name and date on the LCD.
*/
printf("%s%s\n", PROG_NAME, PROG_DATE);
msleep(3000L);
/*
Loop forever, waiting for heart beat signals
and updating the LCD.
*/
state = 0;
for (;;) {
/*
Update LCD to display current state.
*/
if (state > 1) {
/*
beats/min
= (60,000 msecs/min) / (msecs/beat)
= (30,000 msecs/min) / ((msecs/beat)/2)
*/
heart_rate =
30000 / ((int)(this_time-last_time)/2);
printf("hr: %d\n", heart_rate);
} else if (state > 0) {
printf("signal found\n");
} else {
printf("no signal\n");
}
/*
Previous this_time becomes last_time.
*/
last_time = this_time;
/*
If we detected a heart beat last time,
delay for DEAD_TIME milliseconds so that
we don't redetect the same beat.
*/
if (state > 0)
for (;;) {
wait_time = mseconds()-last_time;
if (wait_time > DEAD_TIME)
break;
}
/*
Loop for up to MAX_BEAT_WAIT milliseconds
while looking for the next heart beat signal.
*/
for (;;) {
/*
If we detect a heart beat, update the
state variables to show that we got a
beat and break to update LCD.
*/
if (_raw_analog(0) < TRIGGER_LEVEL) {
this_time = mseconds();
if (state < 2)
state++;
break;
}
/*
If we've waited for MAX_BEAT_WAIT
milliseconds, update the state variables
to show we no longer detect a signal
and break to update LCD.
*/
wait_time = mseconds()-last_time;
if (wait_time > MAX_BEAT_WAIT) {
this_time = mseconds();
state = 0;
break;
}
}
}
}