DIY Arduino Heart Rate Monitor With MAX30102 and OLED Display
141 Views, 4 Favorites, 0 Comments
DIY Arduino Heart Rate Monitor With MAX30102 and OLED Display




This project shows you how to build a compact and accurate heart rate monitor using an Arduino-compatible Wemos D1 mini, the MAX30102 pulse sensor, and a small OLED display — all housed in a custom 3D-printed case, designed with Fusion360.
The goal was to create a fully working device that’s easy to build, affordable, and fun to use. It measures your heart rate in real time and displays both beats per minute (BPM) and frequency in Hertz (Hz).
Unlike many breadboard-only projects, this one results in a portable and practical device — a great introduction to biosignal sensing, Arduino programming, and 3D-printed enclosures.
Supplies

Supplies
To keep this project simple and accessible, it uses only a few common components that are easy to source and affordable. Most of the electronics are off-the-shelf modules, and the custom case can be 3D printed.
Here’s what you’ll need:
Electronics:
- 1× Wemos D1 mini (ESP8266 microcontroller) or clone. D1 mini
- 1× MAX30102 pulse oximeter sensor (I²C) heart rate sensor
- 1× SSD1306 OLED display, 0.66” (I²C, 64x48 pixels) OLED display
- 1× 4-pin header or connector for the sensor (included with display and microcontroller)
- 4× jumper wires (female-to-female or soldered) (generic)
- USB cable (Micro-USB) (generic)
3D-Printed Parts:
- 1× top case with mounting structure
- 1× bottom cover
- 1× sensor holder
- 1× sensor clip
- 1× display clamp
All STL files are available in the GitHub repository.
Tools:
- Soldering iron and a bit of soldering experience
- Wire cutter/stripper
- A 3D printer (I am using a BambuLab X1C, but any other model will work as well)
How It Works

This heart rate monitor uses an optical method to detect your pulse. At the core of the system is the MAX30102 sensor, a tiny integrated module that includes both an infrared light emitter and a photodetector.
When you place your fingertip on the sensor, it shines infrared light into the skin. Some of this light is absorbed by the blood, and some is reflected back to the detector. As your heart beats, the blood flow changes — and so does the amount of light absorbed. These tiny changes in light absorption form a waveform that mirrors your pulse.
By analyzing this waveform in real time, the microcontroller can detect each heartbeat and calculate your heart rate in beats per minute (BPM). For this project, we also convert that value into frequency — displayed in Hertz (Hz) — to highlight the near-1Hz rhythm of the human heart.
Note: Although the MAX30102 is also capable of measuring blood oxygen levels (SpO₂), this function is not used in the current version of the software.
Designing the Case

To make this project more than just a breadboard demo, I designed a compact and robust enclosure using Fusion 360.
The goal was to create a fully enclosed device that feels like a finished product — small enough to hold in your hand, yet large enough to accommodate all components comfortably. I started by modeling the key electronics: the Wemos D1 mini board, the OLED display, and the MAX30102 sensor. This allowed me to design the case around the actual parts, ensuring a perfect fit.
The case consists of three main parts:
- Top shell: Acts as the structural base. All other parts attach to this piece.
- Sensor mount and clip: Holds the MAX30102 in place, positioned at the top of the case for easy fingertip access.
- Bottom shell: Snaps or screws onto the top to close the enclosure securely.
All components are fixed with standard M2 screws. For added durability and reusability, I embedded small M2 hex nuts directly into the 3D-printed top shell and the sensor clamp. These accept standard M2 screws, making the assembly solid and easy to open or modify later.
The display and microcontroller are held in place with a printed crossbar and spacers.
The complete Fusion 360 model is included in the GitHub repository, along with STL files ready for 3D printing. You’re welcome to customize it — adjust the size, swap out components, or remix it for your own ideas.
3D Printing the Parts
All enclosure parts are designed for FDM 3D printing and are easy to print on any standard printer — no supports are needed.
The top shell consists of two separate STL files that form the background and the raised lettering. By printing them in different filament colors, you can achieve the eye-catching look shown in the pictures — for example, white base with blue text. Just load both STLs into your slicer and use a “multi-color” or “object merge” feature.
Two parts — the top shell and the sensor clamp — are designed to hold M2 hex nuts. To insert these, you’ll need to pause the print at the correct layer height and place the nuts into the recesses. This allows for strong and reusable threaded inserts without glue.
If you’re using Bambu Studio, the GitHub repository includes ready-to-use .3mf files with all print settings and object arrangements already configured — including correct color assignments and pause commands for nut insertion. This makes printing as easy as loading and sending to your printer.
You’re also free to slice the included STL files with your preferred slicer.
Preparing the Electronics



The heart of the project is the Wemos D1 mini, an ESP8266-based microcontroller. It’s paired with a small I2C OLED display and a MAX30102 pulse sensor.
To keep the overall height of the device as low as possible, I didn’t use traditional stacking headers. Instead, I used straight pin headers and added small plastic spacers between the D1 mini and the display. These spacers were taken from regular pin headers and slid onto the pins to achieve the exact distance needed. This ensures a secure connection while maintaining a compact profile.
The OLED is connected via four pins: GND, 3.3V, SDA, and SCL. These are all directly compatible with the D1 mini’s I2C interface.
For the MAX30102 sensor, I soldered a 4-wire cable directly to a small female header, which plugs into the sensor module. On the other side, these wires are soldered to the underside of the D1 mini, which keeps the top side clean and helps with fitting everything into the case.
Once all components are prepared, you’re ready to mount them into the 3D-printed enclosure — which we’ll cover in the next step.
Assembling the Device

With the electronics prepared and the printed parts ready, it’s time to put everything together.
Start by placing the D1 mini with the attached OLED display into the top shell. The case was designed so that the microcontroller fits snugly, with openings for USB access and component clearance. Secure it in place using two M2 screws and the printed crossbar, which presses down gently on the board.
Next, insert the MAX30102 sensor into its dedicated holder. This holder clips into the top shell and hods the sensor firmly by a printed sensor clamp, which is also fixed with M2 screws. Be sure the sensor’s LED window is properly aligned with the cutout in the case, so it can make good contact with your finger during use.
Tuck the cables carefully into the available space and route them so they don’t interfere with closing the case. Finally, place the bottom cover on the enclosure and fasten it with four M2 screws into the previously inserted heat-set nuts.
No glue is needed — everything is held together by screws, making the device easy to open and maintain.
Once assembled, the device is compact, sturdy, and ready for action!
Programming the Device

With the hardware assembled, it’s time to bring the heart rate monitor to life by uploading the software to the microcontroller.
There are two supported development environments — choose whichever you prefer:
Option 1: Arduino IDE (Beginner-friendly)
- Install the Arduino IDE from arduino.cc
- Add the ESP8266 board package via the Board Manager (look for esp8266 by ESP8266 Community)
- Select the board type “LOLIN(WEMOS) D1 R2 & mini”
- Install the following libraries via the Library Manager:
- ESP8266 and ESP32 OLED driver for SSD1306 displays by ThingPulse,
- SparkFun MAX3010x Sensor Library
- Open the heart_beat.ino file located in the software_Arduino_IDE folder.
- Connect the D1 mini via USB and upload the code.
Option 2: PlatformIO (Recommended for advanced users)
- Install Visual Studio Code
- Add the PlatformIO extension
- Open the software_platformIO folder as a project.
- All dependencies and board settings are preconfigured in the platformio.ini file.
- Simply click “Upload” in the PlatformIO interface to compile and flash the code.
The code is written in clean, modular C++ using two object-oriented classes for sensor management and display control. It’s well-documented and easy to understand — great for learning or modifying to suit your own ideas.
Once the upload is complete, your device will automatically start up and begin reading your heart rate.
Using the Heart Rate Monitor

Your DIY heart rate monitor is now ready to use!
Place your fingertip gently on the sensor window. The device will automatically detect your pulse and display your heart rate — both in beats per minute (BPM) and Hertz (Hz) — on the screen.
If no signal is detected, the display switches to a simple animation until a valid heartbeat is found again.
Thanks to the compact design and USB power, it’s easy to use on your desk or integrate into other projects. Enjoy exploring your own heartbeat in real-time!