MAX30102 IR sensor drives a scrolling ECG waveform with BPM readout, full-screen beat flash, animated pixel-art heart, and touch-to-freeze.
use the heart rate sensor. i want a live ECG-style scrolling waveform on the screen with my BPM in big numbers. make it flash red when my heart beats
The MAX30102 is already on the shared I2C bus (SDA=2, SCL=1). I'll use the SparkFun MAX30105 library which covers it. Architecture:
ECG grid drawn into the sprite before each waveform render: major horizontal lines every 66 px, minor lines every 33 px, vertical grid every 60/20 px — all in near-black green to stay readable without overpowering the trace.
The waveform ring buffer stores 240 float samples (one per screen column). On each frame the oldest column becomes the new write position — creating a natural left-scroll. An 8-pixel "cursor sweep" fade at the leading edge gives it the classic medical monitor look.
// AC-couple the raw IR signal
dcBaseline = dcBaseline * 0.98f + (float)ir * 0.02f;
float ac = (float)ir - dcBaseline;
// Auto-scale: track peak, decay slowly
if (fabsf(ac) > acPeak) acPeak = fabsf(ac);
else acPeak *= 0.998f;
float norm = ac / acPeak; // –1 .. +1
Beat detection uses the library's checkForBeat() on each IR sample. On a detected beat, a 3-frame flash sequence fires:
| Frame | Header BG | Duration |
|---|---|---|
| 1 | Full red 0xF800 | 55 ms |
| 2 | Mid red 0x9000 | 55 ms |
| 3 | Fade red 0x3000 | 55 ms |
BPM is averaged over the last 8 beats. Colour coding: blue <55, green 55–84, yellow 85–99, red ≥100.
The pixel-art heart (11×9 bitmap, 2px scale normally, 3px on beat) pulses visually in sync.
can i freeze the trace so i can look at a beat pattern?
Added tap-to-freeze via FT6336U touch. A leading-edge tap toggles frozen — the ring buffer stops advancing (waveform stays still) but the sensor keeps reading. A [ FROZEN ] label appears in the header. Tap again to resume scrolling from the current live position.
FT6336U_TouchPointType tp = ts.scan();
bool touched = (tp.touch_count > 0);
if (touched && !prevTouch) {
frozen = !frozen;
drawHeader(0); // immediate FROZEN label update
}
prevTouch = touched;
Wrote flash-sketch-004-heartbeat-viz.sh. Additional libraries required: SparkFun MAX3010x (heart rate) and FT6336U (touch). Both installed automatically by the script.
./flash-sketch-004-heartbeat-viz.sh
# Installing SparkFun MAX3010x library...
# Sketch uses 41% of flash, 18% of RAM
# Wrote 425984 bytes at 0x00010000 in 5.4 seconds
# Hash of data verified.
# Hard resetting via RTS pin...
| File | What it does |
|---|---|
sketches/heartbeat_viz/heartbeat_viz.ino | ECG waveform, BPM display, beat flash, pixel heart, touch freeze |
flash-sketch-004-heartbeat-viz.sh | Full compile + flash with SparkFun MAX3010x lib install |