Update app functions and configs for board command system v2.x

- Обновлены коды базовых эффектов в Морской бой VR.lm с 0..12 на 10..22.
- Создан новый файл настроек подсветки Резервная панель RZ.lm.
- Полностью обновлен справочник команд Основные.csv с поддержкой новых команд v2.x.
- Добавлен выпадающий список стандартных ролей/матриц в диалог role_dialog.py.
- В led_test_dialog.py и led_test_section.py добавлены контролы для выбора физического канала, настройки яркости и гамма-коррекции WS2812.
This commit is contained in:
Данил Ярош 2026-06-29 16:13:29 +03:00
parent 9fd10a3acd
commit 85a7b4db55
7 changed files with 707 additions and 158 deletions

View File

@ -15,6 +15,7 @@ import sys
from PySide6.QtCore import Qt, QTimer
from PySide6.QtWidgets import (
QCheckBox,
QFormLayout,
QGroupBox,
QHBoxLayout,
@ -142,31 +143,72 @@ class LedTestDialog(StyledDialog):
effect_form.addRow(btn_row)
root.addWidget(effect_group)
# ── Цветовое чередование ──
color_group = QGroupBox("Цветовое чередование (cmd 89)")
color_root = QVBoxLayout(color_group)
# ── Настройки WS2812 (cmd 89) ──
color_group = QGroupBox("Настройки WS2812 (cmd 89)")
color_form = QFormLayout(color_group)
color_form.setSpacing(6)
# Выбор физического канала
self._cmd89_channel_combo = NoWheelComboBox()
self._cmd89_channel_combo.addItem("Все ленты (0)", 0)
self._cmd89_channel_combo.addItem("1-й канал (1)", 1)
self._cmd89_channel_combo.addItem("2-й канал (2)", 2)
self._cmd89_channel_combo.addItem("3-й канал (3)", 3)
self._cmd89_channel_combo.addItem("4-й канал (4)", 4)
color_form.addRow("Физический канал:", self._cmd89_channel_combo)
# Порядок цветов
self._color_order_combo = NoWheelComboBox()
for code, name in _COLOR_ORDERS:
self._color_order_combo.addItem(f"{code} — {name}", code)
color_root.addWidget(self._color_order_combo)
set_color_btn = QPushButton("1. Применить")
set_color_btn.setProperty("role", "primary")
set_color_btn.setIcon(icon("fa5s.palette", color="#ecfdf5"))
set_color_btn.clicked.connect(self._send_color_order)
color_root.addWidget(set_color_btn)
apply_order_btn = QPushButton("Применить порядок")
apply_order_btn.setProperty("role", "primary")
apply_order_btn.setIcon(icon("fa5s.palette", color="#ecfdf5"))
apply_order_btn.clicked.connect(self._send_color_order)
self._color_test_btn = QPushButton("2. Тест цвета")
order_layout = QHBoxLayout()
order_layout.addWidget(self._color_order_combo, 1)
order_layout.addWidget(apply_order_btn)
color_form.addRow("Порядок цветов:", order_layout)
# Яркость
self._cmd89_brightness_spin = QSpinBox()
self._cmd89_brightness_spin.setRange(0, 255)
self._cmd89_brightness_spin.setValue(255)
apply_bright_btn = QPushButton("Применить яркость")
apply_bright_btn.setIcon(icon("fa5s.sun", color=get_icon_color()))
apply_bright_btn.clicked.connect(self._send_brightness)
bright_layout = QHBoxLayout()
bright_layout.addWidget(self._cmd89_brightness_spin, 1)
bright_layout.addWidget(apply_bright_btn)
color_form.addRow("Яркость:", bright_layout)
# Гамма-коррекция
self._cmd89_gamma_check = QCheckBox("Включить гамма-коррекцию")
apply_gamma_btn = QPushButton("Применить гамму")
apply_gamma_btn.setIcon(icon("fa5s.adjust", color=get_icon_color()))
apply_gamma_btn.clicked.connect(self._send_gamma)
gamma_layout = QHBoxLayout()
gamma_layout.addWidget(self._cmd89_gamma_check, 1)
gamma_layout.addWidget(apply_gamma_btn)
color_form.addRow("Гамма-коррекция:", gamma_layout)
# Тест цвета
self._color_test_btn = QPushButton("Тест цвета")
self._color_test_btn.setProperty("role", "primary")
self._color_test_btn.setIcon(icon("fa5s.eye", color="#ecfdf5"))
self._color_test_btn.clicked.connect(self._run_color_test)
color_root.addWidget(self._color_test_btn)
color_form.addRow(self._color_test_btn)
color_hint = QLabel("Должны вывестись: красный → зелёный → синий")
color_hint.setStyleSheet("color: #9ca3af; font-size: 12px;")
color_hint.setStyleSheet("color: #9ca3af; font-size: 11px;")
color_hint.setWordWrap(True)
color_root.addWidget(color_hint)
color_form.addRow(color_hint)
root.addWidget(color_group)
@ -279,8 +321,21 @@ class LedTestDialog(StyledDialog):
self._send(mode.base_command)
def _send_color_order(self) -> None:
ch = self._cmd89_channel_combo.currentData()
code = self._color_order_combo.currentData()
cmd = f"8900{code}"
cmd = f"89{ch}0{code}"
self._send(cmd)
def _send_brightness(self) -> None:
ch = self._cmd89_channel_combo.currentData()
val = self._cmd89_brightness_spin.value()
cmd = f"89{ch}1{val}"
self._send(cmd)
def _send_gamma(self) -> None:
ch = self._cmd89_channel_combo.currentData()
val = 1 if self._cmd89_gamma_check.isChecked() else 0
cmd = f"89{ch}2{val}"
self._send(cmd)
def _run_color_test(self) -> None:

View File

@ -18,6 +18,7 @@ from PySide6.QtWidgets import (
from ...services.com_service import ComConnection
from ...ui.icons import get_icon_color, get_icon_muted, icon
from ..no_wheel_combo_box import NoWheelComboBox
from .styled_dialog import StyledDialog
@ -47,6 +48,22 @@ class RoleDialog(StyledDialog):
current_layout.addWidget(read_btn)
root.addLayout(current_layout)
# ── Быстрый выбор роли ──
preset_layout = QHBoxLayout()
preset_layout.addWidget(QLabel("Шаблоны ролей:"))
self._role_preset_combo = NoWheelComboBox()
self._role_preset_combo.addItem("— Свой вариант —", "")
self._role_preset_combo.addItem("s_b (Морской бой)", "s_b")
self._role_preset_combo.addItem("s_b_v1 (Морской бой v1)", "s_b_v1")
self._role_preset_combo.addItem("s_b_v2 (Морской бой v2)", "s_b_v2")
self._role_preset_combo.addItem("dan_ro (Данро)", "dan_ro")
self._role_preset_combo.addItem("dan_ro_v1 (Данро v1)", "dan_ro_v1")
self._role_preset_combo.addItem("rz (Резервная панель RZ)", "rz")
self._role_preset_combo.addItem("rz_v1 (Резервная панель RZ v1)", "rz_v1")
self._role_preset_combo.currentIndexChanged.connect(self._on_preset_changed)
preset_layout.addWidget(self._role_preset_combo, 1)
root.addLayout(preset_layout)
# ── Установка новой роли ──
set_layout = QHBoxLayout()
set_layout.addWidget(QLabel("Новая роль:"))
@ -71,6 +88,11 @@ class RoleDialog(StyledDialog):
btn_layout.addWidget(close_btn)
root.addLayout(btn_layout)
def _on_preset_changed(self, index: int) -> None:
val = self._role_preset_combo.itemData(index)
if val:
self._role_input.setText(val)
def _read_role(self) -> None:
if not self._conn.is_connected:
return

View File

@ -8,16 +8,20 @@ from __future__ import annotations
from PySide6.QtCore import QTimer
from PySide6.QtWidgets import (
QCheckBox,
QFormLayout,
QGroupBox,
QHBoxLayout,
QLabel,
QMessageBox,
QPushButton,
QSpinBox,
QVBoxLayout,
QWidget,
)
from ...services.com_service import ComConnection
from ...ui.icons import icon
from ...ui.icons import get_icon_color, icon
from ..no_wheel_combo_box import NoWheelComboBox
_COLOR_ORDERS: list[tuple[int, str]] = [
@ -45,39 +49,81 @@ class LedTestSection(QWidget):
root.setContentsMargins(0, 0, 0, 0)
root.setSpacing(10)
# ── Тест цвета ──
color_group = QGroupBox("Тест цвета (cmd 89)")
color_root = QVBoxLayout(color_group)
# ── Настройки WS2812 (cmd 89) ──
color_group = QGroupBox("Настройки WS2812 (cmd 89)")
color_form = QFormLayout(color_group)
color_form.setSpacing(6)
desc = QLabel(
"Выберите порядок цветов и нажмите «1. Применить». "
"Затем нажмите «2. Тест цвета»: подсветка должна показать красный, зелёный и синий цвет."
"Настройки вывода WS2812. Выберите физический канал и настройте порядок цветов, "
"яркость или гамма-коррекцию."
)
desc.setWordWrap(True)
desc.setObjectName("HelpText")
color_root.addWidget(desc)
color_form.addRow(desc)
# Выбор физического канала
self._cmd89_channel_combo = NoWheelComboBox()
self._cmd89_channel_combo.addItem("Все ленты (0)", 0)
self._cmd89_channel_combo.addItem("1-й канал (1)", 1)
self._cmd89_channel_combo.addItem("2-й канал (2)", 2)
self._cmd89_channel_combo.addItem("3-й канал (3)", 3)
self._cmd89_channel_combo.addItem("4-й канал (4)", 4)
color_form.addRow("Физический канал:", self._cmd89_channel_combo)
# Порядок цветов
self._color_order_combo = NoWheelComboBox()
for code, name in _COLOR_ORDERS:
self._color_order_combo.addItem(f"{code} — {name}", code)
color_root.addWidget(self._color_order_combo)
self._set_color_btn = QPushButton("1. Применить")
self._set_color_btn = QPushButton("Применить порядок")
self._set_color_btn.setProperty("role", "primary")
self._set_color_btn.setIcon(icon("fa5s.palette", color="#ecfdf5"))
self._set_color_btn.clicked.connect(self._send_color_order)
color_root.addWidget(self._set_color_btn)
self._color_test_btn = QPushButton("2. Тест цвета")
order_layout = QHBoxLayout()
order_layout.addWidget(self._color_order_combo, 1)
order_layout.addWidget(self._set_color_btn)
color_form.addRow("Порядок цветов:", order_layout)
# Яркость
self._cmd89_brightness_spin = QSpinBox()
self._cmd89_brightness_spin.setRange(0, 255)
self._cmd89_brightness_spin.setValue(255)
apply_bright_btn = QPushButton("Применить яркость")
apply_bright_btn.setIcon(icon("fa5s.sun", color=get_icon_color()))
apply_bright_btn.clicked.connect(self._send_brightness)
bright_layout = QHBoxLayout()
bright_layout.addWidget(self._cmd89_brightness_spin, 1)
bright_layout.addWidget(apply_bright_btn)
color_form.addRow("Яркость:", bright_layout)
# Гамма-коррекция
self._cmd89_gamma_check = QCheckBox("Включить гамма-коррекцию")
apply_gamma_btn = QPushButton("Применить гамму")
apply_gamma_btn.setIcon(icon("fa5s.adjust", color=get_icon_color()))
apply_gamma_btn.clicked.connect(self._send_gamma)
gamma_layout = QHBoxLayout()
gamma_layout.addWidget(self._cmd89_gamma_check, 1)
gamma_layout.addWidget(apply_gamma_btn)
color_form.addRow("Гамма-коррекция:", gamma_layout)
# Тест цвета
self._color_test_btn = QPushButton("Тест цвета")
self._color_test_btn.setProperty("role", "primary")
self._color_test_btn.setIcon(icon("fa5s.eye", color="#ecfdf5"))
self._color_test_btn.clicked.connect(self._run_color_test)
color_root.addWidget(self._color_test_btn)
color_form.addRow(self._color_test_btn)
color_hint = QLabel("Должны вывестись: красный → зелёный → синий")
color_hint.setStyleSheet("color: #9ca3af; font-size: 12px;")
color_hint.setStyleSheet("color: #9ca3af; font-size: 11px;")
color_hint.setWordWrap(True)
color_root.addWidget(color_hint)
color_form.addRow(color_hint)
root.addWidget(color_group)
# ── Лог ──
@ -94,8 +140,22 @@ class LedTestSection(QWidget):
# ── Отправка ──────────────────────────────────────────────────────
def _send_color_order(self) -> None:
ch = self._cmd89_channel_combo.currentData()
code = self._color_order_combo.currentData()
self._send(f"8900{code}")
cmd = f"89{ch}0{code}"
self._send(cmd)
def _send_brightness(self) -> None:
ch = self._cmd89_channel_combo.currentData()
val = self._cmd89_brightness_spin.value()
cmd = f"89{ch}1{val}"
self._send(cmd)
def _send_gamma(self) -> None:
ch = self._cmd89_channel_combo.currentData()
val = 1 if self._cmd89_gamma_check.isChecked() else 0
cmd = f"89{ch}2{val}"
self._send(cmd)
def _run_color_test(self) -> None:
self._color_test_cmds = ["8003", "8004", "8005", "8002", "8000"]

View File

@ -1,8 +1,8 @@
command;name;description
00;Перезагрузка;Перезагрузить контроллер (RESET). Помещается в очередь без ожидания.
01;Отладка;Включает/выключает подробные логи. В релизе будет отключена.
01;Отладка;Включает/выключает подробные логи (SILENT / DEVELOPER). В релизе будет отключена.
02;Приём файла;Подготовиться к приёму файла обновления. Параметр — размер в байтах. Пример: 02356987. Выполняется ~15 сек, затем весь приём данных записывается в update.bin.
03;SPIFFS;Показать содержимое SPIFFS (встроенной файловой системы).
03;SPIFFS;Показать содержимое встроенной файловой системы SPIFFS.
04;OTA обновление;Запустить OTA-обновление с ранее записанным файлом /update.bin.
05;Версия прошивки;Показать версию прошивки контроллера.
06;MAC-адрес;Показать MAC-адрес (без двоеточий). Уникальный, можно считать серийным номером.
@ -10,21 +10,26 @@ command;name;description
08;Авторизация (ответ);Приём ответа от компьютера на встречный вызов CHAL. 32 HEX-символа зашифрованных AES256.
09;Сброс EEPROM;Сброс EEPROM. Параметр — MAC-адрес без двоеточий, иначе не сбросится.
10;Подтверждение COIN;Подтвердить принятие сигнала COIN. Без подтверждения сигнал повторяется каждые 200 мс.
20X;Выходы (маска);Установить состояние 8 выходов двоичной маской. Пример: 203 → включить выходы 1 и 2.
21XY;Выход (один);Установить выход X в состояние Y [0/1/2(инверсия)]. Пример: 2131 → включить выход 3.
20X;Выходы (маска);Установить состояние 8 выходов двоичной маской. Пример: 203 → вывести 1 и 2 выходы по единичке, остальные - нолики.
21XY;Выход (один);Установить выход X (0-7) в состояние Y [0/1/2(инверсия)]. Пример: 2131 → включить выход 3.
25CCB;Витрина призов;25 — запрос состояния; 2501B — выдать приз из ячейки B; 2511B — открыть ячейку B без списания; 25991/25990 — вкл/выкл авторежим витрины.
30X;Хоппер 1;301 — включить мотор, 300 — выключить, 309 — выдать приз (авторежим с контролем датчика).
40X;Хоппер 2;Аналогично хопперу 1.
8XYY;Программа LED;Выбор программы YY адресных диодов по каналу X (1..4). 80YY — на все каналы. 0 — выкл, 3 — красный, 4 — зелёный, 5 — синий.
85XXYY;Спецэффект LED;Специфичная программа эффектов. XX — код эффекта, YY — время в секундах. Пример: 854505 — ЗАРЯДКА на 5 сек.
50CCP;Дополнительные GPIO;GPIO25/GPIO26: 50 — запрос состояния; 5001P — настроить режим; 5005P — запрос уровня; 5010P — установить выходы.
8XYY;Программа LED;Выбор программы YY по каналу X (1..4). 80YY — на все каналы. 08RRRGGGBBB — цвет. 8012.. / 8013.. — direct-группы монетника/выдачи.
81XX[NN];Бродяга морей;Управление direct-объектами Бродяги морей. 8130 — очистить; 8131NN / 8132NN — уровень; 81311..81313 / 81321..81323 — эффекты.
85XX[SSS];Эффекты VM-матрицы;Эффекты s_b: 00/01 — авто вкл/выкл; 25 — тесты; 30..34 — direct-шкалы; 10..22 — базовые; 40..49 — спец; 80..82 — цвета. SSS — время.
85;Стоп рендеринг;Без параметра — отключить процесс рендеринга эффектов (освободить RAM).
89[X];Цветовой порядок;Переключить чередование цветов: 0/пусто — RGB, 1 — RBG, 2 — BRG, 3 — BGR, 4 — GRB, 5 — GBR.
8550XX[SSS];Данро (принудительно);Данро (принудительная матрица dan_ro): 855000 — очистить; 855001 — авто вкл; 855010..855016 — эффекты. SSS — время.
8560XX[SSS];RZ (принудительно);Резервная панель RZ (принудительная матрица rz): 856000 — очистить; 856001 — авто вкл; 856010..856016 — эффекты. SSS — время.
89CKP;Настройки WS2812;C — канал (0..3); K — настройка: 0 порядок (0..5 для RGB..GBR), 1 яркость (0..255), 2 гамма (0/1); P — значение.
90;Очистка очереди;Очистить очередь команд.
91;Входы;Запрос состояния 26 цифровых входов. Ответ: INPUT<число>. Пример: INPUT67108863 — все не нажаты.
91;Входы;Запрос состояния 24 цифровых (+2 хоппера) входов в двоичном коде (преобразованном в десятичный). Пример: INPUT67108863.
91X;Антидребезг;Задать время антидребезга (10..100 мс). По умолчанию 50 мс. Пример: 9110.
92;ADC (однократно);Запрос значений 4 аналоговых входов. Отключает автовывод. Ответ: ADC0,0,0,0.
92X;ADC (авто);Периодический автовывод ADC каждые X мс (50..5000). Пример: 92100.
93;Счётчик монет;Запрос global_summa — нестираемый счётчик принятых монет.
96;Сохранить роль;Сохранить пользовательское значение в памяти платы (до 20 символов). Пример: 96right.
97;Показать роль;Вывод сохранённого пользовательского значения. Формат: ROLE : <значение>.
96;Активная матрица;Без параметра — запрос текущей активной VM-матрицы. С параметром — выбор и сохранение матрицы в NVS (s_b, dan_ro, rz, ...).
97;Показать активную матрицу;Вывод сохранённого в NVS имени активной матрицы. Формат: ROLE : <имя>.
98;Состояние системы;Запрос загруженности ядер, оперативки и свободного места в памяти.
99;Статус;Запрос текущего статуса платы.

Can't render this file because it has a wrong number of fields in line 15.

View File

@ -8,19 +8,19 @@ has_duration = true
# ── Базовые эффекты ──
[[effects]]
code = 0
code = 10
name = "Горизонтальная волна"
[[effects]]
code = 1
code = 11
name = "Вертикальная волна"
[[effects]]
code = 2
code = 12
name = "Диагональная волна"
[[effects]]
code = 3
code = 13
name = "Плазма"
[[effects]]
@ -28,35 +28,35 @@ code = 14
name = "Ночь"
[[effects]]
code = 5
code = 15
name = "Радуга"
[[effects]]
code = 6
code = 16
name = "Огонь-Лёд"
[[effects]]
code = 7
code = 17
name = "Вода"
[[effects]]
code = 8
code = 18
name = "Звёзды"
[[effects]]
code = 9
code = 19
name = "Сканер"
[[effects]]
code = 10
code = 20
name = "Поток"
[[effects]]
code = 11
code = 21
name = "Буря"
[[effects]]
code = 12
code = 22
name = "Лёд"
# ── Специальные эффекты ──

View File

@ -0,0 +1,58 @@
# Резервная панель RZ — специальные эффекты подсветки
# Формат команды: 87XXYY (XX — код эффекта, YY — время в секундах)
# Без параметра (87) — отключить рендеринг эффектов
base_command = "87"
has_duration = true
[[effects]]
code = 40
name = "Горизонтальная волна"
[[effects]]
code = 41
name = "Вертикальная волна"
[[effects]]
code = 42
name = "Диагональная волна"
[[effects]]
code = 43
name = "Радуга"
[[effects]]
code = 44
name = "Волна вверх"
[[effects]]
code = 45
name = "Вертикальная волна вверх"
[[effects]]
code = 46
name = "Конечная волна"
[[effects]]
code = 47
name = "Синяя волна"
[[effects]]
code = 48
name = "Диагональная волна 2"
[[effects]]
code = 49
name = "Падающие ряды"
[[effects]]
code = 50
name = "Оранжевая волна"
[[effects]]
code = 51
name = "Морская волна"
[[effects]]
code = 52
name = "Диагональная волна 3"

View File

@ -5,6 +5,7 @@ by: Паша Николаевич
>[!info] Информация
>Это раздел с информацией о плате периферийного контроллера.
>Информацию о плате для витрины призов смотреть в [[Витрина призов]]
>Текущая описанная прошивка: `ver_2.3.6_no_auth_prizes`.
>[!info] Общие сведения
> - Плата подключается к компьютеру по переходу USB - COM порт.
@ -17,35 +18,57 @@ by: Паша Николаевич
2. [[#Авторизация]]
1. [[#Алгоритм авторизации]]
2. [[#Команды]]
1. [[#Примечания]]
1. [[#Список команд]]
2. [[#Примечания]]
1. [[#Служебные команды]]
2. [[#Программы адресных диодов]]
1. [[#Специфичные программы]]
2. [[#Список команд]]
3. [[#Обновление]]
1. [[#Настройки адресной подсветки]]
2. [[#Карты матриц]]
3. [[#Специфичные программы]]
1. [[#Отдельный раздел для призовой стойки]]
2. [[#Отдельный раздел для Бродяги морей]]
3. [[#Отдельный раздел для морского боя VR]]
1. [[#Управляющие коды 85]]
2. [[#Поведение после окончания эффекта]]
3. [[#Direct-шкалы 8530..8534]]
4. [[#Тесты морского боя VR 8525TVVV]]
5. [[#Базовые эффекты 8510..8522]]
6. [[#Спецэффекты 8540..8549]]
7. [[#Тестовые заливки 8580..8582]]
8. [[#Диагностика 85]]
4. [[#Отдельный раздел для Данро]]
1. [[#Тесты панели Данро 8625TVVV]]
2. [[#Список эффектов]]
5. [[#Отдельный раздел для RZ]]
1. [[#Тесты панели RZ 8725TVVV]]
6. [[#Дополнительные цифровые GPIO]]
3. [[#Обновление прошивки платы]]
1. [[#Православный новый]]
2. [[#Пендосский старый]]
# Система команд
- Общение - строка, заканчивающаяся кодами (0xD)+(0xA), достаточно любого из них  для окончания строки
- Минимально – ДВА (2, two) символа. 00+\<Enter\> – команда, а 0+\<Enter\> – уже нет
- Таймаут - 100 милисекунд, если строка за это время не окончилась - идет игнорирование команды
- Максимальная длина входной строки - 199 символов
- Таймаут - 100 миллисекунд, если строка за это время не окончилась - идет игнорирование команды
Команды получаемые от компьютера помещаются в очередь и выполняются последовательно, кроме команд "сброс" (00) и "очистка очереди".
Размер очереди команд - 100 строк. Команды `00` и `90` обрабатываются сразу.
Шифрование обмена: двойное рукопожатие при помощи AES256 c фиксированным ключом.
#### Кнопка SERVICE на плате:
- Если ее зажать и удержать при включении – выполнится сброс EEPROM
## Кнопка SERVICE на плате:
- Если ее зажать и удержать при включении – выполнится сброс настроек контроллера
- При работе – посылает команду «SERVICE – предлагая компьютеру перейти в режим настройки игровой программы
>[!warning] Внимание!
>Имеются два режима работы: SILENT (тихий режим) и DEVELOPER (режим разработки, с полными логами).
>
>Переключение режимов:
>Если соединить ногу GPIO_15 с землей через резистор <10кОм включается ТИХИЙ режим, и контроллер не выдает логи, а только необходимые ответы и команды.
>Также режим можно переключать командой «01» (временно, в релизе будет удалено)
>Команда `01` временно переключает режим логирования. В релизной версии команда может быть удалена.
### Авторизация
## Авторизация
После загрузки контроллер не принимает никаких команд, кроме запросов на авторизацию.
@ -70,14 +93,57 @@ by: Паша Николаевич
4. **Контроллер ответит на первый запрос компа**:
**RAES\<symbols\> (16 байт или 32 HEX-символа)**
***Пример:*** **RAES***99ED731648AB8C1709CC4C3C8C3BB0E1*
5. При успехе контроллер отправляет `AUTH_PC_OK` и статус. При ошибке - `AUTH_PC_FAIL`.
# Команды
## Список команд
| Команда | Назначение, примеры, ответы |
| ---------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [[#Служебные команды\|00]] | Перезагрузить контроллер (RESET) |
| [[#Служебные команды\|01]] | Отладочная. включает-выключает подробные логи. В релизе будет отключена |
| [[#Служебные команды\|02]] | Подготовиться к приему файла. освободить место, отформатировать встроенную файловую, проверить хватит ли места. <br>_**Например**_, `02356987` - заявка на файл обновления размером 356987 байт.<br>Выполняется около 15 секунд, после чего весь прием  данных в порту заносится в файл "update.bin".<br>Ответ при приеме файла - каждый блок (4096) - размер принятого.<br>По окончании - переход снова в режим команд (подробнее – [Обновление](#Обновление)). |
| [[#Служебные команды\|03]] | Показать содержимое SPIFFS |
| [[#Служебные команды\|04]] | Запустить ОТА обновление с ранее записанным файлом SPIFFS: `/update.bin` |
| [[#Служебные команды\|05]] | Показать версию прошивки (указана в дефолтах) |
| [[#Служебные команды\|06]] | Показать MAC-адрес (без двоеточий, как в оригинале), уникальный, можно считать серийным номером |
| [[#Авторизация\|07]] | Безопасность (запрос авторизации от компа. На этот запрос создается рандомный запрос навстречу. См. [[#Алгоритм авторизации]]) |
| [[#Авторизация\|08]] | Безопасность (прием ответа от компьютера на запрос `07`. См. [[#Алгоритм авторизации]]) |
| [[#Служебные команды\|09]] | Сброс EEPROM (параметром - MAC без двоеточий, иначе не сбросится) |
| 10 | Подтверждение принятия сигнала COIN, иначе этот сигнал будет посылаться снова с периодичностью `200 мс` (сколько приняли койнов, столько и подтверждений быть должно) |
| 20X | Установить состояние выходов - всего выходов 8, давать их двоичное состояние.<br>_**Например**_, `203` - вывести 1 и 2 выходы по единичке, остальные - нолики. Соответственно, выход на разъеме будет "прижат" к земле. |
| 21XY | Установить состояние выхода номер Х в -> Y \[0,1,2(инверсия)\].<br>_**Примеры:**_<br>`2131` - Включить 3 по индексу выход<br>`2170` - Выключить 7 по индексу выход |
| [[#Отдельный раздел для призовой стойки\|25CCB]] | Витрина призов (см. [[#Отдельный раздел для призовой стойки]]): <br>`25` - запрос состояния; <br>`2501B` - выдать приз из ячейки `B`; <br>`2511B` - открыть ячейку `B`; <br>`25991`/`25990` - включить/выключить авторежим витрины. |
| 30X | Хоппер 1.<br>`301` - Включить мотор хоппера<br>`300` - Выключить мотор хоппера<br>`309` - Выдать приз (в авторежиме[^1]) |
| 40X | Хоппер 2.<br>Аналогично |
| [[#Дополнительные цифровые GPIO\|50CCP]] | Дополнительные цифровые GPIO25/GPIO26 (см. [[#Дополнительные цифровые GPIO]]): <br>`50` - запрос состояния; <br>`5001P` - конфигурация входа; <br>`5005P` - запрос уровня входа; <br>`5010P` - установка выходов. |
| [[#Программы адресных диодов\|8XYY[PARAMS]]] | Выбор программы адресных диодов `YY` по каналу `X`. <br>Для программы `08` дополнительно передается цвет `RRRGGGBBB`, для `8012..`/`8013..` - direct-группы из проекта 1 на 4-й ленте, где принимаются только `00` и `01..03` (см. [[#Программы адресных диодов]]). |
| [[#Отдельный раздел для морского боя VR\|85XX[SSS]]] | Эффекты активной VM-матрицы (выбирается командой `96`). <br>**Для матрицы `s_b`:** <br>управляющие `00`/`01`;<br>тесты `25`;<br>direct-шкалы `30..34`;<br>базовые `10..22`;<br>спец. `40..49`;<br>заливки `80..82`.<br><br>**Для `dan_ro`/`rz`:**<br>эффекты `51..56`;<br>группа `8550XX` принудительно задаёт `dan_ro`.<br>`SSS` — длительность в секундах (см. [[#Отдельный раздел для морского боя VR]]). |
| [[#Программы адресных диодов\|85]] | Без параметра отключает процесс рендеринга эффектов (чтобы освободить оперативную память) |
| [[#Отдельный раздел для Данро\|8550XX[SSS]]] | Данро (принудительная матрица `dan_ro`): <br>`855000` — очистить экран; <br>`855001` — автокарусель вкл;<br>эффекты `855010..855016`;<br>`SSS` — длительность в секундах (см. [[#Отдельный раздел для Данро]]). |
| [[#Отдельный раздел для RZ\|8560XX[SSS]]] | Резервная панель RZ (принудительная матрица `rz`): <br>`856000` — очистить экран; <br>`856001` — автокарусель вкл; <br>эффекты `856010..856016`; <br>`SSS` — длительность в секундах (см. [[#Отдельный раздел для резервной панели RZ]]). |
| [[#Отдельный раздел для RZ\|96rz + 85XX[SSS]]] | Резервная панель RZ: <br>сначала `96rz` — выбрать матрицу, затем `85` — стоп; <br>`8500`/`8501` — авто выкл/вкл; <br>эффекты `8551..8556`; тесты `8525TVVV` (см. [[#Отдельный раздел для резервной панели RZ]]). |
| [[#Настройки адресной подсветки\|89CKP]] | Настройки WS2812: <br>`C=0` - все 4 ленты, <br>`C=1/2/3` - 2-й/3-й/4-й физический канал; <br>`K=0` - порядок цветов (`0` RGB, `1` RBG, `2` BRG, `3` BGR, `4` GRB, `5` GBR), <br>`K=1` - яркость `0..255`, <br>`K=2` - гамма `0/1`.<br>***Примеры:*** <br>`8901255` - яркость всех каналов 255; <br>`89021` - включить гамму; <br>`89304` - порядок GRB для 4-го физического канала. |
| 90 | Очистить очередь команд |
| 91 | Запрос состояния цифровых входов, их всего 24(+2 входа хоппера), ответ в двоичном коде.<br>Для уменьшения объема передаваемой информации, преобразуется в десятичное число<br>_**Примеры:**_<br>`INPUT67108863` (`11111111111111111111111111`) - все кнопки не нажаты<br>`INPUT67108861` (`11111111111111111111111101`) - нажата вторая кнопка |
| 91X | _Дополнительно_: задать время антидребезга платы (`10..100` для штатного использования; по умолчанию 50 мс).<br>_**Например**_, `9110` - установить антидребезг на 10 мс |
| 92 | Запрос значения аналоговых входов **(отключает автовывод)** - ответ в формате `ADC0,0,0,0`.<br>Всего 4 аналоговых входа |
| 92X | Периодический автовывод значений аналоговых входов.<br>_**Например**_, `92100` - каждые 100 милисекунд выдавать значения ADC (`50..5000`) |
| 93 | Запрос `global_summa` (число коинов, нестираемо) |
| [[#Карты матриц\|96]] | Без параметра — запрос текущей активной VM-матрицы (ответ: `MATRIX:<name> ROWS:<n> COLS:<n>`).<br>С параметром — выбор и сохранение матрицы в NVS.<br> Список доступных карт см. [[#Карты матриц]].<br>***Примеры:***<br> `96s_b` — морской бой;<br> `96dan_ro` — Данро;<br> `96rz` — резервная панель. |
| 97 | Показать сохранённое в NVS имя активной матрицы.<br>***Формат вывода:*** `ROLE : <имя>` (до 20 символов). |
| 98 | Запрос загруженности ядер, оперативки, свободного места в памяти |
| 99 | Запрос статуса |
[^1]: Авторежим: если датчик в закрытом состоянии - на полсекунды включить мотор, ждать сработки датчика либо таймаута. Если таймаут - выдать сообщение "HOPPER1 ERROR" и наглухо повесить процесс хоппера до перезагрузки. Иначе - сообщение "HOPPER1 OK"
## Примечания
### Служебные команды
`02…09` – команды относятся к служебным (обновление прошивки и двойное рукопожопие)
`02…09` – команды относятся к служебным (обновление прошивки и двойное рукопожатие)
>[!warning] Внимание!
>Перешивается только основная программа, не трогается таблица разделов и буты.
@ -87,88 +153,354 @@ by: Паша Николаевич
### Программы адресных диодов
`8XYY` - выбор программы адресных диодов
Всего 4 канала
- `81YY…84YY`  - переключить программу на канале
***Например:*** `8204` – на второй канал вывести четвертую, "зеленую" программу
- `80YY` – переключает программу на всех каналах сразу.
`8XYY[PARAMS]` - выбор программы адресных диодов, где X - номер канала в формате одной цифры, а YY - номер параметра базового эффекта.
Программа зависит от автомата и не может быть унифицирована. Именно для этого требуется обновление прошивки контроллера.
Кроме, пожалуй, этих (считать тестовыми. Остальное – добавлять по вкусу):
- 0 – ничего не выводить в канал
- 1 – повторный периодический вывод буфера
- 2 – погасить (выводить нолики на всю длину)
- 3 – красный
- 4 – зеленый
- 5 - синий
- 6 - серый (100, 100, 100)
- 7 - белый
- 9 - выводить ЛГБТ переливы
***Список базовых эффектов:***
- `00` – ничего не выводить в канал
- `01` – повторный периодический вывод буфера
- `02` – погасить (выводить нолики на всю длину)
- `03` – красный
- `04` – зеленый
- `05` - синий
- `06` - серый (100, 100, 100)
- `07` - белый
- `08RRRGGGBBB` - пользовательский цвет, каждая компонента 3 десятичные цифры (`000..255`)
- `09` - выводить ЛГБТ переливы
- `10` - морская волна для шапки морского боя
- `11` - автоперебор медленных эффектов шапки морского боя
*10 и далее – пользовательские функции*
Для бродяг морей 4 канал - монетник и выдача приза:
`8012хх`
`8013хх`
- `1200` - очистить обе direct-группы на 4-й ленте; `1201..1203` - direct-группа 1, эффекты 1..3
- `1300` - очистить обе direct-группы на 4-й ленте; `1301..1303` - direct-группа 2, эффекты 1..3
#### Настройки адресной подсветки
`89CKP` меняет настройки вывода WS2812. Это не выбор эффекта, а настройка того, как уже рассчитанный цвет будет записан в буфер конкретной ленты:
- `C` - канал: `0` для всех каналов подсветки, `0..3` для конкретного канала;
- `K` - настройка: `0` порядок цветов, `1` яркость, `2` гамма-коррекция;
- `P` - значение настройки. Может состоять из нескольких цифр, например `255` для яркости. Если отправить только `89CK` без `P`, параметр будет принят как `0`, поэтому лучше передавать `P` явно.
| `K` | `P` | Что меняет | Сохранение |
| :-: | :------- | :------------------------------------------- | :--------------------- |
| `0` | `0..5` | Порядок цветов в буфере WS2812 | Сохраняется в NVS |
| `1` | `0..255` | Яркость ленты | Только до перезагрузки |
| `2` | `0/1` | Гамма-коррекция: `1` включить, `0` выключить | Только до перезагрузки |
Порядки цвета для `K=0`:
| `P` | Порядок |
|---|---|
| `0` | RGB |
| `1` | RBG |
| `2` | BRG |
| `3` | BGR |
| `4` | GRB |
| `5` | GBR |
Для проверки удобно включать тестовые цвета:
- `8003` - все ленты красным;
- `8004` - все ленты зеленым;
- `8005` - все ленты синим.
Если какая-то лента показывает цвета неверно, поменяйте ее порядок через `89C0P`.
###### Примеры порядка цветов
| Команда | Что делает |
| :--- | :--- |
| `89004` | Установить `GRB` для всех лент |
| `89104` | Установить `GRB` для 2-го физического канала |
| `89204` | Установить `GRB` для 3-го физического канала |
| `89304` | Установить `GRB` для 4-го физического канала |
| `89000` | Установить `RGB` для всех лент |
| `89300` | Установить `RGB` для 4-го физического канала |
###### Примеры яркости и гаммы
| Команда | Что делает |
| :-------- | :--------------------------------------------------- |
| `8901255` | Яркость `255` для всех лент |
| `8901128` | Яркость `128` для всех лент |
| `8931128` | Яркость `128` для 4-го физического канала |
| `89021` | Включить гамма-коррекцию для всех лент |
| `89020` | Выключить гамма-коррекцию для всех лент |
| `89321` | Включить гамма-коррекцию для 4-го физического канала |
| | |
#### Карты матриц
Выбор карты командой `96<имя>`, сохраняется в NVS, восстанавливается при загрузке.
**Морской бой (s_b):**
- `s_b` — основная карта, 58×42, 4 канала
- `s_b_v1` — версия 1, 65×69, 3 канала, 4 канал шкалы (3 шкалы)
- `s_b_v2` — версия 2, 65×69, 3 канала, 4 канал шкалы (4 шкалы)
**Данро (dan_ro):**
- `dan_ro` — основная карта, 61×19, 2 стрипа (strip 0 зеркалируется в strip 1)
- `dan_ro_v1` — версия 1, 61×19, 1 стрип (без зеркала)
**Резервная панель RZ (rz):**
- `rz` — основная карта, 61×19, 2 стрипа (strip 0 зеркалируется в strip 1)
- `rz_v1` — версия 1, 61×19, 1 стрип (без зеркала)
#### Специфичные программы
##### Отдельный раздел для призовой стойки
- `20` - режим простоя призовой стойки
- `21BCF` - подсветить полку призовой стойки: `B` ячейка `1..5`, `C` цвет, `F` мигание `0/1`
- `22` - красная мигающая тревога
- `23` - ЛГБТ переливы на всю ленту
- `90` - выводить внешний буфер, который заполняет рендер виртуальной панели
`25CCB`:
- `CC` – подкоманда;
- `B` – номер ячейки `1..5`, если подкоманда работает с ячейкой.
| Формат | Назначение |
| :----: | :--------- |
| `25` | Показать состояние всех ячеек |
| `2501B` | Выдать приз из ячейки `B` |
| `2511B` | Открыть ячейку `B` без списания приза |
| `25991` | Включить автозапуск режима призовой стойки и перезагрузиться через 3 сек |
| `25990` | Выключить автозапуск режима призовой стойки и перезагрузиться через 3 сек |
Ответы:
- `BOX<n>_OPEN` – ячейка открыта;
- `BOX<n>_ERROR` – ячейка не открылась или нет приза;
- `BOX<n>_OK` – ячейка закрыта и содержит приз;
- `BOX<n>_OK+CARD` – в ячейке есть приз и привязанная RFID-карта;
- `BOX<n>_EMPTY` – ячейка пуста.
##### Отдельный раздел для Бродяги морей
`81XX[NN]` управляет двумя отдельными direct-объектами Бродяги морей. Эта группа похожа на direct-шкалы `8530..8534`, но не является частью команды `85` и используется отдельно от панелей `85`, `86` и `87`.
- `XX` - подкоманда объекта;
- `NN` - уровень заполнения объекта;
- короткие команды `81311..81313` - эффекты для объекта 1;
- короткие команды `81321..81323` - эффекты для объекта 2;
- если нужен ручной уровень `1..3`, передавайте уровень с ведущим нулем: `813101..813103` или `813201..813203`;
- эффекты `81311..81313` и `81321..81323` ускорены примерно в 3 раза, цветовые переходы сглажены.
| Команда | Назначение | Максимальный уровень |
|---|---|---|
| `8130` | Очистить оба объекта | - |
| `8131NN` | Объект 1. Заполнить шкалу градиентом красный -> фиолетовый -> синий | `21` |
| `81311` | Эффект 1 объекта 1: плавный перелив синий -> фиолетовый -> фиолетово-красный | - |
| `81312` | Эффект 2 объекта 1: плавный перелив фиолетовый -> синий -> сине-голубой | - |
| `81313` | Эффект 3 объекта 1: мягкое мигание белым | - |
| `8132NN` | Объект 2. Заполнить шкалу градиентом красный -> зеленый | `44` |
| `81321` | Эффект 1 объекта 2: плавный перелив синий -> фиолетовый -> фиолетово-красный | - |
| `81322` | Эффект 2 объекта 2: плавный перелив фиолетовый -> синий -> сине-голубой | - |
| `81323` | Эффект 3 объекта 2: мягкое мигание белым | - |
Если `NN` больше длины объекта, значение ограничивается полной длиной объекта. Если `NN=0`, объект гаснет. Команды `8130`, `8131NN` и `8132NN` останавливают эффект соответствующего объекта.
***Примеры:***
- `8130` - очистить оба объекта
- `813105` - установить уровень `5` для первого объекта
- `81311` - запустить эффект 1 первого объекта
- `81312` - запустить эффект 2 первого объекта
- `81313` - запустить эффект 3 первого объекта
- `81321` - запустить эффект 1 второго объекта
- `81322` - запустить эффект 2 второго объекта
- `81323` - запустить эффект 3 второго объекта
- `813101` - вручную установить уровень `1` для первого объекта, не запускать эффект
- `813201` - вручную установить уровень `1` для второго объекта, не запускать эффект
- `813121` - полностью зажечь первый объект
- `813244` - полностью зажечь второй объект
##### Отдельный раздел для морского боя VR
`85XXYY`:
- XX – команда;
- YY – время в секундах.
`85XX[SSS]` управляет виртуальной панелью морского боя (`s_b`). Это отдельная группа анимаций, которая работает независимо от обычных программ подсветки.
***Пример:*** `854505` – включить спецэффект ЗАРЯДКА на 5 секунд
- `XX` – код управления или эффекта, две цифры после `85`;
- `SSS` – необязательная длительность в секундах, все оставшиеся цифры после `XX`;
- для direct-шкал `XX=30..34` хвост команды трактуется как уровень `0..22`, а не как время;
- для тестов `XX=25` хвост команды разбирается как `TVVV`.
`85` – без параметра отключает процесс рендеринга эффектов (чтобы освободить оперативную память).
***Примеры разбора:***
###### Список эффектов
| Команда | Как разбирается |
|---|---|
| `85` | Остановить анимации `s_b` |
| `8500` | Автокарусель выключена, очистить экран, перейти в ожидание |
| `8501` | Автокарусель включена |
| `8510` | Горизонтальная волна с длительностью по умолчанию |
| `851005` | Горизонтальная волна на 5 секунд |
| `853105` | Первая direct-шкала на уровень `5` |
| `854506` | `CHARGE` на 6 секунд |
| `858006` | Красная тестовая заливка на 6 секунд |
| Команда (`XX`) | Название эффекта |
| :-------------: | :------------------: |
| **Базовые** | **эффекты** |
| 00 | Горизонтальная волна |
| 01 | Вертикальная волна |
| 02 | Диагональная волна |
| 03 | Плазма |
| 04 | Ночь |
| 05 | Радуга |
| 06 | Огонь-Лёд |
| 07 | Вода |
| 08 | Звёзды |
| 09 | Сканер |
| 10 | Поток |
| 11 | Буря |
| 12 | Лёд |
| **Специальные** | **эффекты** |
| 40 | СТАРТ |
| 41 | КОНЕЦ |
| 42 | ПОПАДАНИЕ |
| 43 | ВЫСТРЕЛ |
| 44 | ПРОМАХ |
| 45 | ЗАРЯДКА |
| 46 | СОНАР |
| 47 | КРАСНАЯ ВОЛНА |
| 48 | ТРЕВОГА |
| 49 | ПУЛЬСАЦИЯ |
| 80 | красный |
| 81 | зеленый |
| 82 | синий |
`85` без параметра отключает анимации `s_b`. В debug-режиме контроллер может отправить `85 - rendering OFF`.
Любая непустая команда `85...` запускает анимации `s_b`, если они еще не запущены. Direct-группы `813x` и `8530..8534` управляются отдельными командами и не смешиваются с обычными эффектами `85`.
Анимации рассчитываются как виртуальная 2D-панель. Для внешней программы важны только коды эффектов, длительность и правила возврата к предыдущему состоянию.
###### Управляющие коды `85`
| `XX` | Назначение | Длительность по умолчанию |
|---|---|---|
| `00` | Автокарусель выключена, очистить экран, перейти в ожидание | - |
| `01` | Автокарусель включена | 10 сек на эффект |
###### Поведение после окончания эффекта
- Если запущен базовый эффект `10..22` и автокарусель выключена, после истечения времени экран очищается и `s_b` переходит в ожидание.
- Если автокарусель включена, базовые эффекты переключаются по кругу `10 -> 11 -> ... -> 22 -> 10`.
- Если запущен спецэффект `40..49` или `80..82`, после завершения контроллер возвращается к последнему базовому эффекту.
- Если автокарусель выключена, после спецэффекта экран очищается и уходит в ожидание.
###### Direct-шкалы `8530..8534`
Эти команды управляют отдельными шкалами `s_b`. Параметр после `XX` - уровень шкалы `0..22`. Значения больше `22` ограничиваются до полной шкалы.
Шкалы живут независимо от эффектов и не обнуляются при `8500`, `8501`, `8510..8522`, `8540..`, перезапуске анимаций или автопереходе карусели. Обновляются командами `8531..8534`; `8530` вручную очищает шкалы.
| Команда | Назначение | Параметр |
|---|---|---|
| `8530` | Очистить все direct-шкалы | не используется |
| `8531NN` | Шкала 1: красный -> фиолетовый -> синий | уровень `0..22` |
| `8532NN` | Шкала 2: красный -> зеленый | уровень `0..22` |
| `8533NN` | Шкала 3: красный -> фиолетовый -> синий | уровень `0..22` |
| `8534NN` | Шкала 4: красный -> зеленый | уровень `0..22` |
***Примеры:***
- `8530` - очистить все direct-шкалы
- `853105` - установить уровень `5` для первой шкалы
- `853222` - полностью зажечь вторую шкалу
- `853300` - погасить третью шкалу
- `853422` - полностью зажечь четвертую шкалу
###### Тесты морского боя VR `8525TVVV`
При запуске теста обычные анимации `s_b` останавливаются, и панель переходит в тестовый режим.
| Команда | Назначение |
|---|---|
| `85250` | Стоп теста, очистить тестовый режим |
| `85251` | Общий тест подсветки VR: бегущая змейка, цвета меняются |
| `85252NN` | Тест строки панели VR, `NN` - номер строки |
| `85253NN` | Тест столбца панели VR, `NN` - номер столбца |
| `85254NNN` | Тест адресного элемента `NNN` |
***Примеры:***
- `85251` - змейка VR
- `8525212` - строка `12` VR
- `852533` - столбец `3` VR
- `85254105` - адресный элемент `105`
###### Базовые эффекты `8510..8522`
| `XX` | Имя в коде | Визуальный смысл | Длительность по умолчанию |
|---|---|---|---|
| `10` | `hor wave` | Горизонтальная волна: синяя и красная волны идут навстречу | 10 сек |
| `11` | `vert wave` | Вертикальная морская волна снизу вверх/вниз, ping-pong | 10 сек |
| `12` | `diag wave` | Диагональная волна с темно-синим/оранжевым характером | 10 сек |
| `13` | `plazma` | Плазма: смешение синий/красный/зеленый | 10 сек |
| `14` | `night` | Ночной градиент: голубой, фиолетовый, розовый | 10 сек |
| `15` | `rainbow` | Радуга, полный HSV-спектр | 10 сек |
| `16` | `fire-ice` | Огонь-лед, красный к голубому | 10 сек |
| `17` | `wave` | Вода, диагональная темно-синяя/голубая волна | 10 сек |
| `18` | `stars` | Звезды, розово-зеленая диагональная динамика | 10 сек |
| `19` | `scaner` | Зеленый сканер с затуханием | 10 сек |
| `20` | `flame` | Поток / 2D RGB-градиент | 10 сек |
| `21` | `shtorm` | Быстрая радужная буря | 10 сек |
| `22` | `ice` | Лед, холодный вариант красный/голубой | 10 сек |
###### Спецэффекты `8540..8549`
Спецэффекты предназначены для событий игры. Они имеют приоритет над базовой анимацией, очищают состояние панели перед показом и после завершения возвращают систему к предыдущему базовому состоянию или в ожидание.
| `XX` | Имя в коде | Назначение | Длительность по умолчанию |
|---|---|---|---|
| `40` | `START` | Старт: волны темно-синий -> бирюзовый снизу вверх | 3 сек |
| `41` | `FINISH` | Финиш / завершение | 3 сек |
| `42` | `ONE_SHOT` | Попадание / торпеда | 2 сек |
| `43` | `SHOT` | Выстрел / boom: красно-оранжево-желтые полосы от центра | 1 сек |
| `44` | `MISS` | Промах: зелено-голубая волна снизу вверх | 1 сек |
| `45` | `CHARGE` | Зарядка: сине-красный фон и индикатор заряда | 2 сек |
| `46` | `SONAR` | Сонар: расширяющиеся концентрические круги | 3 сек |
| `47` | `RED WAVE` | Красная волна сверху вниз | 3 сек |
| `48` | `ALARM` | Тревога: мигание красным | 3 сек |
| `49` | `PULSE` | Оранжевая пульсация | 2 сек |
###### Тестовые заливки `8580..8582`
Эти коды идут через тот же механизм спецэффектов:
| `XX` | Назначение | Длительность по умолчанию |
|---|---|---|
| `80` | Залить всю виртуальную панель красным | 3 сек |
| `81` | Залить всю виртуальную панель зеленым | 3 сек |
| `82` | Залить всю виртуальную панель синим | 3 сек |
###### Диагностика `85`
В debug-режиме возможны сообщения:
| Сообщение | Значение |
|---|---|
| `85 - rendering ON` | Рендер `s_b` запущен |
| `85 - rendering OFF` | Рендер остановлен командой `85` |
| `[S_B_] autoCarousel ON` | Автокарусель включена |
| `[S_B_] autoCarousel OFF` | Автокарусель выключена, экран очищен |
| `[S_B_] effect: 85XX (...)` | Запущен базовый эффект |
| `[S_B_] gauge: 85XX, level=N` | Обновлена direct-шкала `30..34` |
| `[S_B_] spec: XX (...)` | Запущен спецэффект |
| `[S_B_] effect done, waiting...` | Эффект завершен, экран очищен, режим ожидания |
Ограничения текущего кода:
- параметры после `85` должны быть цифрами, но строгой проверки каждого символа сейчас нет;
- для спецэффектов в текущем коде принимается любой `XX >= 40`, но безопасно описаны только `40..49` и `80..82`;
- полный останов анимаций выполняется пустой командой `85`.
##### Отдельный раздел для Данро
`85XXYY`:
`86XX[SSS]`:
- XX – команда;
- YY – время в секундах.
- SSS – время в секундах.
***Пример:*** `854505` – включить спецэффект ЗАРЯДКА на 5 секунд
***Пример:*** `864906` – включить эффект "Падающие ряды" на 6 секунд
`85` – без параметра отключает процесс рендеринга эффектов (чтобы освободить оперативную память).
`86` – без параметра отключает анимации Данро.
Команды `86XX[SSS]` управляют только панелью Данро и не меняют direct-объекты других аппаратов.
###### Тесты панели Данро `8625TVVV`
При запуске теста обычные анимации Данро останавливаются, и панель переходит в тестовый режим.
| Команда | Назначение |
| ---------- | ---------------------------------------------------------- |
| `86250` | Стоп теста, очистить тестовый режим |
| `86251` | Общий тест подсветки Данро: бегущая змейка, цвета меняются |
| `86252NN` | Тест строки панели Данро, `NN` - номер строки |
| `86253NN` | Тест столбца панели Данро, `NN` - номер столбца |
| `86254NNN` | Тест адресного элемента `NNN` |
***Примеры:***
- `86251` - змейка Данро
- `8625212` - строка `12` Данро
- `862533` - столбец `3` Данро
- `86254105` - адресный элемент `105`
###### Список эффектов
| Команда (`XX`) | Название эффекта |
| :------------: | :----------------------: |
| 00 | Autoplay OFF, очистить экран |
| 01 | Autoplay ON |
| 25 | Тесты подсветки панели |
| 40 | Горизонтальная волна |
| 41 | Вертикальная волна |
| 42 | Диагональная волна |
@ -183,51 +515,68 @@ by: Паша Николаевич
| 51 | Морская волна |
| 52 | Диагональная волна 3 |
## Список команд
##### Отдельный раздел для RZ
| Команда | Назначение, примеры, ответы |
| ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 00 | Перезагрузить контроллер (RESET) |
| 01 | Отладочная. включает-выключает подробные логи. В релизе будет отключена |
| 02 | Подготовиться к приему файла. освободить место, отформатировать встроенную файловую, проверить хватит ли места. <br>_**Например**_, `02356987` - заявка на файл обновления размером 356987 байт.<br>Выполняется около 15 секунд, после чего весь прием  данных в порту заносится в файл "update.bin".<br>Ответ при приеме файла - каждый блок (4096) - размер принятого.<br>По окончании - переход снова в режим команд (подробнее – [Обновление](#Обновление)). |
| 03 | Показать содержимое SPIFFS |
| 04 | Запустить ОТА обновление с ранее записанным файлом SPIFFS: `/update.bin` |
| 05 | Показать версию прошивки (указана в дефолтах) |
| 06 | Показать MAC-адрес (без двоеточий, как в оригинале), уникальный, можно считать серийным номером |
| 07 | Безопасность (запрос авторизации от компа. На этот запрос создается рандомный запрос навстречу. См. [[#Алгоритм авторизации]]) |
| 08 | Безопасность (прием ответа от компьютера на запрос `07`. См. [[#Алгоритм авторизации]]) |
| 09 | Сброс EEPROM (параметром - MAC без двоеточий, иначе не сбросится) |
| 10 | Подтверждение принятия сигнала COIN, иначе этот сигнал будет посылаться снова с периодичностью `200 мс` (сколько приняли койнов, столько и подтверждений быть должно) |
| 20X | Установить состояние выходов - всего выходов 8, давать их двоичное состояние.<br>_**Например**_, `203` - вывести 1 и 2 выходы по единичке, остальные - нолики. Соответственно, выход на разъеме будет "прижат" к земле. |
| 21XY | Установить состояние выхода номер Х в -> Y \[0,1,2(инверсия)\].<br>_**Примеры:**_<br>`2131` - Включить 3 по индексу выход<br>`2170` - Выключить 7 по индексу выход |
| 30X | Хоппер 1.<br>`301` - Включить мотор хоппера<br>`300` - Выключить мотор хоппера<br>`309` - Выдать приз (в авторежиме[^1]) |
| 40X | Хоппер 2.<br>Аналогично |
| 8XY | Выбор программы адресных диодов Y по каналу X (См. [[#Программы адресных диодов]]) |
| 85XXYY | См. [[#Специфичные программы]] |
| 85 | Без параметра отключает процесс рендеринга эффектов (чтобы освободить оперативную память) |
| 89\[X\] | Переключить цветовое чередование.<br>***Примеры:***<br>- `89` или `890` – RGB<br>- `891` – RBG<br>- `892` – BRG<br>- `893` – BGR<br>- `894` - GRB<br>- `895` - GBR |
| 90 | Очистить очередь команд |
| 91 | Запрос состояния цифровых входов, их всего 24(+2 входа хоппера), ответ в двоичном коде.<br>Для уменьшения объема передаваемой информации, преобразуется в десятичное число<br>_**Примеры:**_<br>`INPUT67108863` (`11111111111111111111111111`) - все кнопки не нажаты<br>`INPUT67108861` (`11111111111111111111111101`) - нажата вторая кнопка |
| 91X | _Дополнительно_: задать время антидребезга платы (`10..100`; по умолчанию установлено на 50 мс)<br>_**Например**_, 9110 - Установить антидребезг на 10 мс |
| 92 | Запрос значения аналоговых входов **(отключает автовывод)** - ответ в формате `ADC0,0,0,0`.<br>Всего 4 аналоговых входа |
| 92X | Периодический автовывод значений аналоговых входов.<br>_**Например**_, `92100` - каждые 100 милисекунд выдавать значения ADC (`50..5000`) |
| 93 | Запрос `global_summa` (число коинов, нестираемо) |
| 96 | Cохранение в памяти платы пользовательского значения.<br>***Например,*** «роли» контроллера (левый-правый в морском бое, или шкаф…)<br>***Пример команды:*** `96right` |
| 97 | Вывод пользовательского значения<br>***Формат вывода:*** `ROLE : <значение>` (до 20 символов) |
| 98 | Запрос загруженности ядер, оперативки, свободного места в памяти |
| 99 | Запрос статуса |
`87XX[SSS]` - резервная виртуальная панель. Формат и эффекты совпадают с `86`.
[^1]: Авторежим: если датчик в закрытом состоянии - на полсекунды включить мотор, ждать сработки датчика либо таймаута. Если таймаут - выдать сообщение "HOPPER1 ERROR" и наглухо повесить процесс хоппера до перезагрузки. Иначе - сообщение "HOPPER1 OK"
Команды `87XX[SSS]` управляют только резервной панелью RZ и не меняют direct-объекты других аппаратов.
###### Тесты панели RZ `8725TVVV`
При запуске теста обычные анимации RZ останавливаются, и панель переходит в тестовый режим.
| Команда | Назначение |
|---|---|
| `87250` | Стоп теста, очистить тестовый режим |
| `87251` | Общий тест подсветки RZ: бегущая змейка, цвета меняются |
| `87252NN` | Тест строки панели RZ, `NN` - номер строки |
| `87253NN` | Тест столбца панели RZ, `NN` - номер столбца |
| `87254NNN` | Тест адресного элемента `NNN` |
***Примеры:***
- `8701` - включить автоперебор резервной панели
- `8743` - rainbow с длительностью по умолчанию
- `872533` - тест столбца `3`
- `87254105` - адресный элемент `105`
- `87` - остановить анимации
##### Дополнительные цифровые GPIO
`50CCP`:
- `CC` – подкоманда;
- `P` – числовой параметр.
| Формат | Назначение |
| :----: | :--------- |
| `50` | Показать режимы и уровни GPIO25/GPIO26 |
| `5001P` | Настроить режимы: если `P > 9`, GPIO25 выход; если младший бит `P` равен `1`, GPIO26 выход |
| `5005P` | Показать краткое состояние: `ADD:..` |
| `5010P` | Установить уровни выходов: GPIO25 = `P > 9`, GPIO26 = младший бит `P` |
# Обновление прошивки платы
## Православный (новый)
Зайти в [[Новое приложение для работы с платой|програму для платы]], и [[Новое приложение для работы с платой#Обновление прошивки|обновить прошивку]] через него.
Для этого надо:
1. Заполучить новую прошивку
2. Подключить плату
3. Открыть приложение
4. Подключиться к плате через приложение
5. Обновить прошивку через специальный пункт "Обновление прошивки"
## Пендосский (старый)
Файл обновления принимается командой `02<size>`. После полного приема контроллер отвечает текущим количеством записанных байт и итоговым `file size=<size> OK`, затем обновление запускается командой `04`.
# Обновление
Для обновления платы на новую версию прошивки надо:
1. Волшебным образом заполучить флешку с новой прошивкой
2. Проверить, что прошивка на плате точно старше при помощи команды `05`
3. Выбрать файл новой прошивки с флешки
4. Вполнить появившуюся команду
5. После успешного выполнения команды, проверить состояние SPIFFS
4. Выполнить появившуюся команду
5. После успешного выполнения команды, проверить состояние файла обновления
6. При наличии выделенного места, обновить прошивку при помощи команды `04`, дождаться завершения обновления
7. Проверить, что прошивка на плату встала при помощи команды `05`
8. ...
9. PROFIT!
9. PROFIT!