Heart-rate uplink: batching and a dropout buffer #66
Labels
No labels
area:companion
area:docs
area:shared
area:tooling
area:watchapp
blocker
kind:chore
kind:feature
kind:spike
kind:test
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
robert/PedalPebble#66
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Goal
Stop losing heart rate to Bluetooth dropouts.
Heart rate is generated on the watch (D3) and recorded on the phone (#20), and nothing connected those two facts. The uplink rate for heart rate was specified nowhere, and nothing buffered samples across a disconnection. NFR-R2 and NFR-R3 cover the phone's ride state, not the watch's samples.
On a bike the phone is in a jersey pocket with a body between it and the wrist. 2.4 GHz dropouts of tens of seconds are ordinary, not exceptional - so as planned, every one of them punched a hole in the recorded ride.
Batching also removes a message per second from the uplink, which the map view will want back.
Acceptance criteria
HR_SAMPLESmessage every 5 s, not one message per seconduint32 base_timestampthen a run ofuint8 bpmheap_bytes_free()and recorded - 10 minutes at 1 s is 600 bytes, but the production period may differFiles
watchapp/src/c/hrm.cwatchapp/src/c/proto.ccompanion/.../pebble/Proto.ktcompanion/.../ride/GpxRecorder.ktNotes
See D31 and docs/PROTOCOL.md section 5.
Update — 2026-09-02: do not assume a fixed sample cadence
The buffer specified "a run of
uint8bpm at the production sample period".HealthEventHeartRateUpdatefires irregularly, so a fixed-cadence run misattributes everytimestamp after the first — and those timestamps land in the recorded GPX, where nothing can recover
them (D46).
HR_SAMPLEScarriesuint32 base_timestampfollowed by(uint8 dt, uint8 bpm)pairs, wheredtis seconds since the previous sample in the run and0for the firstdtthat would exceed 254 s cuts the run; a new message starts instead