fl3xbl0w Projektlogo

Laufband-Motorsteuerung - fl3xbl0w

Veröffentlicht am 28. Mai 2022

Reverse-Engineering-Projekt. Es begann mit dem Bowflex Laufband 22, wurde jedoch für jede von Nautilus Inc. (Nautilus, Bowflex, Schwinn) verkaufte Android-gesteuerte Maschine verallgemeinert.

Dies gilt hauptsächlich für das Laufband 22 & Laufband 56.

Die Motorsteuerplatine wird von Electronics Way Industry hergestellt.

Motorsteuerungsplatine B017D

Anhand des von Nautilus Inc. bereitgestellten Servicehandbuchs (Sicherung auf archive.org):

Elektrisches Diagramm des Laufbands

Konzentration speziell auf diesen Teil:

Kommunikationsweg des Laufbands

Wir können das “Kommunikationskabel”, das die Motorsteuerung verbindet, als 5-poliges Kabel identifizieren. Es gibt nur einen 5-poligen Anschluss. Ich habe die Kabel mit ihren entsprechenden Farben beschriftet (Daten & Schalter sind opto-isoliert):

KabelfarbeBezeichnung
rotGND
weißRXD
schwarzTXD
gelb+12
grünSW

Die Platine ist nicht direkt mit der Android-Konsole verbunden.

Der einzige 5-polige Anschluss ist von Molex. Eine Google-Suche nach “kleine Molex-Anschlüsse” führte mich zu einem Bild von dem, was sie Molex Micro-Fit 3.0 Single Row (5-Pin) nennen, das verwendet wird, um die Motorsteuerplatine zu verbinden:

Molex Micro-Fit 3.0 Anschluss

AliExpress Link

Beim Blick in NautilusLauncher.apk mit jadx-gui kann ich sehen, dass sie das Android-Tablet mit ihrer “Universal Console” über Serial bei 230400 Baud (unter Verwendung von /dev/ttyS4) kommunizieren. DAS ist NICHT das, was wir hier analysieren. Das bezieht sich auf die Kommunikation zwischen Android und der “Universal Console”. Wir untersuchen die Kommunikation zwischen dem “Button Panel Controller” und der “Motorsteuerungsplatine”, wodurch drei Platinen als mögliche Fehlerquellen ausgeschlossen werden.

Der Versuch, eine ESP32- oder eine CH340-basierte Serial-Brücke direkt mit den Kabeln zwischen dem Laufbandrahmen und der Bowflex-Steuerplatine zu verbinden, führte dazu, dass das Laufbandrahmen nicht korrekt initialisiert wurde, woraufhin ich einen Logikanalysator beschafft habe, um weiter zu untersuchen.

Aktualisierung 2025

In den letzten Wochen und fast drei Jahren, nachdem ich damit begonnen habe, haben sich mehrere Leute bei mir gemeldet und nach den Fortschritten gefragt. Damit wurde meine anfängliche Annahme bestätigt, dass das Laufbandsystem furchtbar ist und es nur eine Frage der Zeit sei, bis die Geräte den Geist aufgeben würden. Es schien ein guter Zeitpunkt zu sein, meinen Logikanalysator, der bis jetzt nur Staub angesetzt hatte, einzusetzen.

Beim Anschluss des Logikanalysators an die TXD- und RXD-Leitungen (und natürlich GND) konnte ich sofort beginnen, Nachrichten zwischen beiden Parteien abzufangen, ohne die Kommunikation zu unterbrechen. Ich vermute, dass ich anfänglich keinen ESP32 aufgrund von Impedanzproblemen verwenden konnte. Nach ein paar Minuten Trial-and-Error kam ich zu folgender Serial-Konfiguration:

- 2400 Baud
- 8 Bits pro Frame
- 1 Stoppbit
- Kein Paritätsbit
- Least Significant Bit zuerst gesendet
- TXD: Invertiertes Signal
- RXD: Nicht invertiertes Signal

Mit diesen Einstellungen konnte ich deutlich definierte Nachrichten sehen.

Abfangen von UART-Nachrichten

Abfangen von UART-Nachrichten während des Startvorgangs

Einige Dinge, die mir sofort aufgefallen sind:

  • Alle Nachrichten, die vom Button Panel gesendet werden, beginnen mit 0x68
  • Alle Nachrichten, die von der Motorsteuerplatine gesendet werden, beginnen mit 0x73
  • Nachrichten von beiden Parteien enden mit 0x43
  • Generell werden Nachrichten vom Button Panel 100 ms nach Empfang einer Nachricht von der Motorsteuerplatine gesendet
    • Außer während des Startvorgangs, wo es in einem Fall eine Differenz von 300 ms gibt
  • Das Rauschen auf den Kommunikationsleitungen ist unglaublich, was das Lesen der Nachrichten erschwert

Mit dieser Grundlage beginnt der Prozess, die Nachrichten zu entschlüsseln und zu verstehen, was zwischen beiden Parteien kommuniziert wird, was kontrollierte Änderungen in einem Trainingsprogramm ermöglicht.

Abfangen von Geschwindigkeitsänderungen

Durch kontrollierte Änderungen spezifischer Geschwindigkeiten können die folgenden Werte, die an die Motorsteuerplatine gesendet werden, beobachtet werden:

Geschwindigkeit auf dem BildschirmGesendete Nachricht
0,0 km/h (Wartend oder pausiert)0x68 0x08 0x80 0x50 0x00 0x0A 0x00 0x00 0xE2 0x43
2,0 km/h0x68 0x08 0x80 0x50 0x14 0x0A 0x00 0x00 0xF6 0x43
3,0 km/h0x68 0x08 0x80 0x50 0x1D 0x0A 0x00 0x00 0xFF 0x43
5,0 km/h0x68 0x08 0x80 0x50 0x31 0x0A 0x00 0x00 0x13 0x43

Es ist zu beobachten, dass Byte 5 und Byte 9 sich ändern. Byte 5 scheint die Geschwindigkeit in Hexadezimal zu sein, und Byte 9 scheint eine Prüfsumme zu sein.

Umrechnung der Werte von Byte 5 in Dezimal:

Geschwindigkeit auf dem BildschirmHexadezimalDezimal
0,0 km/h (Wartend oder pausiert)0x000
2,0 km/h0x1420
3,0 km/h0x1D29
5,0 km/h0x3149

Nachdem ich vor Jahren einige Teile des Android-Systems dekompiliert hatte, erinnerte ich mich, dass bei der Konfiguration des Geräts im metrischen System die Bowflex-Anwendung intern die Umrechnung von metrisch zu imperial durchführt, um mit der “UCB” zu kommunizieren. Die Motorsteuerplatine scheint das metrische System zu verwenden, und anscheinend gibt es einen Präzisionsverlust bei der Umrechnung von metrisch zu imperial und dann zurück zu metrisch (was die Motorsteuerung erwartet), da alles mit einer Dezimalstelle behandelt wird. War es so schwer, es richtig zu machen, Nautilus?

Wenn man das berücksichtigt und einen Skalierungsfaktor von 10 anwendet, passt es perfekt zu den an die Motorsteuerplatine gesendeten Werten. Daher lautet die Formel:

Dezimalwert = Geschwindigkeit in km/h × 10

Abfangen von Neigungsänderungen

Nach demselben Verfahren wie bei der Geschwindigkeit können die folgenden Werte, die an die Motorsteuerplatine gesendet werden, beobachtet werden:

Neigung auf dem BildschirmGesendete Nachricht
-5°0x68 0x08 0x80 0x50 0x1D 0x00 0x00 0x00 0xF5 0x43
0x68 0x08 0x80 0x50 0x1D 0x32 0x00 0x00 0x27 0x43
0x68 0x08 0x80 0x50 0x1D 0x8C 0x00 0x00 0x81 0x43

In diesem Fall scheint Byte 6 die Neigung in Hexadezimal zu sein, und es bestätigt, dass Byte 9 eine Prüfsumme ist.

Umrechnung der Werte von Byte 6 in Dezimal:

Neigung auf dem BildschirmHexadezimalDezimal
-5°0x000
0x3250
0x8C140

Die Formel, die perfekt zu den an die Motorsteuerplatine gesendeten Werten passt, lautet:

Dezimalwert = (Winkel + 5) × 10

Prüfsumme

Dies scheint eine einfache und standardmäßige Prüfsumme in Mikrocontrollern zu sein, bei der alle Bytes der Nachricht addiert werden und ein Überlauf auftritt, sobald 256 erreicht ist. Eine einfache Darstellung wäre etwas wie:

uint8_t calculateChecksum(uint8_t *msg) {
  return msg[1] + msg[2] + msg[3] + msg[4] + msg[5] + msg[6] + msg[7];
}

Durch die Verwendung von uint8_t als Rückgabetyp tritt der Überlauf natürlich auf. Eine for-Schleife könnte verwendet werden, um die Werte zu summieren und sum % 256 zurückzugeben, aber das wäre für Mikrocontroller langsamer ohne wirklichen Nutzen.

Nächste Schritte

  • Ein logisches Verständnis des Startprozesses erlangen oder ihn zumindest replizieren
  • Interaktionen mit dem Sicherheitsschlüssel erfassen (das rote Teil, das auf der Kleidung platziert wird)
  • Die von der Motorsteuerplatine gesendeten Nachrichten interpretieren, die sich vermutlich nicht stark von den vom Button Panel gesendeten Nachrichten unterscheiden

Damit kann die Funktionalität des Button Panels repliziert werden, und damit kann das Laufband von einem Mikrocontroller aus gesteuert werden.

— Fortsetzung folgt —

Inhalt übersetzt von o1-mini

©2022-2025 Sebastian Barrenechea. Alle Rechte vorbehalten.

Erstellt mit Astro v5.5.4.