A one-screen PulseSensor heartbeat dashboard for the ESP32 Cheap Yellow Display (CYD). Flash from your browser, wire three colored wires, and watch your pulse live with sound, light, and touch volume.
Educational biofeedback demo — not for medical use.
👉 Easiest install: pulsesensor.com/pages/cyd
That page has a one-click web installer, wiring diagram, and the full tutorial. Use it if you just want to flash your CYD and see your heartbeat. This README is for people who want to read the source or build from source.
| Channel | Feedback |
|---|---|
| Screen | Cyan waveform (searching) → white waveform (locked), BPM, IBI, 12-step quality meter |
| Light | Onboard rear red LED blinks and fades on every qualified beat |
| Sound | Short heartbeat tone on the CYD speaker (GPIO 26) |
| Touch | Header buttons change speaker volume, default 1/10 |
| Heart | Centered animated heart whose outline follows the live trace color |
| Searching for signal | Locked on qualified beat |
|---|---|
| PulseSensor Wire | CYD Connection |
|---|---|
| Red (+V) | 3.3V on CN1 |
| Black (GND) | GND on P3 or CN1 |
| Purple (Signal) | GPIO 35 on P3 |
Use 3.3V, not 5V. Signal must go to GPIO 35.
Go to pulsesensor.com/pages/cyd in Chrome, Edge, or Brave on a desktop or laptop. Plug in your CYD over USB. Click Install.
The same installer is also hosted from this repo: worldfamouselectronics.github.io/PulseSensor_CYD/
This is the verified developer path used to build the binaries that ship to the web installer.
- Plug one CYD into USB.
- Detect the serial port:
arduino-cli board list- Flash with the helper script:
./flash-cyd.sh /dev/cu.usbserial-3110If your serial port is different, pass it as the first argument. The script includes the required TFT_eSPI CYD display compile flags and uses 115200 upload speed.
The firmware is intentionally kept as one .ino file so beginners can open it directly:
PulseSensor_CYD.ino
Steps:
- Download
PulseSensor_CYD.ino. - Make a folder named
PulseSensor_CYD. Put the.inofile inside. - Open it in Arduino IDE 2.x.
- Install the ESP32 board package.
- Install these libraries:
TFT_eSPI,PulseSensor Playground,XPT2046_Touchscreen. - Configure
TFT_eSPIfor the CYD display (seeflash-cyd.shfor the exact build flags — preferred over editing globalUser_Setup.h). - Select an ESP32 board and upload at
115200.
Every reading on screen comes directly from the PulseSensor Playground library, so what you see is what you'd see in your own Arduino sketches.
| On screen | Playground call |
|---|---|
| Live waveform | getLatestSample() |
| Heart pulse / LED blink / tone | sawStartOfBeat() |
| Inside-beat indicator | isInsideBeat() |
| BPM | getBeatsPerMinute() |
| IBI | getInterBeatIntervalMs() |
| Amplitude meter | getPulseAmplitude() |
| Dotted threshold guide | setThreshold(550) |
The 12-step quality meter rises on qualified beats and falls on questionable ones. Lock at 10/12. The R# counter shows automatic detector re-arms.
No serial port? Try a different USB cable — many micro-USB cables are charge-only.
Flat waveform? Confirm the purple wire is on GPIO 35, not 36 or 34.
Erratic readings? Gentle, steady finger pressure. Insulate the back of the sensor. The Stabilizer Ring gives the cleanest signal.
BPM stays at 0? Give it 5–10 seconds. The detector needs a few clean beats before it reports BPM.
- Board: ESP32-2432S028R CYD
- Display: ILI9341 320×240 TFT
- Sensor input: PulseSensor signal on
GPIO 35 - RGB LED: onboard CYD LED, active-low PWM
- Speaker:
GPIO 26 - Touch: XPT2046 controller on HSPI
PULSE_PIN = 35
BACKLIGHT = 21
LED_RED_PIN = 4
LED_GREEN_PIN = 16
LED_BLUE_PIN = 17
SPEAKER_PIN = 26
TOUCH_IRQ = 36
TOUCH_MISO = 39
TOUCH_MOSI = 32
TOUCH_SCLK = 25
TOUCH_CS = 33
The PulseSensor signal pin on this CYD revision was found with a small analog pin scanner. Signal was visible on IO35, not the originally documented GPIO 36. The scanner is its own diagnostic sketch: CYD_Analog_Pin_Scanner.
PulseSensorPlayground's detector expects 10-bit analog samples (0..1023, idle near 512). ESP32 defaults to 12-bit (0..4095), so this firmware calls:
analogReadResolution(10);That keeps the library's threshold and beat-detection math in the range it expects.
Useful next ideas, only if they improve the student experience or the accuracy of the reading:
- Method Overlay: tap the quality panel to cycle through the live Playground method names behind each reading.
- USB Serial Lab Mode: optional Playground-style serial output for Arduino Serial Plotter or a WebSerial monitor.
Good Playground branches that should stay out of this default firmware until they clearly improve the CYD experience:
- Multi-sensor and Pulse Transit Time experiments — extra wiring; wait until the one-sensor lesson is rock solid.
- WiFi server mode — credentials and classroom setup friction without improving the default experience.
- Servo or motor outputs — fun, but they add hardware without improving accuracy here.
- Automatic Playground
blinkOnPulse()/fadeOnPulse()— less clear than the current qualified-beat-gated CYD LED feedback.
The web installer's binary parts live in docs/flasher/firmware/. Rebuild them with:
bash scripts/build-web-flasher-firmware.shThe script uses the same board family, upload speed, and display flags as flash-cyd.sh. It writes:
docs/flasher/firmware/bootloader.bin(offset0x1000)docs/flasher/firmware/partitions.bin(offset0x8000)docs/flasher/firmware/boot_app0.bin(offset0xE000)docs/flasher/firmware/firmware.bin(offset0x10000)
The manifest at docs/flasher/manifest.json lists those offsets for ESP Web Tools.
After UI changes:
node scripts/render-dashboard-screenshots.mjsCurrent release: v1.2.0. First known-good single-screen release: v1.0.0. See CHANGELOG.md.
MIT. Made by World Famous Electronics — the original PulseSensor since 2012.
Heartbeats in your project, lickety-split. ♥