diff --git a/cmd/bridge/main.go b/cmd/bridge/main.go index 3df10a0..466e455 100644 --- a/cmd/bridge/main.go +++ b/cmd/bridge/main.go @@ -3,6 +3,7 @@ package main import ( "encoding/binary" "fmt" + "math" "os/exec" "time" @@ -53,31 +54,41 @@ func main() { })) must(adapter.DefaultAdvertisement().Start()) fmt.Println("BLE advertising...") - var crankRevs uint16 - var lastCrankEventTime uint16 + var totalRevs float64 + var lastCompletedRev float64 // time in 1/1024s of last completed revolution + lastUpdate := time.Now() + var elapsedTicks float64 for { - sec := time.Now().Second() + now := time.Now() + deltaT := now.Sub(lastUpdate).Seconds() + lastUpdate = now + + sec := now.Second() watts := uint16(100 + sec) - rpm := uint16(50 + sec) + rpm := float64(50 + sec) - // advance crank event time based on rpm - // time between crank events = 1024*60/rpm ticks - crankEventInterval := uint16(1024 * 60 / rpm) - lastCrankEventTime += crankEventInterval - crankRevs++ + totalRevs += rpm / 60.0 * deltaT + elapsedTicks += deltaT * 1024.0 + + completedRevs := math.Floor(totalRevs) + // time at which the last completed revolution occurred + // = current time - fractional part of revolution * time per revolution + fracRev := totalRevs - completedRevs + timePerRev := 1024.0 * 60.0 / rpm + lastCompletedRev = elapsedTicks - fracRev*timePerRev - // flags: bit 5 = crank revolution data present payload := make([]byte, 8) binary.LittleEndian.PutUint16(payload[0:], 0x20) binary.LittleEndian.PutUint16(payload[2:], watts) - binary.LittleEndian.PutUint16(payload[4:], crankRevs) - binary.LittleEndian.PutUint16(payload[6:], lastCrankEventTime) + binary.LittleEndian.PutUint16(payload[4:], uint16(completedRevs)) + binary.LittleEndian.PutUint16(payload[6:], uint16(lastCompletedRev)) powerChar.Write(payload) - fmt.Printf("watts: %d rpm: %d crankRevs: %d eventTime: %d\n", watts, rpm, crankRevs, lastCrankEventTime) + fmt.Printf("watts: %d rpm: %.0f completedRevs: %.0f lastRevTime: %.0f\n", + watts, rpm, completedRevs, lastCompletedRev) - time.Sleep(time.Second) + time.Sleep(250 * time.Millisecond) } }