Initial: backup from Claude Project 'Весовое оборудование'

- 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
This commit is contained in:
admin
2026-04-30 12:26:31 +03:00
commit 35e5ffea1e
7 changed files with 464 additions and 0 deletions
+125
View File
@@ -0,0 +1,125 @@
# 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