BLE FTMS, Running Speed and Cadence (RSC), and DIRCON server for NordicTrack and ProForm fitness equipment.
NordicFTMS is an Android app that runs on your iFit-enabled treadmill, bike, elliptical, or rower and exposes it as a standard Bluetooth FTMS (Fitness Machine Service) device. It can also expose compatible equipment over Wahoo DIRCON on your local network. Any FTMS-compatible app — PowerTread, Zwift, Kinomap, and others — can connect over Bluetooth, and supported treadmill apps can also connect over Wi-Fi through DIRCON.
If you found NordicFTMS useful and would like to support continued development
NordicFTMS communicates with the machine hardware through the GlassOS gRPC interface running on the machine's own Android system. It reads live metrics (speed, incline, distance, cadence, watts) via gRPC streaming subscriptions and broadcasts them over BLE FTMS or DIRCON. It also receives control commands (set speed, set incline, set resistance) and forwards them to the hardware via gRPC.
- Zero configuration — auto-starts on boot, auto-detects machine type (treadmill, bike, elliptical, rower)
- Standard BLE FTMS protocol — works with any FTMS-compatible app
- RSC treadmill sensor — advertises running speed and distance alongside FTMS for compatible Bluetooth foot-pod clients
- DIRCON treadmill support — supported treadmills can be discovered over Wi-Fi by apps that support Wahoo Direct Connect
- Bidirectional control — read metrics AND control incline/resistance from your phone
- Runs silently in background — no user interaction needed after initial installls
- Direct hardware communication — uses gRPC to talk directly to GlassOS
For standard Bluetooth FTMS, NordicFTMS advertises as NordicFTMS.
NordicFTMS also exposes a persistent per-installation Bluetooth identity for apps that support reconnecting across Android BLE address changes. This requires client support; it does not fix auto-connect in existing PowerTread versions by itself. See backend troubleshooting and the identity integration guide.
For supported treadmills, NordicFTMS also advertises a DIRCON service on your local network using a KICKR RUN <id>-style name. This allows Zwift to discover it as a controllable treadmill in addition to the normal run-speed sensor path.
In practice, that means:
- When running on Zwift, first connect the RUN SPEED device which should show as
KICKR RUN <id> - Then connect the same
KICKR RUN <id>within the CONTROLLABLE device. - Zwift will prompt you to allow incline control, be sure to allow it.
- Start running on Zwift!
- At any time you can manually set the incline on your treadmill and Zwift should relinquish control. Use the Zwift UI to re-enable control if and when desired.
[CAUTION]
Always remain in control of your treadmill and follow all safety precautions. Zwift can command steep inclines, especially on NordicTrack X-series treadmills with very high incline capability. If needed, manually change the incline and Zwift should relinquish control.
| Treadmills | Bikes |
|---|---|
| Speed (km/h) | Speed (km/h) |
| Incline (%) | Cadence (RPM) |
| Distance (m) | Resistance Level |
| Power (watts) |
Detected treadmills and incline trainers advertise both FTMS (0x1826) and
Running Speed and Cadence (0x1814) in one NordicFTMS advertisement and GATT
server. RSC is enabled automatically; bikes, ellipticals, and rowers keep their
existing FTMS behavior. An RSC client
and an FTMS app can subscribe independently, subject to the console's Bluetooth
connection limits.
On a watch that supports Bluetooth RSC foot pods, try adding NordicFTMS from
the watch's sensor menu as a Foot Pod (or use Search All), then use it for
an indoor/treadmill activity. If the watch offers speed and distance source
settings, select the foot pod for indoor use. Exact menus vary by model and
firmware. Garmin compatibility is not guaranteed: an epix Gen 2 running 26.09
did not discover the test console. Android manages the console's BLE addresses,
which may affect client compatibility.
RSC sends belt speed and cumulative distance. The mandatory cadence field is zero because NordicFTMS has no measured treadmill footfall cadence. Stride length, walking/running detection, and sensor calibration are not advertised. A watch may display zero cadence when using this sensor; use another source for cadence if needed. RSC cannot control speed or incline.
The RSC distance counter follows increases in the console's distance, continues across console workout resets, and lasts for the lifetime of the Android service. It is separate from FTMS workout distance. The RSC Set Cumulative Value procedure can reset or set this sensor counter without changing the console, FTMS, or DIRCON session. RSC clients should use distance differences relative to the beginning of their activity.
For protocol details and a hardware validation checklist, see RSC treadmill support.
- Enable privileged mode on your treadmill/bike (tap white area 10 times, wait 7 seconds, tap 10 more times)
- Enable USB debugging in Developer Options
- Install the APK via ADB:
adb connect <treadmill-ip>:5555 adb install NordicFTMS.apk
- Reboot the treadmill. NordicFTMS will auto-start in the background.
- Open your FTMS app (PowerTread, Zwift, etc.), scan for Bluetooth devices, and connect to
NordicFTMS. - For supported treadmills, if you are using Zwift on the same local network, also look for
KICKR RUN <id>in the DIRCON list and connect it as a Controllable treadmill.
- NordicTrack X11i Incline Trainer (ETNT22019, MT8163, Android 9)
More iFit v2 machines with GlassOS should work — please report your results!
./gradlew assembleDebugThe APK will be at app/build/outputs/apk/debug/app-debug.apk.
This project was inspired by and originally forked from QZ Companion by Roberto Viola (@cagnulein). Roberto's pioneering work on the QZ ecosystem — including the companion app and the QZ (qdomyos-zwift) fitness bridge — made it possible to connect NordicTrack machines to third-party fitness apps for the first time. His generous open-source contributions to the fitness community are deeply appreciated.
NordicFTMS would not exist without Roberto's foundational work.
GNU GENERAL PUBLIC LICENSE V3 — see LICENSE.