35e5ffea1e
- PROTOCOL.md: topology, JSON schema, MQTT topic, auth, retry logic - HARDWARE.md: components, GPIO map, ASCII wiring, power, calibration - FIRMWARE_NOTES.md: stack (ESP32 core 3.x), libraries, main loop, known issues, TODO - INDEX.md: manifest + current status + blockers Current blocker: TITAN 9 P5 default = no RS232 output. Fix: call Zemic +7(472)277-71-19, set P5=3, then test on-site. Related server repo: admin/scales
126 lines
7.1 KiB
Markdown
126 lines
7.1 KiB
Markdown
# 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
|