Introduction
This tutorial will help you display real time sensor reading from your MAX3010X Heart rate monitor onto an alphanumeric display (16 x 2) using Arduino UNO. Potential applications include a public health installation, DIY smart health tracker and many more.
Parts List
- Blood Oxygen Sensor Heart Rate (GY-MAX30102)
- Soldering iron and metal
- Female to Male DuPont wires
- jumper wires
- Alphanumeric LCD Display (16×2)
- Breadboard
- Arduino UNO
Steps covered below:
- Connect LCD Display to Arduino (see below)
- Connect heart rate monitor to Arduino (here)
- Produce code to change display output based on heart rate detected
Libraries Needed
Add MAX3010 library for Heart Rate monitor
- Go to manage libraries
- Search for MAX3010X and install
- Note: Make sure to use the MAX3010X library with Arduino. There are two other similar libraries (MAX30100) that will not work with
Add Liquid Crystal library for LCD Display
- The ‘Liquid Crystal’ library should be available with the ELEGOO kit (chapter 14: LCD Display)
- Find Liquid Crystal library in ELEGOO folder
- It should look something like: “C:\Users\s\Arduino\ELEGOO Super Starter Kit for UNO V1.0.2022.08.04\English\Libraries\LiquidCrystal.zip”
- Copy and paste library to ‘libraries’ in your Arduino backend folder
Diagram and connections
Breakdown of connections:
For Heartrate sensor:
- MAX3010 VIN to 5V on Arduino
- MAX3010 GND to GND on Arduino
- MAX3010 SCL to Analog pin A5 on Arduino
- MAX3010 SDA to Analog pin A4 on Arduino
For LCD Display:
- LCD RS pin to digital pin 7
- LCD Enable pin to digital pin 8
- LCD D4 pin to digital pin 9
- LCD D5 pin to digital pin 10
- LCD D6 pin to digital pin 11
- LCD D7 pin to digital pin 12
- LCD R/W pin to ground
- LCD VSS pin to ground
- LCD VCC pin to 5V
- 10K resistor:
- ends to +5V and ground
- wiper to LCD VO pin (pin 3)
Steps
- The heart rate monitor is sold as two separate parts. Part A is a straight pin header. Part B is the heart rate monitor.
2. Clamp parts to hold together. The shorter end of Part A goes into the five holes of Part B
3. Solder on the two parts (shown below) and keep aside.
4. Now for display, Connect LCD Display using breadboard, LCD Display and jumper wires and Arduino UNO (Connections mentioned above)
5. Connect the soldered heart rate monitor to Arduino and breadboard using M to F Dupont wires
6. Here is what the entire setup will look like
7. Now run this code on ArduinoIDE:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
// This code uses real time data measured on MAX3010 heart rate monitor and produces a display on LCD screen (16x2) // 04.03.2023 // Shreya Bansal // This code is an extension of code from the MAX3010 library > example code > MAX30105PulseoximeterHeartrate // and code from ELEGOO Super starter kit chapter 14 >LCD Display // first, include libraries for MAX3010 and LCD Display #include <MAX3010x.h> #include "filters.h" #include <LiquidCrystal.h> // Sensor (adjust to your sensor type) MAX30105 sensor; // set a sampling rate const auto kSamplingRate = sensor.SAMPLING_RATE_400SPS; // set a sampling frequency const float kSamplingFrequency = 400.0; // set a Finger Detection Threshold and Cooldown const unsigned long kFingerThreshold = 10000; const unsigned int kFingerCooldownMs = 500; // set an Edge Detection Threshold const float kEdgeThreshold = -2000.0; // Filters const float kLowPassCutoff = 5.0; const float kHighPassCutoff = 0.5; // Averaging const bool kEnableAveraging = true; const int kAveragingSamples = 50; const int kSampleThreshold = 5; // for LCD, set the pins connected to display // here its will be pins 7,8,9,10,11,12 LiquidCrystal lcd(7, 8, 9, 10, 11, 12); void setup() { Serial.begin(9600); lcd.begin(16, 2); // set if else condition to display on serial monitor whether sensor is working or not if(sensor.begin() && sensor.setSamplingRate(kSamplingRate)) { // if the sensor detects pulse, print the following message on LCD display lcd.print("Hello from CityBeat"); } // if the sensor is not initialized, print the following on LCD else { Serial.println("Sensor not found"); while(1); } } // Filter Instances HighPassFilter high_pass_filter(kHighPassCutoff, kSamplingFrequency); LowPassFilter low_pass_filter(kLowPassCutoff, kSamplingFrequency); Differentiator differentiator(kSamplingFrequency); MovingAverageFilter<kAveragingSamples> averager; // Timestamp of the last heartbeat long last_heartbeat = 0; // Timestamp for finger detection long finger_timestamp = 0; bool finger_detected = false; // Last diff to detect zero crossing float last_diff = NAN; bool crossed = false; long crossed_time = 0; void loop() { // read sample on sensor every 1000 milliseconds auto sample = sensor.readSample(1000); float current_value = sample.red; // Detect Finger using raw sensor value if(sample.red > kFingerThreshold) { if(millis() - finger_timestamp > kFingerCooldownMs) { finger_detected = true; } } else { // Reset values if the finger is removed differentiator.reset(); averager.reset(); low_pass_filter.reset(); high_pass_filter.reset(); finger_detected = false; finger_timestamp = millis(); } if(finger_detected) { current_value = low_pass_filter.process(current_value); current_value = high_pass_filter.process(current_value); float current_diff = differentiator.process(current_value); // Valid values? if(!isnan(current_diff) && !isnan(last_diff)) { // Detect Heartbeat - Zero-Crossing if(last_diff > 0 && current_diff < 0) { crossed = true; crossed_time = millis(); } if(current_diff > 0) { crossed = false; } // Detect Heartbeat - Falling Edge Threshold if(crossed && current_diff < kEdgeThreshold) { if(last_heartbeat != 0 && crossed_time - last_heartbeat > 300) { // Show Results int bpm = 60000/(crossed_time - last_heartbeat); if(bpm > 50 && bpm < 250) { // Average? if(kEnableAveraging) { int average_bpm = averager.process(bpm); // Show if enough samples have been collected if(averager.count() > kSampleThreshold) { // first print output of average heartrate on serial monitor Serial.print("Heart Rate (avg, bpm): "); Serial.println(average_bpm); // then print output of average heartrate on LCD display lcd.clear(); lcd.print("avg Rate: "); lcd.print(average_bpm); lcd.print("bpm"); } } else { // otherwise print output of heartrate on serial monitor Serial.print("Heart Rate (current, bpm): "); Serial.println(bpm); // otherwise print output of heartrate on LCD Display lcd.clear(); lcd.print(" rate: "); lcd.println(bpm); } } } crossed = false; last_heartbeat = crossed_time; } } last_diff = current_diff; } } |
8. Now place your finger on the heart rate sensor and run the code on Arduino IDE.
9. Here is how it should look like:
10. Please feel free to comment for any queries or questions!
References
- https://store-usa.arduino.cc/products/arduino-starter-kit-multi-language
- https://diymall.com.ng/product/max30100-pulse-oximetry-sensor/
- https://www.amazon.com/Heart-MAX30102-Sensor-Monitor-Arduino/dp/B077QB8L47/ref=sr_1_6?crid=GLWB60GOM9O5&keywords=heart+rate+monitor+arduino&qid=1680543910&sprefix=%2Caps%2C123&sr=8-6#customerReviews
- Datashet for LCD Display: www.arduino.cc/documents/datasheets/LCDscreen.PDF
- Datasheet for Heart Monitor: https://www.analog.com/media/en/technical-documentation/data-sheets/max30100.pdf
One reply on “Use MAX3010 Heart rate sensor and alphanumeric LCD (16×2) to display real-time heartrate reading”
I am getting error:
C:\Users\hp\AppData\Local\Temp\.arduinoIDE-unsaved2023514-19212-f2kvp8.y9omi\sketch_jun14a\sketch_jun14a.ino:9:10: fatal error: filters.h: No such file or directory
#include
^~~~~~~~~~~
compilation terminated.
exit status 1
Compilation error: filters.h: No such file or directory