Live heart rate monitor for the Colmi R02 smart ring.
Connects to the ring over Bluetooth Low Energy, streams real-time heart rate straight off the sensor, and plots it live. Built from scratch by reverse-engineering the ring's BLE protocol.
- Scans for and connects to a Colmi R02 ring over BLE
- Sends the real-time heart rate command and parses the raw packets
- Displays a live, scrolling heart rate graph
- Python 3.12+
- macOS or Linux with Bluetooth
- A Colmi R02 smart ring
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txtFind your ring's address and set it in ring/connection.py:
colmi_r02_client scanThen update RING_ADDRESS with the address it prints.
Note: on macOS the "address" is a per-machine CoreBluetooth UUID, not the ring's real MAC. That's expected.
python3 main.pyWear the ring sensor-side (green LED) against the palm side of your finger, snug. The graph will sit flat while the sensor warms up, then lock onto your pulse and start scrolling. Give it ~20–30 seconds on the first read.
The ring exposes a Nordic UART Service over BLE with two characteristics: one to write commands to, one that streams notifications back. Commands are fixed 16-byte packets — a command byte, a payload, and a checksum. To start a live heart rate reading you send command 105 with payload [1, 1] (heart rate, start), then read byte 3 of each response packet for the BPM.
raw BLE packet → queue → parse → BPM → live plot
connection.py— find and connect to the ringstream.py— subscribe to notifications and send the start commandprotocol.py— build command packets and parse responsesdisplay.py— the live PyQtGraph window
This is a hobby project for reading your own data off a ring you own. It is not a medical device and the readings are not clinical-grade!