Bsp software Pulsuhr

Aus der Mikrocontroller.net Artikelsammlung, mit Beiträgen verschiedener Autoren (siehe Versionsgeschichte)
Wechseln zu: Navigation, Suche
->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;
            }
        }
    }
}