Peter Smith
Published © GPL3+

Easy-to-read Heart Rate Monitor

When users can combine Bluetooth devices together, they can solve bigger problems.

IntermediateProtip4 hours805
Easy-to-read Heart Rate Monitor

Things used in this project

Hardware components

Hexiwear
NXP Hexiwear
×1
DOTTI
×1

Software apps and online services

Best Calculator

Story

Read more

Custom parts and enclosures

Bracket to wall-mount a DOTTI display

By creating a wall mount (VESA D) for the DOTTI display, the easy-to-read heart monitor becomes even easier to read!

Schematics

Schematic diagram of the easy-to-read heart rate monitor

The Hexiwear integrates all of the required sensors into one neat package. The DOTTI is also a consumer-ready device. No soldering or wiring was needed to create the final product.

Code

Hexiwear Heart Monitor

Plain text
The language is BC BASIC, a programming language built into the Best Calculator app for Windows.
CLS BLUE
PRINT "Hexiwear Pulse Monitor"

REM
REM Initialize Bluetooth devices and globals
REM
Data = Bluetooth.Array()
FOR i = 1 TO 8
    Data.Set(i, 0)
NEXT i
REM 1..8 for the data points

result = FindDevices()
IF (result = 0) THEN ShowFail()
IF (result = 0) THEN STOP


MinPulse = INPUT DEFAULT 84 PROMPT "Min pulse?"
MaxPulse = INPUT DEFAULT 117 PROMPT "Max pulse?"
ShowStart()
DottiSetup()


PRINT "READY"


REM
REM The main loop
REM     Read BPM
REM     Remove old point
REM     Draw new point
REM     Update
REM 
column = 1
FOR p = 1 TO 64
    REM Read BPM (beats per minute)
    pulse = Hexi.GetHeart()
    PRINT AT 5,1 "BPM", pulse
    y = PulseToIndex(pulse)

    REM Remove old data point
    oldy = Data.Get(column)
    IF (oldy <> y AND oldy >= 1) THEN DottiErase(column, oldy)

    REM Draw new data point
    DottiDot (p, column, y)

    REM Update
    Data.Set(column, y)
    column = column + 1
    IF (column > 8) THEN column = 1
NEXT p


PRINT "DONE"
Dotti.Close()

FUNCTION DottiSetup()
    GLOBAL Dotti
    Dotti.SetPanel (10, 10, 10) 
    Dotti.SetRow (3, 10, 50, 10)
    Dotti.SetRow (4, 10, 50, 10)
    Dotti.SetRow (5, 10, 50, 10)
    Dotti.SetRow (6, 10, 50, 10)
END

REM Helper routine to display a point on the DOTTI
REM Used by Draw new point
FUNCTION DottiDot(pulse, x,y)
    GLOBAL Dotti
    isred = y < 3 OR y > 6
    IF (isred) THEN PRINT "IS=" + isred, pulse, x, y
    IF (NOT isred) THEN PRINT "no=" + isred, pulse, x, y

    IF (isred) THEN Dotti.SetPixel (x, y, 255, 0, 0)
    IF (NOT isred) THEN Dotti.SetPixel (x, y, 80, 220, 80)
END

REM Helper routines to erase an old point
REM Used by Erase old point
FUNCTION DottiErase(x, y)
    GLOBAL Dotti
    isred = y < 3 OR y > 6
    IF (isred) THEN PRINT "ER=" + isred, " ", x, y
    IF (NOT isred) THEN PRINT "er=" + isred, " ", x, y

    IF (isred) THEN Dotti.SetPixel (x, y, 10, 10, 10)
    IF (NOT isred) THEN Dotti.SetPixel (x, y, 10, 50, 10)
END

REM Helper routine converts a BPM into a row (y height)
REM value from 1 to 8 (to match DOTTI requirements)
REM Uses the MinPulse and MaxPulse values
REM Has detailed knowledge of what the display looks like
REM Used by Remove old point
REM Also used by Draw new point
FUNCTION PulseToIndex(pulse)
    GLOBAL MinPulse
    GLOBAL MaxPulse
    REM step 1: index is 0...3
    index = Math.Round(4 * (pulse - MinPulse) / (MaxPulse - MinPulse))
    REM next steps: index is 0..-3 ; index is 3..0 ; 6..0
    index = (-index)+3+3
    IF (index < 1) THEN index =1
    IF (index > 8) THEN index = 8
END index

REM Used by Initialize Bluetooth devices and globals
FUNCTION ShowFail()
    PRINT "ERROR: You need a DOTTI and a Hexiwear"
END

REM Used by Initialize Bluetooth devices and globals
FUNCTION ShowStart()
    CLS GREEN
    PRINT "Hexiwear and DOTTI"
    PRINT "  pulse monitor"
    PRINT "=================="
    PRINT "   (preparing the DOTTI)"
END

REM Used by Initialize Bluetooth devices and globals
REM Sets up the Dotti and Hexi globals
REM Return 0==fail and 1==OK
FUNCTION FindDevices()
    GLOBAL Dotti
    GLOBAL Hexi

    devices = Bluetooth.DevicesName ("*Dotti")
    IF (devices.Count = 0) THEN PRINT "ERROR: Cannot find a DOTTI"
    IF (devices.Count = 0) THEN RETURN 0
    device = devices.Get(1)
    Dotti = device.As (“DOTTI”)

    devices = Bluetooth.DevicesName ("HEXIWEAR")
    IF (devices.Count = 0) THEN PRINT "ERROR: Cannot find a Hexiwear"
    IF (devices.Count = 0) THEN RETURN 0
    REM Need to return 0 for failure!
    device = devices.Get(1)
    Hexi = device.As ("Hexiwear")
    mode  = Hexi.GetMode()
    IF (mode <> 5) THEN PRINT "Error: Hexi must be in heart mode"
    IF (mode <> 5) THEN  RETURN 0    

    REM 1 means all OK
    RETURN 1
END

Credits

Peter Smith

Peter Smith

2 projects • 3 followers
C# Programmer for many years, and a lover of all things IOT and Bluetooth.

Comments