antplusbridge/README.md
Erik Brakkee ed4f75a93d docs: add README with setup instructions and tested hardware
Add comprehensive README.md covering project purpose, CLI usage,
and troubleshooting. Document the udev rule needed to prevent
usbserial from claiming the ANT+ dongle.

Add Tested hardware section listing the ANT USBStick2 and update
setup.md dmesg output accordingly.

Note: the bridge must be run as root to access the USB dongle.
2026-05-27 00:36:06 +02:00

110 lines
3.2 KiB
Markdown

# 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+ bridge boxes 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
1. Opens a USB ANT+ dongle (vendor ID `0x0fcf`) and listens for broadcast messages from a specific trainer device number.
2. Parses power (Watts) and cadence (RPM) from the trainer's ANT+ data pages.
3. 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`, product `0x1008`)
## Setup
The Linux `usbserial` driver must be prevented from claiming the ANT+ dongle. Create the following udev rule:
```bash
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
```
Then reload the rules and reconnect the dongle:
```bash
sudo modprobe -r usb_serial_simple
sudo udevadm control --reload-rules
sudo udevadm trigger
```
Verify the dongle is no longer claimed by `usbserial`:
```bash
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
```bash
make build
```
The binary is built to `bin/bridge`.
## Usage
```bash
# 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
```bash
make build # Build with ldflags (version, build time)
make clean # Remove build artifacts
```
The Makefile injects the git commit hash and build timestamp via ldflags for version information.