Fully functional ant+ to bluetooth bridge.
This commit is contained in:
parent
eb6fdd6b16
commit
29d7dc1632
@ -27,7 +27,8 @@ func resetAndWait(drv io.ReadWriter) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func listenForAntDevice(vendorId gousb.ID, productId gousb.ID, deviceNumber uint32) {
|
func ListenForTrainer(vendorId gousb.ID, productId gousb.ID, deviceNumber uint32,
|
||||||
|
events chan<- Event) {
|
||||||
drv, err := usb.GetDevice(vendorId, productId)
|
drv, err := usb.GetDevice(vendorId, productId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
@ -58,9 +59,18 @@ func listenForAntDevice(vendorId gousb.ID, productId gousb.ID, deviceNumber uint
|
|||||||
|
|
||||||
switch msg.DeviceType() {
|
switch msg.DeviceType() {
|
||||||
case ant.DEVICE_TYPE_POWER:
|
case ant.DEVICE_TYPE_POWER:
|
||||||
|
// Check data page first
|
||||||
|
page := msg[4] & 0x7F // mask toggle bit
|
||||||
|
if page != 0x10 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
cur := ant.PowerMessage(msg)
|
cur := ant.PowerMessage(msg)
|
||||||
fmt.Printf("%v: power: %dW cadence: %d rpm\n",
|
fmt.Printf("%v: power: %dW cadence: %d rpm\n",
|
||||||
msg.DeviceNumber(), cur.InstantaneousPower(), cur.InstantaneousCadence())
|
msg.DeviceNumber(), cur.InstantaneousPower(), cur.InstantaneousCadence())
|
||||||
|
events <- Event{
|
||||||
|
Power: cur.InstantaneousPower(),
|
||||||
|
Cadence: cur.InstantaneousCadence(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,7 +17,7 @@ func must(err error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func ExposeBluetooth() {
|
func ExposeBluetooth(events <-chan Event) {
|
||||||
must(adapter.Enable())
|
must(adapter.Enable())
|
||||||
|
|
||||||
var powerChar bluetooth.Characteristic
|
var powerChar bluetooth.Characteristic
|
||||||
@ -49,14 +49,13 @@ func ExposeBluetooth() {
|
|||||||
var lastCompletedRev float64 // time in 1/1024s of last completed revolution
|
var lastCompletedRev float64 // time in 1/1024s of last completed revolution
|
||||||
lastUpdate := time.Now()
|
lastUpdate := time.Now()
|
||||||
var elapsedTicks float64
|
var elapsedTicks float64
|
||||||
for {
|
for event := range events {
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
deltaT := now.Sub(lastUpdate).Seconds()
|
deltaT := now.Sub(lastUpdate).Seconds()
|
||||||
lastUpdate = now
|
lastUpdate = now
|
||||||
|
|
||||||
sec := now.Second()
|
watts := event.Power
|
||||||
watts := uint16(100 + sec)
|
rpm := float64(event.Cadence)
|
||||||
rpm := float64(50 + sec)
|
|
||||||
|
|
||||||
totalRevs += rpm / 60.0 * deltaT
|
totalRevs += rpm / 60.0 * deltaT
|
||||||
elapsedTicks += deltaT * 1024.0
|
elapsedTicks += deltaT * 1024.0
|
||||||
@ -77,7 +76,5 @@ func ExposeBluetooth() {
|
|||||||
powerChar.Write(payload)
|
powerChar.Write(payload)
|
||||||
fmt.Printf("watts: %d rpm: %.0f completedRevs: %.0f lastRevTime: %.0f\n",
|
fmt.Printf("watts: %d rpm: %.0f completedRevs: %.0f lastRevTime: %.0f\n",
|
||||||
watts, rpm, completedRevs, lastCompletedRev)
|
watts, rpm, completedRevs, lastCompletedRev)
|
||||||
|
|
||||||
time.Sleep(250 * time.Millisecond)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
6
cmd/bridge/event.go
Normal file
6
cmd/bridge/event.go
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
type Event struct {
|
||||||
|
Power uint16
|
||||||
|
Cadence uint8
|
||||||
|
}
|
||||||
@ -1,26 +1,20 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
|
||||||
"github.com/google/gousb"
|
"github.com/google/gousb"
|
||||||
)
|
)
|
||||||
|
|
||||||
func oldMain() {
|
func main() {
|
||||||
|
exec.Command("hciconfig", "hci0", "down").Run()
|
||||||
|
exec.Command("hciconfig", "hci0", "up").Run()
|
||||||
|
|
||||||
var vendorId gousb.ID = 0x0fcf
|
var vendorId gousb.ID = 0x0fcf
|
||||||
var productId gousb.ID = 0x1008
|
var productId gousb.ID = 0x1008
|
||||||
var deviceNumber uint32 = 3001
|
var deviceNumber uint32 = 3001
|
||||||
|
|
||||||
listenForAntDevice(vendorId, productId, deviceNumber)
|
events := make(chan Event)
|
||||||
|
go ListenForTrainer(vendorId, productId, deviceNumber, events)
|
||||||
fmt.Println("channel closed")
|
ExposeBluetooth(events)
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
exec.Command("hciconfig", "hci0", "down").Run()
|
|
||||||
exec.Command("hciconfig", "hci0", "up").Run()
|
|
||||||
|
|
||||||
ExposeBluetooth()
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user