Heart Rate Meter
I was working on a project involving the display of my heart rate.
I initially started out using the standard colour coded target heart rate chart then decided to make another that has a graduated numeric display.
The heart rate is read using an open source sensor. It is displayed on a pseudo analog meter.
I used a stepper motor and position program to display the reading.
The colour display is meant to be show target heart rate ranges for exercising
Using steppers to simulate analog gauges is how many modern automobile displays work...
Supplies
The Meter Shape
Since this is a custom project I was free to make this any shape.
I began by drawing a heart shape as shown this is then extruded to a depth of 40mm.
Using the offset feature I created a 10mm shape for the meter face. This is extruded cut 10mm.
The base is then cut off at a 10 degree angle which will cause the entire structure to lean back and have a stable foundation.
The shape is then shelled from the back with a 3mm width.
The front 'tongue' is cut through to allow for a meter hand to protrude through.
Motor mounts were then added using the requirements from the motor datasheet.
I then added studs for allowing for screws to secure a back cover.
I then used the offset feature to cut the back out 3mm deep at 1.5mm from the edge.
Holes were then added to the studs for securing the back cover.
The Meter Face and Pointer
I used the offset feature at 0.1mm to create a meter face.
This was extruded and the original body was hidden.
A circle was the drawn over the face and segmented.
The 5 sections required to make the heart rate chart were cut out separately.
the same circles were then used to make a scaled face.
the numbers were then extruded .25mm and printed in a contrasting colour.
A pointer was created as shown...
The Back Cover
The rear view was used along with the offset feature. to make a 3mm thick extrusion.
The offset feature at 10mm was used to extrude cut 1.5mm.
Lines were drawn on the inside of the extrude cut, these were used to make ribs for internal structure.
Printed Parts
The pieces were all designed to friction fit together as shown.
The indicator was fitted to the motor shaft.
The motor was mounted then heat staked in place using a hot iron.
The Electrics
This project is ultimately aimed towards using a wireless sensor to display on the meter. That part of the project will not be covered in this write up.
For testing purposes the sensor and meter are both on the same Arduino.
I connected an UNO pin A0 to the pulse sensor.
pins 8,9,10,11 to a ULN2003 stepper driver board IN1, IN2, IN3, IN4 respectively.
The Reader
The sensor that I used was from pulsesensor.com
I had 2 they both died.
This is most unfortunate since these yield quick and fairly accurate results.
This project will continue with a Maxim MAXREFDES117...
The pulsesensor.com device has many pre-built algorithms which can be seen on their website...
The Code for Pulsesensor.com Device
This was the test code I used before my last sensor died...
Upon initialization the motor is activated and driven against the stop at the extreme left position, this is to reference the motor position since there is no electronics for this in this simple system. For here the sensor is read in and this value is adjusted to show Beats Per Minute
This value is the converted to a value that corresponds to steps for the motor.
The starting point for the motor is 0 (50 on the graduations) values are added to this and the new value is saved to memory. Lower reading are subtracted and higher reading are added as needed.
This value when it changes, will adjust the pointer up or down the correct amount to read relatively accurately.
For testing the values are also output to the serial monitor.
#define USE_ARDUINO_INTERRUPTS true // Set-up low-level interrupts for most acurate BPM math.<br>#include <Stepper.h> #include <PulseSensorPlayground.h>
const int PulseWire = 0; // Sensor input const int stepsPerRevolution = 1025; // change this to fit the number of steps per meter face for my motor int Threshold = 550; // Determine which Signal to "count as a beat" and which to ignore. int testing = 0; int oldBPM = 0; int newBPM = 0; const int division = 7; int steps = 0; int differenceSteps = 0;
PulseSensorPlayground pulseSensor; // Creates an instance of the PulseSensorPlayground object called "pulseSensor" Stepper stepper(stepsPerRevolution, 8, 10,9,11); // initialize the stepper library on pins 8 through 11:
void setup() { stepper.setSpeed(30); // set the speed at 30 rpm: Serial.begin(9600); // initialize the serial port: pulseSensor.analogInput(PulseWire); stepper.step(-1024); }
void loop() { int myBPM = pulseSensor.getBeatsPerMinute(); // Calls function on our pulseSensor object that returns BPM as an "int". steps = (myBPM - 50) * division; differenceSteps = (steps - testing); if (myBPM < 51) { stepper.step(0); Serial.println(" off"); Serial.println(myBPM); }else if (myBPM > newBPM) { stepper.step(differenceSteps); Serial.println(" UP"); Serial.println(myBPM); }else if (myBPM < newBPM) { stepper.step(-differenceSteps); Serial.println(" DOWN"); Serial.println(myBPM); } newBPM = myBPM; testing = (myBPM - 50) * division; delay(20); }
Downloads
Maxim MaxREFDES117 Device
There is sample code for this device but when I run it the results are less than stellar. I get a resting heart rate range from 28 to 250 BPM. Not Good! This When compared with a known good source is at 64BPM stable.
This is supposed to be due to the algorithm provided, I have not found a stable algorithm as of yet. There is a slightly better one from Sparkfun on GitHub...
I used Example 5 with some display modifications.
The connections are fairly basic.
On the UNO gnd and 5V (or 3.3V) are connected to the module GND and VIN
UNO D7 goes to device INT
UNO A4 and A5 go to device SDA and SDL respectively
The Motor driver was connected to digital 4, 5, 6, 7.
I chose to display heart rate average as this is the closest, the only problem here is the reading takes about a minute to complete
There are still some bugs to work out...
The program code was modified from the original code found here!
The meter reading still works the same as before.
For the heart rate version the code has to be adjusted to show the max of less than 200 based on the age range of the user, I still used the minimum of 50. There are many charts available online for this range.