| .opencode | ||
| cmd/bridge | ||
| go.mod | ||
| go.sum | ||
| LICENSE | ||
| Makefile | ||
| out | ||
| README.md | ||
| setup.md | ||
ANT+ to Bluetooth LE Bridge
Bridge an ANT+ cycling power trainer over Bluetooth Low Energy, allowing modern devices that don't support ANT+ to receive power and cadence data.
Why this exists
Modern training apps and devices (phone apps, many power meter displays) support Bluetooth LE but lack ANT+ radios. Previously, hardware-based Bluetooth-to-ANT+ bridges were available for this purpose, but these have now been discontinued. This project provides a simple, software-based alternative using a standard USB ANT+ dongle. This bridge listens to ANT+ data from a wired trainer and re-broadcasts it as a standard Cycling Power Profile service over BLE.
How it works
- Opens a USB ANT+ dongle (vendor ID
0x0fcf) and listens for broadcast messages from a specific trainer device number. - Parses power (Watts) and cadence (RPM) from the trainer's ANT+ data pages.
- Exposes a Cycling Power Measurement BLE service via the system's Bluetooth adapter, updating values as new ANT+ messages arrive.
Requirements
- Linux
- D-Bus (for BlueZ Bluetooth management)
- A Bluetooth adapter
- An ANT+ USB dongle
- An ANT+ cycling power trainer
Note: This program must be run as root to access the USB dongle.
Tested hardware
- USB dongle: ANT USBStick2 (Dynastream Innovations, vendor
0x0fcf, product0x1008)
Setup
The Linux usbserial driver must be prevented from claiming the ANT+ dongle. Create the following udev rule:
sudo tee /etc/udev/rules.d/99-ant-usb.rules > /dev/null <<EOF
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fcf", ATTRS{idProduct}=="1008", ENV{MODALIAS}="ignore"
EOF
The vendor id and product id above can be obtained from the dmesg output after inserting the USB dongle.
Then reload the rules and reconnect the dongle:
sudo modprobe -r usb_serial_simple
sudo udevadm control --reload-rules
sudo udevadm trigger
Verify the dongle is no longer claimed by usbserial:
dmesg | tail -5
Expected output:
usb 3-1.2.1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
usb 3-1.2.1: Product: ANT USBStick2
usb 3-1.2.1: Manufacturer: Dynastream Innovations
Installation
make build
The binary is built to bin/bridge.
Usage
# Use defaults (device 3001)
./bin/bridge
# Custom trainer device
./bin/bridge --device 0xbb9
# Custom vendor/product IDs
./bin/bridge --vendor 0x0fcf --product 0x1008 --device 3001
CLI Flags
| Flag | Default | Description |
|---|---|---|
--vendor |
0x0fcf |
USB vendor ID (hex or decimal, e.g. 0x0fcf or 4047) |
--product |
0x1008 |
USB product ID (hex or decimal) |
--device |
3001 |
ANT+ device number (hex or decimal, e.g. 3001 or 0xbb9) |
--help |
Show help | |
--version |
Show version info |
Output
2026-05-26 11:00:34 ANT Bridge abc1234 built 2026-05-26T11:00:00
2026-05-26 11:00:34 vendor: 0x0fcf/4047
2026-05-26 11:00:34 product: 0x1008/4104
2026-05-26 11:00:34 device: 0xbb9/3001
2026-05-26 11:00:34 BLE advertising...
2026-05-26 11:00:34 bt: watts: 150 rpm: 80 completedRevs: 1234 lastRevTime: 4890 processingTime: 250us
Development
make build # Build with ldflags (version, build time)
make clean # Remove build artifacts
Known issues
It has been observed that during use the wattage sometimes drops briefly to 0 but then quickly recovers. Logging will hopefully pinpoint the issue should it occur again.