Watch your pulse appear as a wave on your screen. The heartbeat sensor shines infrared light through your fingertip, and the tiny changes in blood flow with each heartbeat change how much light gets through. The UNO cleans up the signal, plots it, flashes its built-in LED with each beat and estimates your heart rate.
What you need
- UNO R3 board and USB cable
- Heartbeat sensor module (45-in-1 Sensor Kit)
- Breadboard and jumper wires (not included in the Sensor Kit: use the ones from the UNO R3 Starter Kit or any others)
Important
This is a science experiment, not a medical device. Simple sensors like this one are easily disturbed by movement and room light, so the beats-per-minute value is only a rough estimate. Never use it to make health decisions.
Wiring

| Module pin | UNO pin |
|---|---|
| S (signal) | A0 |
| + (middle) | 5V |
| − | GND |
Pin labels differ between module versions. Always follow the labels printed on your module.
Build it step by step
- Wire the module as in the diagram.
- Upload the code.
- Open Tools → Serial Plotter and set it to 9600 baud.
- Rest your fingertip lightly across the two components on the module, keep very still and cover your finger with your other hand to block room light.
- Wait a few seconds for the wave to settle. The LED on the UNO flashes with each beat.
The code
const int SENSOR_PIN = A0;
const int LED_PIN = 13; // built-in LED
const float THRESHOLD = 2.0; // raise it if you get extra beats, lower it if beats are missed
float smooth = 0;
float baseline = 0;
bool inBeat = false;
unsigned long lastBeat = 0;
float bpm = 0;
void setup() {
Serial.begin(9600);
pinMode(LED_PIN, OUTPUT);
smooth = baseline = analogRead(SENSOR_PIN);
}
void loop() {
int raw = analogRead(SENSOR_PIN);
smooth = smooth * 0.75 + raw * 0.25; // remove fast noise
baseline = baseline * 0.99 + smooth * 0.01; // follow the slow drift
float signal = smooth - baseline; // what's left is the pulse
if (!inBeat && signal > THRESHOLD) { // start of a beat
inBeat = true;
digitalWrite(LED_PIN, HIGH);
unsigned long now = millis();
unsigned long gap = now - lastBeat;
if (gap > 300 && gap < 2000) { // 30 to 200 beats per minute
float instant = 60000.0 / gap;
bpm = (bpm == 0) ? instant : bpm * 0.7 + instant * 0.3;
}
lastBeat = now;
}
if (inBeat && signal < 0) { // end of the beat
inBeat = false;
digitalWrite(LED_PIN, LOW);
}
// Labelled values show as two lines in the Serial Plotter
Serial.print("Pulse:");
Serial.print(signal);
Serial.print(",BPM:");
Serial.println(bpm / 10.0); // scaled down so both fit on the same graph
delay(10);
}
How it works
The raw reading changes slowly with finger pressure and room light, while the heartbeat is a tiny ripple on top. The sketch uses two moving averages: a fast one (smooth) removes noise, and a very slow one (baseline) follows the drift. Their difference is the pulse wave. Each time the wave rises above the threshold the sketch counts a beat, measures the time since the last one and turns it into beats per minute. BPM is plotted at one tenth of its value (7.2 means 72) so it fits next to the wave.
Make it your own
- Make the active buzzer module click with each beat, like a hospital monitor.
- Compare your pulse sitting down and after jumping on the spot for a minute.
- Show the BPM on the 1602 LCD from the UNO R3 Starter Kit.
Troubleshooting
- No wave, just noise: cover your finger and the sensor from light, and keep completely still.
-
Too many or too few beats: adjust
THRESHOLD. - The plotter shows nothing: close the Serial Monitor first. Only one of them can be open at a time.
Learn the basics first
New to these parts? These lessons explain them step by step: Build an automatic night light (analog sensors) and Set up the Arduino IDE and blink an LED.
0 comments