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.
Anhand des von Nautilus Inc. bereitgestellten Servicehandbuchs (Sicherung auf archive.org):
Konzentration speziell auf diesen Teil:
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):
Kabelfarbe | Bezeichnung |
---|---|
rot | GND |
weiß | RXD |
schwarz | TXD |
gelb | +12 |
grün | SW |
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:
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.
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 während des Startvorgangs
Einige Dinge, die mir sofort aufgefallen sind:
0x68
0x73
0x43
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.
Durch kontrollierte Änderungen spezifischer Geschwindigkeiten können die folgenden Werte, die an die Motorsteuerplatine gesendet werden, beobachtet werden:
Geschwindigkeit auf dem Bildschirm | Gesendete Nachricht |
---|---|
0,0 km/h (Wartend oder pausiert) | 0x68 0x08 0x80 0x50 0x00 0x0A 0x00 0x00 0xE2 0x43 |
2,0 km/h | 0x68 0x08 0x80 0x50 0x14 0x0A 0x00 0x00 0xF6 0x43 |
3,0 km/h | 0x68 0x08 0x80 0x50 0x1D 0x0A 0x00 0x00 0xFF 0x43 |
5,0 km/h | 0x68 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 Bildschirm | Hexadezimal | Dezimal |
---|---|---|
0,0 km/h (Wartend oder pausiert) | 0x00 | 0 |
2,0 km/h | 0x14 | 20 |
3,0 km/h | 0x1D | 29 |
5,0 km/h | 0x31 | 49 |
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
Nach demselben Verfahren wie bei der Geschwindigkeit können die folgenden Werte, die an die Motorsteuerplatine gesendet werden, beobachtet werden:
Neigung auf dem Bildschirm | Gesendete Nachricht |
---|---|
-5° | 0x68 0x08 0x80 0x50 0x1D 0x00 0x00 0x00 0xF5 0x43 |
0° | 0x68 0x08 0x80 0x50 0x1D 0x32 0x00 0x00 0x27 0x43 |
9° | 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 Bildschirm | Hexadezimal | Dezimal |
---|---|---|
-5° | 0x00 | 0 |
0° | 0x32 | 50 |
9° | 0x8C | 140 |
Die Formel, die perfekt zu den an die Motorsteuerplatine gesendeten Werten passt, lautet:
Dezimalwert = (Winkel + 5) × 10
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.
Damit kann die Funktionalität des Button Panels repliziert werden, und damit kann das Laufband von einem Mikrocontroller aus gesteuert werden.
— Fortsetzung folgt —
©2022-2025 Sebastian Barrenechea. Alle Rechte vorbehalten.
Erstellt mit Astro v5.5.4.