Laufband-Hacking: NordicTrack C990 mit Raspberry Pi steuern
NordicTrack C990 per Raspberry Pi Zero hacken — WebSocket-Steuerung, selbstgebauter Bandsensor und Live-Dashboard ohne iFit-Abo.
Mein NordicTrack C990 hat einen Steigungsmotor, Geschwindigkeitsregelung und ein 7-Zoll-Display — aber alles steckt hinter einem iFit-Abo. Die Lösung: ein Raspberry Pi Zero W, der das Laufband über WebSocket steuert, einen selbstgebauten Bandsensor und ein Live-Dashboard im Browser.
Das Setup
- Laufband: NordicTrack C990 (Modell ETNE14716) mit Android-Steuereinheit
- Controller: Raspberry Pi Zero W
- Kommunikation: WebSocket-API auf dem Laufband-Display
- Extras: GPIO-Sensor für unabhängige Geschwindigkeitsmessung
- Frontend: Socket.io-Dashboard auf dem Pi
Die Android-Einheit des C990 läuft intern mit einer WebSocket-API. Dank der Community rund um iFit-Laufbänder — u.a. die Projekte nordichack und iFitController — sind die Kommandos dokumentiert. Das Laufband akzeptiert JSON-Nachrichten im lokalen Netz.
Die Laufband-Klasse: WebSocket-Steuerung
Das Herzstück ist eine Node.js-Klasse, die sich per WebSocket mit dem Laufband verbindet und alle Werte in Echtzeit empfängt:
const WebSocketClient = require("websocket").client;
const client = new WebSocketClient();
const EventEmitter = require("events");
class Laufband extends EventEmitter {
constructor(ip) {
super();
this.ip = ip;
this.running = false;
this.promise = new Promise((resolve) => {
client.connect(`ws://${this.ip}/control`);
client.on("connect", connection => {
this.socket = connection;
connection.on("message", msg => {
const json = JSON.parse(msg.utf8Data);
if (json.values) {
if (json.values["Current KPH"]) {
this.kmh = parseFloat(json.values["Current KPH"]);
if (this.kmh > 0 && !this.running) {
this.running = true;
this.emit("start", this.data);
}
}
this.emit("data", this.data);
}
});
resolve(this);
});
});
}
}
Steigung und Geschwindigkeit setzen ist dann simpel — eine JSON-Nachricht mit dem gewünschten Wert:
this.incline = steigung => {
this.socket.sendUTF(JSON.stringify({
type: "set",
values: { Incline: steigung + "" }
}));
};
this.speed = kmh => {
this.socket.sendUTF(JSON.stringify({
type: "set",
values: { KPH: kmh + "" }
}));
};
Das Laufband antwortet kontinuierlich mit dem aktuellen Status: Geschwindigkeit, Steigung, Distanz, Gesamtzeit. Der Steigungsbereich liegt beim C990 bei 0% bis 12%.
Der Bandsensor: Hardware-Hacking am GPIO
Das Spannendste am Projekt: ein selbstgebauter Sensor, der die Geschwindigkeit unabhängig vom Laufband misst. Ein Magnetschalter am Laufband-Rahmen erkennt jede Umdrehung des Bandes (Umfang: 3140mm) über einen GPIO-Pin am Raspberry Pi.
const gpio = require("rpi-gpio");
class Sensor extends EventEmitter {
constructor(GPIO, BELT_LENGTH) {
super();
this.beltlength = BELT_LENGTH; // 3140mm
this.data = { distanz: 0, ticks: 0 };
gpio.on("change", (channel, val) => {
if (val) this.calc();
});
gpio.setup(GPIO, gpio.DIR_IN, gpio.EDGE_BOTH);
}
calc() {
const blkm = this.beltlength / 1000 / 1000;
this.data.distanz += blkm;
this.data.ticks++;
const ts2 = new Date().getTime();
const diff = ts2 - this.ts;
this.data.ms = this.beltlength / diff;
this.data.kmh = parseFloat(
(this.data.ms / 1000 / (1 / 3600)).toFixed(2)
);
this.emit("data", this.data);
this.ts = ts2;
}
}
Der Sensor berechnet aus der Zeit zwischen zwei Umdrehungen die aktuelle Geschwindigkeit in km/h. Damit lässt sich die Genauigkeit des eingebauten Laufband-Sensors verifizieren — und man hat eine zweite, unabhängige Datenquelle.
Server und Live-Dashboard
Ein Express-Server auf dem Pi bringt alles zusammen. Socket.io streamt die Daten in Echtzeit an ein minimales Frontend:
const sensor = new Sensor(40, 3140).on("data", d => {
if (LB.data) d.laufband = LB.data;
// Workout-Daten mitloggen
if (workoutName) {
fs.appendFileSync(workoutName,
`${time}|${d.laufband.Kilometers}|${d.laufband.Incline}` +
`|${d.laufband.KPH}|${sensor.data.distanz}|${sensor.data.kmh}\n`
);
}
if (socket) socket.emit("data", d);
});
Das Dashboard zeigt Geschwindigkeit, Distanz, Steigung und Sensor-Ticks. Bewusst minimal — HTML, etwas CSS, Vanilla JS. Auf dem Pi Zero zählt jedes Megabyte. Jedes Workout wird automatisch als Textdatei mitgeschrieben — Zeitstempel, Distanz, Steigung, Speed vom Laufband und vom Sensor. So lassen sich die Läufe später auswerten.
Herausforderungen
Netzwerk: Der Pi Zero W hat nur 2.4 GHz WLAN. Im Keller war das Signal anfangs zu schwach — ein WLAN-Repeater hat das gelöst.
Sensor-Kalibrierung: Die Bandlänge exakt zu messen ist entscheidend. Eine Abweichung von wenigen Zentimetern summiert sich über eine Stunde Laufen spürbar auf.
WebSocket-Stabilität: Die Verbindung zum Laufband ist solide, solange man auf dem gleichen Subnetz bleibt. Ab und zu bricht sie nach Standby ab — ein Reconnect-Handler im Code fängt das ab.
Fazit
Das Projekt hat aus einem 900€-Laufband mit Zwangs-Abo eine offene Plattform gemacht. Steigung per Code setzen, unabhängige Geschwindigkeitsmessung über einen Magnet-Sensor und automatisches Workout-Logging — alles mit einem 15€-Raspberry Pi Zero. Wer ein iFit-fähiges Laufband hat und gerne bastelt: Die Community hat die Vorarbeit bei der WebSocket-Dokumentation gemacht. Der Rest ist Node.js und ein Nachmittag Löten.
Timo Sütterlin
Fullstack-Entwickler — Web, Mobile, KI