Протокол общения китайского контроллера МК с БК

Автор DarkByte, 28 Сен. 2018 в 13:23

« назад - далее »

0 Пользователи и 1 гость просматривают эту тему.

DarkByte

Стало интересно сделать свой БК с блекджеком и wifi несколько более расширенным функционалом, и для начала решил изучить протокол общения между контроллером и дисплеем. На удивление, готовых решений не нашлось. Самое близкое описание того, что мне требовалось, удалось найти в данной теме. Ввиду того, что в моём случае несколько другой БК и контроллер, решил создать отдельную тему.

Собственно контроллер китайский безымянный, на 12 мосфетов, в голове используется μPD79F9211.

Дисплейный модуль к контроллеру подключен 5 проводами:
  красный -- питание от батареи
  черный -- земля
  синий -- данные к БК
  зеленый -- данные к контроллеру
  белый -- сигнал зажигания от БК

Общение происходит по интерфейсу UART (уровни 3.3V), на скорости 1200 бод, пакетами по 15 байт.
Как такового общения не происходит, каждая сторона примерно по 5 раз в секунду отправляет текущее состояние.

Данные от контроллера к БК
После включения питания, БК отправляет в линию 1 байт F5, затем начинают отправляться пакеты по 15 байт. Первый пакет отправляется пустой и похоже с неправильной контрольной суммой. Дальше пакеты идут с данными, и можно примерно понять их содержимое. Нулевым байтом идёт идентификатор (устройства, типа пакета), он не меняется. Первым байтом идёт порядковый номер пакета, циклически меняется от 0 до 255. Второй байт всегда ноль. Далее следует десять байт зашифрованных данных. В тринадцатом байте находится псевдослучайное число, которые выполняет роль ключа шифрования. В четырнадцатом байте записана контрольная сумма пакета.

Начнём разбор с контрольной суммы, так как она считается уже от зашифрованного пакета. Считается она путём побитового сложения по модулю два (xor) всех байтов пакета. Например для второго пакета: 36^02^00^5c^5c^5c^00^5c^5c^5c^5c^d1^8d^5c = 68.

С шифрованием всё тоже не сильно сложно. Для того, чтобы расшифровать данные, нужно вычесть по модулю 256 из каждого байта байт под номером 13. Соответственно для обратной процедуры требуется прибавить это значение и записать его по модулю 256. Пример расшифровки пакетов:


0  1  2  3  4  5  6  7  8  9 10 11 12 13 14      0  1  2  3  4  5  6  7  8  9 10 11 12 13 14
00 01 00 23 23 23 00 23 23 23 23 23 23 23 37  => 00 01 00 00 00 00 00 00 00 00 00 00 00 00 37
36 02 00 5c 5c 5c 00 5c 5c 5c 5c d1 8d 5c 68  => 36 02 00 00 00 00 a4 00 00 00 00 75 31 00 0c
36 03 00 21 21 21 00 21 21 21 21 96 52 21 f1  => 36 03 00 00 00 00 df 00 00 00 00 75 31 00 d0
36 04 00 2a 2a 2a 00 2a 2a 2a 2a 9f 5b 2a f6  => 36 04 00 00 00 00 d6 00 00 00 00 75 31 00 cc
36 05 00 2f 2f 2f 00 2f 2f 2f 2f a4 60 2f f7  => 36 05 00 00 00 00 d1 00 00 00 00 75 31 00 c8
36 06 00 28 28 28 00 28 28 28 28 9d 59 28 f4  => 36 06 00 00 00 00 d8 00 00 00 00 75 31 00 cc
36 07 00 2d 2d 2d 00 2d 2d 2d 2d a2 5e 2d cd  => 36 07 00 00 00 00 d3 00 00 00 00 75 31 00 a0
36 08 00 26 26 26 00 26 26 26 26 9b 57 26 f2  => 36 08 00 00 00 00 da 00 00 00 00 75 31 00 cc
36 09 00 2b 2b 2b 00 2b 2b 2b 2b a0 5c 2b c3  => 36 09 00 00 00 00 d5 00 00 00 00 75 31 00 98
36 0a 00 24 24 24 00 24 24 24 24 99 55 24 f0  => 36 0a 00 00 00 00 dc 00 00 00 00 75 31 00 cc
36 0b 00 29 29 29 00 29 29 29 29 9e 5a 29 f9  => 36 0b 00 00 00 00 d7 00 00 00 00 75 31 00 d0
36 0c 00 52 52 52 00 52 52 52 52 c7 83 52 7e  => 36 0c 00 00 00 00 ae 00 00 00 00 75 31 00 2c
36 0d 00 57 57 57 00 57 57 57 57 cc 88 57 7f  => 36 0d 00 00 00 00 a9 00 00 00 00 75 31 00 28
36 0e 00 50 50 50 00 50 50 50 50 c5 81 50 7c  => 36 0e 00 00 00 00 b0 00 00 00 00 75 31 00 2c
36 0f 00 55 55 55 00 55 55 55 55 ca 86 55 75  => 36 0f 00 00 00 00 ab 00 00 00 00 75 31 00 20


Получив расшифрованные данные, можно продолжить их анализ.

На данный момент мне удалось определить, что байты 3-4-5 отвечают за отображение статусный иконок на дисплее:


бит -> байт76543210
3круизошибка двигателяошибка ручки газаошибка контроллерабатарея разряженакруиз-ошибка двигателя
4--нажат тормоз--ошибка ручки газа
5------нажат тормоз-

Байт 6 до декода всегда 0, соответственно после декодирования выглядит как псевдослучайное число.

Байты 7-8 показывают текущую скорость, выраженную в непонятных пока мне величинах. Например если записать в 8 байт 10, то отображается скорость 01.0км/ч, если 15->01.5, если 100->10.5, если 200->21.0.

Байт 9 не понятно что показывает, но при вращении колеса вперёд меняется с 00 на 0A.

Байт 10 отвечает за индикатор потребляемой мощности в условных единицах. На экране отображается в виде шкалы с 10 делениями, каждое деление имеет размер 10 единиц, соответственно можно передавать значения от 0 до 100 с шагом 10.

Байты 11 и 12 за время исследования протокола не менялись и пока не очень понятно, за что отвечают.


Данные от БК к контроллеру
После включения питания БК начинает примерно с той же скоростью отправлять пакеты той же длины контроллеру. Контрольная сумма считается аналогично. В отличии от получаемых пакетов, БК отправляет пакеты без шифрования, но в них по прежнему содержится псевдослучайное число в 5м байте, и контрольная сумма в 14 байте. Нулевой и первый байт пакета содержат идентификатор версии (протокола, устройства). Во втором байте передаётся порядковый номер пакета, который после включения начинается с 0x1a, доходит до 255 и продолжается с нуля. В третий, четвёртый и шестой байт записывается текущая передача (уровень максимальной поддержки), для уровня 0 передаётся значение 0, для 1-3, 2-6, 3-9, 4-12, 5-15. В байте 8 передаётся настройка P07 (ограничение максимальной скорости). В 9 байте передаются различные флаги (вкл\выкл света, круиза). 12 байт - число магнитов в колесе (настройка P02).

Пример пакетов:

0  1  2  3  4  5  6  7  8  9 10 11 12 13 14       0   1   2   3   4   5   6   7   8   9  10  11  12  13  14
01 03 1a 03 03 7c 03 00 64 80 00 00 34 38 8f  =>   1   3  26   3   3 124   3   0 100 128   0   0  52  56 143
01 03 1b 03 03 61 03 00 64 80 00 00 34 38 93  =>   1   3  27   3   3  97   3   0 100 128   0   0  52  56 147
01 03 1c 03 03 0a 03 00 64 80 00 00 34 38 ff  =>   1   3  28   3   3  10   3   0 100 128   0   0  52  56 255
01 03 1d 03 03 5f 03 00 64 80 00 00 34 38 ab  =>   1   3  29   3   3  95   3   0 100 128   0   0  52  56 171
01 03 1e 03 03 60 03 00 64 80 00 00 34 38 97  =>   1   3  30   3   3  96   3   0 100 128   0   0  52  56 151
01 03 1f 03 03 65 03 00 64 80 00 00 34 38 93  =>   1   3  31   3   3 101   3   0 100 128   0   0  52  56 147
01 03 20 03 03 5e 03 00 64 80 00 00 34 38 97  =>   1   3  32   3   3  94   3   0 100 128   0   0  52  56 151

edw123

Цитата: DarkByte от 28 Сен. 2018 в 13:23
Стало интересно сделать свой БК с блекджеком и wifi несколько более расширенным функционалом, и для начала решил изучить протокол общения между контроллером и дисплеем.
Тут ещё где-то есть тема про контроллеры серии kt и дисплеи вида LCDx. И там была ссылка на открытый забугорный проект.

DarkByte

Цитата: edw123 от 28 Сен. 2018 в 14:39Тут ещё где-то есть тема про контроллеры серии kt и дисплеи вида LCDx. И там была ссылка на открытый забугорный проект.
Находил в интернете описание протокола общения LCD3 и S12SN, к сожалению, там всё несколько иначе.

DarkByte

Пятый байт пакета от БК к контроллеру представляет закодированное значение из третьего (четвёртого или шестого). Именно на него ориентируется контроллер и алгоритм его подсчёта пока понять не удалось. Вот пример пакетов, где отличается только он один:

0  1  2  3  4  5  6  7  8  9 10 11 12 13 14       0   1   2   3   4   5   6   7   8   9  10  11  12  13  14

01 03 20 03 03 5e 03 00 64 80 00 00 35 38 96  =>   1   3  32   3   3  94   3   0 100 128   0   0  53  56 150
01 03 21 03 03 63 03 00 64 80 00 00 35 38 aa  =>   1   3  33   3   3  99   3   0 100 128   0   0  53  56 170
01 03 22 03 03 64 03 00 64 80 00 00 35 38 ae  =>   1   3  34   3   3 100   3   0 100 128   0   0  53  56 174
01 03 23 03 03 09 03 00 64 80 00 00 35 38 c2  =>   1   3  35   3   3   9   3   0 100 128   0   0  53  56 194
01 03 24 03 03 12 03 00 64 80 00 00 35 38 de  =>   1   3  36   3   3  18   3   0 100 128   0   0  53  56 222
01 03 25 03 03 07 03 00 64 80 00 00 35 38 ca  =>   1   3  37   3   3   7   3   0 100 128   0   0  53  56 202
01 03 26 03 03 08 03 00 64 80 00 00 35 38 c6  =>   1   3  38   3   3   8   3   0 100 128   0   0  53  56 198
01 03 27 03 03 0d 03 00 64 80 00 00 35 38 c2  =>   1   3  39   3   3  13   3   0 100 128   0   0  53  56 194
01 03 28 03 03 06 03 00 64 80 00 00 35 38 c6  =>   1   3  40   3   3   6   3   0 100 128   0   0  53  56 198


01 03 20 06 06 61 06 00 64 80 00 00 35 38 ac  =>   1   3  32   6   6  97   6   0 100 128   0   0  53  56 172
01 03 21 06 06 66 06 00 64 80 00 00 35 38 aa  =>   1   3  33   6   6 102   6   0 100 128   0   0  53  56 170
01 03 22 06 06 67 06 00 64 80 00 00 35 38 a8  =>   1   3  34   6   6 103   6   0 100 128   0   0  53  56 168
01 03 23 06 06 0c 06 00 64 80 00 00 35 38 c2  =>   1   3  35   6   6  12   6   0 100 128   0   0  53  56 194
01 03 24 06 06 15 06 00 64 80 00 00 35 38 dc  =>   1   3  36   6   6  21   6   0 100 128   0   0  53  56 220
01 03 25 06 06 0a 06 00 64 80 00 00 35 38 c2  =>   1   3  37   6   6  10   6   0 100 128   0   0  53  56 194
01 03 26 06 06 0b 06 00 64 80 00 00 35 38 c0  =>   1   3  38   6   6  11   6   0 100 128   0   0  53  56 192
01 03 27 06 06 10 06 00 64 80 00 00 35 38 da  =>   1   3  39   6   6  16   6   0 100 128   0   0  53  56 218
01 03 28 06 06 09 06 00 64 80 00 00 35 38 cc  =>   1   3  40   6   6   9   6   0 100 128   0   0  53  56 204


01 03 20 09 09 64 09 00 64 80 00 00 35 38 a6  =>   1   3  32   9   9 100   9   0 100 128   0   0  53  56 166
01 03 21 09 09 69 09 00 64 80 00 00 35 38 aa  =>   1   3  33   9   9 105   9   0 100 128   0   0  53  56 170
01 03 22 09 09 6a 09 00 64 80 00 00 35 38 aa  =>   1   3  34   9   9 106   9   0 100 128   0   0  53  56 170
01 03 23 09 09 0f 09 00 64 80 00 00 35 38 ce  =>   1   3  35   9   9  15   9   0 100 128   0   0  53  56 206
01 03 24 09 09 18 09 00 64 80 00 00 35 38 de  =>   1   3  36   9   9  24   9   0 100 128   0   0  53  56 222
01 03 25 09 09 0d 09 00 64 80 00 00 35 38 ca  =>   1   3  37   9   9  13   9   0 100 128   0   0  53  56 202
01 03 26 09 09 0e 09 00 64 80 00 00 35 38 ca  =>   1   3  38   9   9  14   9   0 100 128   0   0  53  56 202
01 03 27 09 09 13 09 00 64 80 00 00 35 38 d6  =>   1   3  39   9   9  19   9   0 100 128   0   0  53  56 214
01 03 28 09 09 0c 09 00 64 80 00 00 35 38 c6  =>   1   3  40   9   9  12   9   0 100 128   0   0  53  56 198

0  1  2  3  4  5  6  7  8  9 10 11 12 13 14       0   1   2   3   4   5   6   7   8   9  10  11  12  13  14

Может кто догадается, как он считается.

Dimkin808

Общение должно быть на 9600. Описание примерное протокола здесь. https://github.com/hurzhurz/tsdz2/blob/master/serial-communication.md

DarkByte

Цитата: Dimkin808 от 11 Фев. 2019 в 15:19Общение должно быть на 9600. Описание примерное протокола здесь. ссылка
В моём случае оно на 1200. И с описанным по ссылке протоколом не совпадает ни по длине пакетов, ни по содержанию.

13_chip_13

   DarkByte, а это применительно к какому железу (самокату или дисплею) протокол?

DarkByte

Цитата: 13_chip_13 от 24 Март 2020 в 14:27DarkByte, а это применительно к какому железу (самокату или дисплею) протокол?
Noname китайский контроллер с примерно таким дисплеем


aka13

Я пока не закончил тесты, но этот же протокол у "омологированного" всетта с экраном, Iohawk Legacy. Что у самого VSETT за протокол, не знаю, но думаю что то же самое, т.к. экран по меню и ошибкам тот же самый. Когда закончу, выложу на гите.


Проводов при этом 6 -
Vbat, Vcc (экран дает зажигание после разблокировки), SD (аналоговый сигнал газа, работает всегда, 1в при газе на нуле, мотор крутит при наличии пакетов на RX есц), Rx,Tx и GND соответственно.

На самом экране этот протокол называется "4" и невозможно его сменить.