Repository navigation
Releases: abcsds/RRStreamer
Release list
v0.2.1 — Local interval log + disconnect/reconnect hardening
Adds an optional local fallback log on the scan screen and hardens the disconnect/reconnect path.
New
- Save intervals to file toggle on the scan screen (off by default). When enabled, every RR/PP value that goes out over LSL is also appended to a text file at
Android/data/io.github.abcsds.rrstreamer/files/Documents/<YYYY-MM-DD_HH-MM-SS-MS>.txt— one rounded-ms int per line. A safety net for sessions where the LSL stream isn't recorded over the network. Pull viaadb pull, the system Files app, or USB. - The writer flushes after every line, so a kill never loses more than the in-flight sample. Logger failures (missing SD card, I/O hiccup) are logged and swallowed — they never break the live BLE → LSL pipeline.
Fixed
- FGS ANR after stop+restart:
startForeground()is now called inonStartCommandtoo. WithBIND_AUTO_CREATEthe service can outlive astop()+stopSelf(), so a follow-upstartForegroundService(...)reaches an existing instance whoseonCreatedoesn't re-run. Without re-assertingstartForegroundthe 5-second FGS watchdog ANRs. - UI stuck in Connecting after reconnect: per-session resources (LSL streamer, log file) are now torn down on disconnect/error, not just on stop. Without the streamer close the lazy first-sample init skipped the state transition and the UI stayed on Connecting forever even while samples were flowing.
- 3-frame protocol decision window: the Polar H10 sometimes emits an HR-only
0x2A37frame before computing the first R-R interval (especially right after reconnect). Committing to PolarPpi on that single frame stranded the client waiting for PPI from a band that doesn't produce it. - PMD CP error responses parsed: bands like the H10 expose the PMD service but answer
START_PPIwithNOT_SUPPORTED(error code 3). The app now surfaces a clean error and you can retry, instead of waiting forever for frames that won't arrive. - Cross-thread session fields use
@Volatile+ null-then-close so astop()on the main thread can't race a write-after-close from the BLE binder thread.
Install
Sideload RRStreamer-v0.2.1.apk on Android 8.0+ (API 26+). The package identifier changed in this release, so Android treats this as a different app from earlier builds — uninstall any previous RRStreamer first, otherwise the install will be refused.
v0.2.0 — PPG band support (Polar Verity Sense, OH1)
Adds support for PPG (optical) bands alongside the existing ECG path.
New
- Polar Verity Sense, OH1, OH1+ — bands that don't expose RR over the standard
0x2A37characteristic. The app picks the right protocol at connect time:- If the first
0x2A37notification carries the RR-flag bit → ECG path (Polar H10, Wahoo TICKR, …) →RR <devicename>outlet. - Else if the device exposes the Polar PMD service (
FB005C80-…) → bumps MTU to 232, chains the PMD CCCD writes, sendsSTART_PPI→PP <devicename>outlet (peak-to-peak intervals in ms).
- If the first
- New PP outlet symmetric with RR:
Markers, 1 channel, int32, source-idPP_markers_<devicename>.
Notes
- RMSSD computed from PP is shown with a
≈prefix and anapproxqualifier on the 100-beat graph — useful for relative comparisons but not ECG-grade. - Receivers can resolve by type (
Markers) and inspect the stream name to handle either RR or PP transparently.
Install
Sideload RRStreamer-v0.2.0.apk on Android 8.0+ (API 26+).
v0.1.0 — Initial release
First public release of RRStreamer — Android client that streams heart rate and beat-to-beat (RR) intervals from a BLE Heart Rate band to the network as Lab Streaming Layer marker streams.
What it does
- Scans for BLE bands advertising the standard Heart Rate service (
0x180D). - Connects on tap; subscribes to the Heart Rate Measurement characteristic (
0x2A37). - Pushes two LSL outlets:
HR <devicename>— heart rate (bpm)RR <devicename>— beat-to-beat intervals in milliseconds (rounded int)
- Foreground service keeps the GATT connection alive when the screen is off.
Supported bands
Any BLE Heart Rate band exposing RR intervals: Polar H10 (tested), Wahoo TICKR, Garmin HRM-Pro, Coospo, Decathlon Kalenji, Suunto Smart Sensor, etc.
Install
Sideload RRStreamer-v0.1.0.apk on Android 8.0+ (API 26+). Allow installs from your browser, then open the file. Tested on Android 15 (API 35).
Verify the stream
On any machine on the same Wi-Fi:
pip install pylsl && python scripts/verify_lsl.py