Bring hardware/spec content from drho1y-mvp_1 (3d_models, arduino_code, backend_control, kicad, specification) so dan_branch holds the shared union of branch files without rewriting other branch tips. Co-authored-by: Cursor <cursoragent@cursor.com>
Вот обновленная и расширенная документация по MQTT-интерфейсу, включающая новую функциональность работы с датчиками расстояния VL53L0X, а также оптимизации, появившиеся в коде.
📡 Документация по MQTT интерфейсу (ESP32 + TMC2209 + Servo + VL53L0X)
📌 Общая информация
- Архитектура: ESP32 (FreeRTOS задача
mqttTask). - Период опроса телеметрии: 500 мс.
- Оптимизация трафика:
- Публикация данных происходит только при изменении значения (строгое кэширование).
- Используется статический буфер (
intToString/uintToString) вместо динамического классаStringдля экономии памяти и предотвращения фрагментации кучи.
- Префиксы:
.../control/...— топики для отправки команд устройству (подписка)..../feedback/...— топики для получения статуса/телеметрии от устройства (публикация).
⚙️ 1. Управление шаговым двигателем (Motor Control)
| Топик | Тип данных | Описание | Пример Payload |
|---|---|---|---|
motor/control/rpm |
Integer | Целевая скорость в об/мин (RPM). Отрицательные значения включают реверс. | -150, 0, 300 |
motor/control/driver |
String | Аппаратное вкл/выкл драйвера (пин EN_PIN). on = LOW (вкл), иначе = HIGH (выкл). |
on, off |
motor/control/totalsteps/reset |
Any | Сброс счетчика шагов в ноль. Устройство сразу опубликует "0" в feedback. |
1, reset |
Телеметрия двигателя (Motor Feedback)
(Публикуется только при изменении)
motor/feedback/rpm(Integer): Текущая скорость.motor/feedback/totalsteps(Integer): Общее количество шагов.motor/feedback/is_run(String:true/false): Двигатель движется.motor/feedback/driver/status(String:on/off): Общий статус драйвера.motor/feedback/tmc/status(String:on/off): Статус программного включения TMC.
Детальная телеметрия TMC2209 (motor/feedback/tmc/...)
current_percent(Integer): Текущий % рабочего тока.microsteps(Integer): Текущий режим микрошага.sg_result(Integer): Текущее значение StallGuard (нагрузка).interstep_duration(Integer): Длительность между шагами.status/over_temp(String:true/false): Перегрев.status/short_to_ground(String:true/false): КЗ на землю.status/open_load(String:true/false): Обрыв нагрузки.status/stealth_chop_active(String:true/false): Активен ли StealthChop.status/standstill(String:true/false): Двигатель в покое.status/current_scaling(Integer): Внутренний масштабный коэффициент тока.
🦾 2. Управление сервоприводами (Servo Control)
Поддержка нескольких каналов ({channel} от 0 до MAX_SERVOS - 1).
Команды
| Топик (пример для канала 0) | Тип данных | Описание | Пример Payload |
|---|---|---|---|
servo/control/0/angle |
Integer (0-180) | Установить угол поворота. | 90 |
servo/control/0/enable |
String | Включить (on, 1, true) или выключить. |
on |
Обратная связь
servo/0/feedback/status(String:on/off): Статус питания сервопривода.servo/0/feedback/angle(Integer): Текущий установленный угол.
📏 3. Управление датчиками VL53L0X (Sensor Control) (НОВОЕ)
Поддержка до 8 каналов (VL53L0X_MAX_CHANNELS = 8). Топики используют параметр {channel} (0–7).
| Топик | Тип данных | Описание | Пример Payload |
|---|---|---|---|
sensor/control/mode |
Integer | Установка глобального режима измерения (0 до MODE_COUNT - 1). |
0, 1 |
sensor/control/mode_name |
String | Заглушка/Логирование. Принимает имя режима для отладки. | LongRange |
sensor/control/calibrate/start/{ch} |
Integer | Начало калибровки: указать близкое расстояние в мм. | 50 |
sensor/control/calibrate/finish/{ch} |
Integer | Завершение калибровки: указать дальнее расстояние в мм. | 500 |
sensor/control/clear_cal/{ch} |
Any | Сбросить калибровку для указанного канала. | 1 |
sensor/control/enable/{ch} |
String | Включить (on, 1, true) или выключить конкретный канал. |
on |
sensor/control/publish_all |
Any | Принудительный сброс кэша. Заставляет устройство немедленно опубликовать текущие значения всех датчиков, даже если они не изменились. | 1 |
📊 4. Телеметрия датчиков VL53L0X (Sensor Feedback) (НОВОЕ)
Глобальная информация о режиме
Публикуется только при смене режима измерения:
sensor/feedback/mode(String): Человекочитаемое имя текущего режима (например, "Default", "LongRange").sensor/feedback/mode_id(Integer): Числовой ID текущего режима.sensor/feedback/max_range(Integer): Максимальная дальность для текущего режима (в мм).
Постатусная информация по каналам ({channel} = 0..7)
(Публикуется только при изменении состояния или значения)
| Топик (пример для канала 0) | Тип данных | Описание |
|---|---|---|
sensor/feedback/0/status |
String (on/off) |
Включен ли логически данный канал. |
sensor/feedback/0/calibrated |
String (true/false) |
Была ли проведена калибровка для этого канала. |
sensor/feedback/0/distance |
Integer или String | Калиброванное расстояние в мм. Если значение 65535 (ошибка/вне диапазона), публикуется строка "out_of_range". |
sensor/feedback/0/raw |
Integer | Сырое (некалиброванное) значение расстояния в мм. |
Примечание: Топики distance и raw публикуются только если канал активен (vl53l0xIsChannelActive).
💡 Важные особенности реализации (Обновлено)
- Безопасная работа со строками: В новом коде добавлены функции
intToStringиuintToString, использующие статические буферы. Это полностью устраняет риск фрагментации памяти (heap fragmentation) при частой публикации телеметрии, который был присущ использованию классаString. - Принудительная публикация: Топик
sensor/control/publish_allсбрасывает кэш значенийdistanceиrawна65535. При следующем цикле (через 500 мс) система "увидит" изменение и гарантированно отправит актуальные данные. Это полезно при подключении нового клиента, которому нужно получить текущее состояние без перезагрузки устройства. - Обработка ошибок дальности: Если датчик возвращает
65535(стандартный код ошибки "вне диапазона" или сбоя измерения для VL53L0X), в топикdistanceпубликуется понятная строка"out_of_range", а не число, что упрощает обработку на стороне клиента. - Изоляция каналов: Цикл телеметрии VL53L0X предварительно проверяет
vl53l0xIsChannelPresent(ch), поэтому несуществующие или отключенные на аппаратном уровне каналы не создают лишнего трафика.
🛠️ Примеры использования (CLI / mosquitto)
# --- Двигатель ---
mosquitto_pub -t "motor/control/rpm" -m "100"
mosquitto_pub -t "motor/control/tmc/stealthchop" -m "on"
# --- Сервопривод (канал 0) ---
mosquitto_pub -t "servo/control/0/enable" -m "on"
mosquitto_pub -t "servo/control/0/angle" -m "90"
# --- Датчики VL53L0X ---
# Включить канал 1
mosquitto_pub -t "sensor/control/enable/1" -m "on"
# Начать калибровку канала 1 (близкая точка 50 мм)
mosquitto_pub -t "sensor/control/calibrate/start/1" -m "50"
# ... передвинуть объект ...
# Завершить калибровку канала 1 (дальняя точка 400 мм)
mosquitto_pub -t "sensor/control/calibrate/finish/1" -m "400"
# Принудительно запросить публикацию всех текущих показаний датчиков
mosquitto_pub -t "sensor/control/publish_all" -m "1"
# Подписаться на все события датчиков для отладки
mosquitto_sub -t "sensor/feedback/#" -v