# Firmware Notes: ESP32 Весовой контроллер ## Стек | Инструмент | Версия / примечание | |----------------------|-----------------------------------------------------------------------------| | Arduino IDE | Основная среда разработки | | ESP32 core | **esp32 by Espressif Systems 3.x** (НЕ Arduino ESP32 Boards 2.0.x!) | | Целевая плата | ESP32 Dev Module | | Порт прошивки | USB Serial (напр. `/dev/cu.usbserial-...`) | > Использование Espressif 3.x принципиально: в нём есть нативная `ETH.h` с поддержкой W5500, > которая надёжнее сторонней `Ethernet.h`. Версия 2.x (Arduino) вызывала `hardwareStatus: 0`. ## Используемые библиотеки | Библиотека | Источник | Назначение | |----------------------|-----------------------------|----------------------------------------| | `ETH.h` | Встроена в ESP32 core 3.x | Ethernet W5500 через SPI (нативная) | | `NetworkClient` | Встроена в ESP32 core 3.x | TCP-клиент поверх ETH.h | | `NetworkUDP` | Встроена в ESP32 core 3.x | UDP для NTP-синхронизации | | `PubSubClient` | Nick O'Leary (Arduino Lib) | MQTT клиент | | `ArduinoJson` | Benoit Blanchon | Формирование JSON-payload | | `Wire.h` | Встроена | I2C для DS3231 | | `RTClib` | Adafruit | Работа с DS3231 RTC | > **Отказались от:** `Ethernet.h` (сторонняя) + `SSLClient` — SPI конфликты и TLS handshake failure. > Переход на нативную `ETH.h` (Espressif) решил проблему. ## Ключевые параметры конфигурации ```cpp // MQTT const char* MQTT_SERVER = "77.222.43.248"; // scales.zeroday.su const int MQTT_PORT = 1884; // plain (без TLS, тестовая фаза) const char* MQTT_TOPIC = "scales/weighing/event"; const char* DEVICE_ID = "scales_01"; const char* MQTT_USER = "esp32"; const char* MQTT_PASS = "Esp32Scales#2026"; // GPIO #define W5500_CS_PIN 4 #define W5500_RST_PIN 26 #define RELAY_RED_PIN 32 #define RELAY_GREEN_PIN 33 // UART (весы) // Serial2, GPIO16 RX, GPIO17 TX, 9600 baud // SPI (W5500) — MOSI/MISO перепутаны на модуле // SPI.begin(SCK=18, MISO=23, MOSI=19, SS=4) ← физически перевёрнуто! // NTP // UDP broadcast на 216.239.35.0 (Google NTP) ``` ## Логика основного цикла ``` BOOT: 1. Инициализация DS3231 (I2C) — ОБЯЗАТЕЛЬНО до ETH.begin()! 2. ETH.begin() — W5500 SPI инициализация 3. DHCP → если FAIL → статический IP (192.168.10.200) 4. NTP синхронизация RTC (UDP, Google 216.239.35.0) 5. Serial2.begin(9600) — UART для весов 6. Веб-сервер на порту 80 (live статус) 7. MQTT connect (esp32 / Esp32Scales#2026) LOOP: ├─ Читать Serial2 (строки с весов) │ └─ Парсить: "ww018450.500kg" → weight_kg = 18450.5 │ ├─ Логика стабилизации: │ ├─ Накапливаем N последних показаний │ ├─ Если разброс < ±50 кг И вес > порога (машина есть) → stable = true │ └─ Если stable → отправить MQTT + включить КРАСНЫЙ светофор │ ├─ После получения подтверждения взвешивания: │ └─ Включить ЗЕЛЁНЫЙ светофор, сбросить флаг │ ├─ Ждать пока вес упадёт ниже порога → машина уехала → сбросить всё │ └─ MQTT reconnect при обрыве (rc != 0 → повторная попытка) WEB (встроенный HTTP): GET / → live HTML дашборд (вес, статус светофора) GET /api/status → JSON: {"weight_kg": ..., "stable": ..., "light": "red|green"} ``` ## Логика светофора | Состояние | Красный | Зелёный | |-----------------------|---------|---------| | Ожидание машины | OFF | ON | | Машина на весах | ON | OFF | | Взвешивание стабильно | ON | OFF | | Данные отправлены | OFF | ON | ## Известные проблемы / TODO ### Решённые проблемы - ✅ **GPIO5 strapping pin** — вызывал SPI конфликт при загрузке → переключено на GPIO4 - ✅ **MOSI/MISO перепутаны** на зелёном W5500 модуле → компенсировано в `SPI.begin()` - ✅ **Синий W5500 бракованный** — заменён на зелёный компактный 3.3V - ✅ **DS3231 I2C конфликт с ETH** — решено инициализацией RTC до `ETH.begin()` - ✅ **Ethernet.h + SSLClient не работали** → переход на нативную `ETH.h` (ESP32 core 3.x) - ✅ **DHCP FAIL → Static IP** — добавлен fallback на 192.168.10.200 - ✅ **NTP Timeout** — следствие отсутствия сети (теперь работает после решения W5500) ### Актуальные TODO - [ ] **P5=3 на TITAN 9** — главный блокер. Нужен пароль сервисного меню (Zemic: +7 (472) 277-71-19) - [ ] **Тест с подключённой платформой** — без платформы весы могут не давать RS232 - [ ] **Переход на MQTTS** (порт 8883, TLS) после подтверждения RS232-потока - [ ] **DS3231 detection нестабильный** — иногда не определяется при старте; возможно нужен pull-up - [ ] **Локальная буферизация** — сохранять события если MQTT недоступен - [ ] **Watchdog** — перезагрузка при зависании MQTT/Ethernet стека ## Файлы прошивки Актуальный `.ino` файл находится **локально у Алексея** (не залит в репо). Сгенерированный в ходе разработки скелет: `scales_controller.ino` (создавался в чате). Репозиторий бэкенда (server.js + WebSocket UI): https://git.zeroday.su/admin/scales