Проект реверс-инжиниринга. Начался с беговой дорожки Bowflex 22, но впоследствии был обобщен для любой машины на Android, продаваемой компанией Nautilus Inc. (Nautilus, Bowflex, Schwinn).
Это в основном относится к Treadmill 22 и Treadmill 56.
Плата управления двигателем производится компанией Electronics Way Industry.
Учитывая сервисный мануал, предоставленный Nautilus Inc. (резервная копия на archive.org):
Фокусируясь конкретно на этой части:
Мы можем идентифицировать “коммуникационный кабель”, который соединяет плату управления двигателем, как кабель с 5 контактами. Есть только один 5-контактный разъем. Я пометил кабели соответствующими цветами (данные и переключатель оптоизолированы):
Цвет кабеля | Метка |
---|---|
красный | GND |
белый | RXD |
черный | TXD |
желтый | +12 |
зеленый | SW |
Плата не подключена напрямую к консоли Android.
Единственный 5-контактный разъем от Molex. Поиск в Google по запросу “маленькие разъемы Molex” привел меня к изображению того, что они называют Molex Micro-Fit 3.0 Single Row (5-Pin)
, который используется для подключения платы управления двигателем:
Посмотрев в NautilusLauncher.apk
с помощью jadx-gui
, я вижу, что они связывают Android-планшет с их “Универсальной консолью” через последовательный порт со скоростью 230400 бод (используя /dev/ttyS4
). ЭТО не то, что мы анализируем здесь. Это относится к связи между Android и “Универсальной консолью”. Мы исследуем связь между “Контроллером кнопочной панели” и “Платой управления двигателем”, тем самым исключая три платы как потенциальные точки отказа.
Попытка напрямую подключить ESP32 или мост на базе CH340 к кабелям между основанием беговой дорожки и платой управления Bowflex привела к некорректной инициализации основания беговой дорожки, после чего я приобрел логический анализатор для дальнейшего исследования.
В последние недели, почти три года после того, как я начал этим заниматься, несколько человек связались со мной, чтобы узнать о прогрессе в этом направлении, подтвердив мое первоначальное предположение, что система беговой дорожки ужасна и что это было лишь вопросом времени, прежде чем машины начнут выходить из строя. Похоже, это было хорошее время, чтобы использовать мой логический анализатор, который до сих пор только собирал пыль.
Подключив логический анализатор к линиям TXD и RXD (и GND, конечно), я сразу же смог начать перехват сообщений между обеими сторонами без прерывания связи. Полагаю, изначально я не мог использовать ESP32 из-за проблем с импедансом. После нескольких минут проб и ошибок, я пришел к следующей конфигурации последовательного порта:
- 2400 бод
- 8 бит на кадр
- 1 стоповый бит
- Без бита четности
- Отправка младшего значащего бита первой
- TXD: инвертированный сигнал
- RXD: не инвертированный сигнал
С этими настройками я мог четко видеть определенные сообщения.
Перехват сообщений UART во время процесса загрузки
Некоторые вещи, которые я заметил сразу:
0x68
0x73
0x43
Исходя из этого, начинается процесс расшифровки сообщений и понимания того, что передается между обеими сторонами, внося контролируемые изменения в тренировочную программу.
Внося контролируемые изменения в определенные скорости, можно наблюдать следующие значения, отправляемые на плату управления двигателем:
Скорость на экране | Отправленное сообщение |
---|---|
0.0 км/ч (ожидание или пауза) | 0x68 0x08 0x80 0x50 0x00 0x0A 0x00 0x00 0xE2 0x43 |
2.0 км/ч | 0x68 0x08 0x80 0x50 0x14 0x0A 0x00 0x00 0xF6 0x43 |
3.0 км/ч | 0x68 0x08 0x80 0x50 0x1D 0x0A 0x00 0x00 0xFF 0x43 |
5.0 км/ч | 0x68 0x08 0x80 0x50 0x31 0x0A 0x00 0x00 0x13 0x43 |
Можно заметить, что изменяются байты 5 и 9. Байтов 5, по-видимому, соответствует скорость в шестнадцатеричном формате, а байт 9, вероятно, является контрольной суммой.
Преобразование значений байта 5 в десятичное:
Скорость на экране | Шестнадцатеричное | Десятичное |
---|---|---|
0.0 км/ч (ожидание или пауза) | 0x00 | 0 |
2.0 км/ч | 0x14 | 20 |
3.0 км/ч | 0x1D | 29 |
5.0 км/ч | 0x31 | 49 |
Распаковав некоторые части системы Android несколько лет назад, я вспомнил, что при настройке машины в метрической системе приложение Bowflex внутренне выполняет преобразование из метрической в имперскую систему для связи с “UCB”. Плата управления двигателем, по-видимому, использует метрическую систему, и, очевидно, происходит потеря точности при преобразовании из метрической в имперскую систему, а затем обратно в метрическую (что ожидает плата управления двигателем), поскольку все обрабатывается с точностью до 1 десятичного знака. Так сложно было сделать это правильно, Nautilus?
Учитывая это, и если применить коэффициент масштабирования 10, это идеально соответствует значениям, отправляемым на плату управления двигателем. Поэтому формула будет:
Десятичное значение = Скорость в км/ч × 10
Следуя тому же процессу, что и со скоростью, можно наблюдать следующие значения, отправляемые на плату управления двигателем:
Наклон на экране | Отправленное сообщение |
---|---|
-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 |
В этом случае байт 6, по-видимому, соответствует наклону в шестнадцатеричном формате, и это подтверждает, что байт 9 является контрольной суммой.
Преобразование значений байта 6 в десятичное:
Наклон на экране | Шестнадцатеричное | Десятичное |
---|---|---|
-5° | 0x00 | 0 |
0° | 0x32 | 50 |
9° | 0x8C | 140 |
Формула, которая идеально соответствует значениям, отправляемым на плату управления двигателем:
Десятичное значение = (Угол + 5) × 10
Это кажется простой и стандартной контрольной суммой в микроконтроллерах, складывающей все байты сообщения и вызывающей переполнение, когда сумма достигает 256. Простое представление могло бы быть следующим:
uint8_t calculateChecksum(uint8_t *msg) {
return msg[1] + msg[2] + msg[3] + msg[4] + msg[5] + msg[6] + msg[7];
}
Используя uint8_t
в качестве типа возвращаемого значения, переполнение происходит естественно. Можно использовать for loop
для суммирования значений и возвращения sum % 256
, но это было бы медленнее для микроконтроллеров без реальной пользы.
Таким образом, функциональность кнопочной панели можно будет воспроизвести, и, следовательно, беговую дорожку можно будет управлять с помощью микроконтроллера.
— Продолжение следует —
©2022-2025 Себастьян Барренечеа. Все права защищены.
Создано с использованием Astro v5.6.1.