more stable computation of lastRevtime

Only computing lastRevtime when we have made a new full rev.
This leads to more consistency in RPMs, especially when accelerating or
decellerating.
This commit is contained in:
Erik Brakkee 2026-06-06 16:58:26 +02:00
parent 7644ab2e4d
commit 13ea215996
2 changed files with 40 additions and 15 deletions

View File

@ -51,14 +51,19 @@ func ExposeBluetooth(events <-chan Event) {
must(adapter.DefaultAdvertisement().Start()) must(adapter.DefaultAdvertisement().Start())
logMsg("bt: BLE advertising...") logMsg("bt: BLE advertising...")
var totalRevs float64 var totalRevs float64 = 0.0
var lastCompletedRev float64 // time in 1/1024s of last completed revolution var elapsedTicks float64 = 0.0
lastUpdate := time.Now()
var elapsedTicks float64 // initial event.
event := <-events
lastUpdateTime := event.Now
var lastCompletedRevs float64 = 0.0
var lastRevTicks float64 = 0.0 // time in 1/1024s of last completed revolution
for event := range events { for event := range events {
now := event.Now now := event.Now
deltaT := now.Sub(lastUpdate).Seconds() deltaT := now.Sub(lastUpdateTime).Seconds()
lastUpdate = now lastUpdateTime = now
watts := event.Power watts := event.Power
rpm := float64(event.Cadence) rpm := float64(event.Cadence)
@ -67,23 +72,33 @@ func ExposeBluetooth(events <-chan Event) {
elapsedTicks += deltaT * 1024.0 elapsedTicks += deltaT * 1024.0
completedRevs := math.Floor(totalRevs) completedRevs := math.Floor(totalRevs)
if completedRevs > lastCompletedRevs {
// we crossed a new full RPM so comput the last time of that rotation
// time at which the last completed revolution occurred // time at which the last completed revolution occurred
// = current time - fractional part of revolution * time per revolution // = current time - fractional part of revolution * time per revolution
fracRev := totalRevs - completedRevs fracRev := totalRevs - completedRevs
timePerRev := 1024.0 * 60.0 / rpm ticksPerRev := 1024.0 * 60.0 / rpm
lastCompletedRev = elapsedTicks - fracRev*timePerRev
lastRevTicks = elapsedTicks - fracRev*ticksPerRev
lastCompletedRevs = completedRevs
} else {
// No change we need to emit the same data ss before.
}
payload := make([]byte, 8) payload := make([]byte, 8)
binary.LittleEndian.PutUint16(payload[0:], bleSignalDetectedFlag) binary.LittleEndian.PutUint16(payload[0:], bleSignalDetectedFlag)
binary.LittleEndian.PutUint16(payload[2:], watts) binary.LittleEndian.PutUint16(payload[2:], watts)
binary.LittleEndian.PutUint16(payload[4:], uint16(completedRevs)) binary.LittleEndian.PutUint16(payload[4:], uint16(lastCompletedRevs))
binary.LittleEndian.PutUint16(payload[6:], uint16(lastCompletedRev)) binary.LittleEndian.PutUint16(payload[6:], uint16(lastRevTicks))
if _, err := powerChar.Write(payload); err != nil { if _, err := powerChar.Write(payload); err != nil {
logPrintf("bt: failed to write power characteristic: %v\n", err) logPrintf("bt: failed to write power characteristic: %v\n", err)
} }
logPrintf("bt: watts: %d rpm: %.0f completedRevs: %.0f lastRevTime: %.0f processingDelay: %v\n", logPrintf("bt: watts: %d rpm: %.0f completedRevs: %.0f lastRevTime: %.0f processingDelay: %v\n",
watts, rpm, completedRevs, lastCompletedRev, time.Now().Sub(now)) watts, rpm, completedRevs, lastRevTicks, time.Now().Sub(now))
} }
logMsg("bt: BLE advertising stopped") logMsg("bt: BLE advertising stopped")
} }

12
run.sh
View File

@ -1,3 +1,13 @@
#!/bin/bash #!/bin/bash
systemd-inhibit --what=idle:sleep --why="Do not interrupt cycling" $( dirname $0 )/bin/bridge
while :
do
systemd-inhibit --what=idle:sleep --why="Do not interrupt cycling" $( dirname $0 )/bin/bridge "$@"
if [[ $? -ne 0 ]]
then
echo "ERROR: bridge exited with ERROR" 1>&2
fi
sleep 1
done