251 lines
8.6 KiB
Markdown
251 lines
8.6 KiB
Markdown
# PROJECT_KNOWLEDGE.md — Весовой контроллер ESP32
|
|
|
|
> Последнее обновление: 2026-05-03
|
|
> Автор: Алексей (admin@zeroday.su)
|
|
|
|
## Назначение проекта
|
|
|
|
ESP32-based весовой контроллер для автомобильной грузовой платформенной весовой системы.
|
|
Индикатор: **Zemic TITAN 9** (основан на Zemic A12E). Грузоподъёмность платформы — до 50 тонн.
|
|
|
|
**Задачи контроллера:**
|
|
- Приём данных весов по RS232 (через MAX3232 → Serial2)
|
|
- Передача данных на сервер по MQTT over Ethernet (W5500)
|
|
- Управление светофором (2-канальное реле: красный / зелёный сигнал)
|
|
- Локальный веб-интерфейс на ESP32 (статус + IP)
|
|
|
|
---
|
|
|
|
## Стек технологий
|
|
|
|
### Железо (Hardware)
|
|
|
|
| Компонент | Модель | Примечание |
|
|
|---|---|---|
|
|
| МК | ESP32 Dev Module | Arduino IDE, ESP32 core 3.x (Espressif) |
|
|
| Ethernet | W5500 зелёный, компактный 3.3V | Первый синий модуль был дефектный (RJ45 трансформатор не работал) |
|
|
| RS232 → TTL | MAX3232 | Для согласования уровней 12V RS232 и 3.3V ESP32 |
|
|
| RTC | DS3231 | Обнаружение нестабильное — требует инициализации **до** ETH.begin() |
|
|
| Реле | 2-канальный оптоизолированный модуль | Управление через BC547 транзисторы |
|
|
| Питание | 5V 2A PSU | |
|
|
|
|
### Подключение W5500 → ESP32
|
|
|
|
| W5500 | ESP32 GPIO | Примечание |
|
|
|---|---|---|
|
|
| MOSI | GPIO 23 | На модуле MOSI/MISO физически перепутаны — компенсировано в прошивке |
|
|
| MISO | GPIO 19 | (MISO/MOSI swapped на плате) |
|
|
| SCK | GPIO 18 | |
|
|
| CS | GPIO 4 | GPIO5 — strapping pin, вызывал конфликты SPI при инициализации |
|
|
| RST | GPIO 26 | |
|
|
| INT | GPIO 27 | Не используется |
|
|
|
|
### Подключение MAX3232 → ESP32
|
|
|
|
| MAX3232 (TTL сторона) | ESP32 GPIO |
|
|
|---|---|
|
|
| TX (TTL out) | GPIO 16 (RX2) |
|
|
| RX (TTL in) | GPIO 17 (TX2) — не используется |
|
|
| VCC | 3V3 |
|
|
| GND | GND |
|
|
|
|
### Подключение весов Zemic TITAN 9
|
|
|
|
| DB25 пин весов | Куда |
|
|
|---|---|
|
|
| Пин 2 (TXD) | MAX3232 RX (RS232 сторона) |
|
|
| Пин 7 (GND) | Общий GND |
|
|
|
|
### Реле (управление светофором)
|
|
|
|
| GPIO ESP32 | Реле | Сигнал |
|
|
|---|---|---|
|
|
| GPIO 32 | Канал 1 | Красный |
|
|
| GPIO 33 | Канал 2 | Зелёный |
|
|
|
|
---
|
|
|
|
## Прошивка (Firmware)
|
|
|
|
**Файл:** `firmware/scales_controller.ino`
|
|
|
|
**Библиотеки:**
|
|
- `ETH.h` — нативная библиотека ESP32 core 3.x (Espressif) для W5500
|
|
- `NetworkClient`, `NetworkUDP` — из ESP32 core 3.x
|
|
- `PubSubClient` (Nick O'Leary) — MQTT клиент
|
|
- `ArduinoJson` (Benoit Blanchon) — сериализация JSON
|
|
- `RTClib` — DS3231 RTC
|
|
|
|
**Ключевые параметры прошивки:**
|
|
|
|
```cpp
|
|
// Ethernet SPI
|
|
#define ETH_SPI_SCK 18
|
|
#define ETH_SPI_MISO 19 // Физически MOSI на плате (swapped!)
|
|
#define ETH_SPI_MOSI 23 // Физически MISO на плате (swapped!)
|
|
#define ETH_PHY_CS 4 // Не GPIO5! (strapping pin)
|
|
#define ETH_PHY_RST 26
|
|
#define ETH_PHY_IRQ 27
|
|
|
|
// UART (весы)
|
|
#define SCALES_BAUD 9600 // P3 в меню весов
|
|
|
|
// Реле
|
|
#define RELAY_RED_PIN 32
|
|
#define RELAY_GREEN_PIN 33
|
|
|
|
// MQTT (тестовая фаза)
|
|
const char* MQTT_HOST = "77.222.43.248"; // или scales.zeroday.su
|
|
const int MQTT_PORT = 1884; // plain MQTT
|
|
const char* MQTT_USER = "esp32";
|
|
const char* MQTT_TOPIC = "scales/weighing/event";
|
|
```
|
|
|
|
**Порядок инициализации в setup() (критично!):**
|
|
1. `Wire.begin(21, 22)` → DS3231 RTC
|
|
2. `SPI.begin(SCK, MISO, MOSI)` → W5500
|
|
3. `ETH.begin(...)` → Ethernet
|
|
4. `mqttClient.setServer(...)` → MQTT
|
|
5. `Serial2.begin(9600, ...)` → RS232 от весов
|
|
|
|
---
|
|
|
|
## Сервер (Backend)
|
|
|
|
**Сервер:** `scales.zeroday.su`
|
|
**IP:** `77.222.43.248`
|
|
**ОС:** Ubuntu 24
|
|
**Директория проекта:** `/var/www/scales/`
|
|
|
|
### Структура директории
|
|
|
|
```
|
|
/var/www/scales/
|
|
├── server.js # Node.js Express + WebSocket + MQTT subscriber
|
|
├── public/
|
|
│ └── index.html # Дашборд (реальное время, история, светофор, график)
|
|
├── node_modules/
|
|
└── package.json
|
|
```
|
|
|
|
### Стек сервера
|
|
|
|
| Компонент | Версия / Конфиг |
|
|
|---|---|
|
|
| Node.js | LTS |
|
|
| Express | HTTP + WebSocket (ws) |
|
|
| MQTT клиент | mqtt (npm) |
|
|
| PM2 | Процесс: `scales` (id=13), порт 3016 |
|
|
| Mosquitto | MQTT broker, конфиг: `/etc/mosquitto/conf.d/acs.conf` |
|
|
| nginx | Reverse proxy + SSL termination |
|
|
| SSL | Let's Encrypt (certbot), домен `scales.zeroday.su` |
|
|
| PostgreSQL | Установлен, для будущей персистентности (пока in-memory) |
|
|
|
|
### Переменные окружения (server.js)
|
|
|
|
```js
|
|
const PORT = 3016;
|
|
const MQTT_BROKER = 'mqtt://localhost:1883';
|
|
const MQTT_USER = 'scales-server';
|
|
// MQTT_PASS — хранится в server.js, не публикуется
|
|
const MQTT_TOPIC = 'scales/weighing/event';
|
|
const MAX_HISTORY = 100; // событий в памяти
|
|
```
|
|
|
|
### MQTT Конфигурация
|
|
|
|
**Файл:** `/etc/mosquitto/conf.d/acs.conf`
|
|
|
|
```
|
|
listener 1883 127.0.0.1 # для Node.js бэкенда
|
|
listener 1884 0.0.0.0 # для ESP32 (plain, тестовый)
|
|
allow_anonymous false
|
|
password_file /etc/mosquitto/passwd
|
|
```
|
|
|
|
**Пользователи MQTT:**
|
|
|
|
| Пользователь | Роль |
|
|
|---|---|
|
|
| `esp32` | ESP32 контроллер (publisher) |
|
|
| `scales-server` | Node.js backend (subscriber) |
|
|
|
|
*Пароли хранятся в `/etc/mosquitto/passwd`, в документацию не включаются.*
|
|
|
|
### nginx
|
|
|
|
- HTTPS → порт 3016 (proxy_pass)
|
|
- WebSocket upgrade: `Upgrade $http_upgrade; Connection "upgrade"`
|
|
- MQTTS stream proxy: порт 8883 → localhost:1883 (запланировано, настроено в nginx stream)
|
|
|
|
**Конфиг:** `/etc/nginx/sites-available/scales.zeroday.su`
|
|
**Stream:** nginx.conf (stream блок в конце)
|
|
|
|
### REST API (server.js)
|
|
|
|
| Endpoint | Метод | Описание |
|
|
|---|---|---|
|
|
| `/api/status` | GET | Статус MQTT, uptime, последнее событие |
|
|
| `/api/history` | GET | Последние 100 событий взвешивания |
|
|
| WebSocket `/` | WS | Реалтайм события + инит состояния |
|
|
|
|
---
|
|
|
|
## Формат данных весов
|
|
|
|
### RS232 строка от TITAN 9 / A12E
|
|
|
|
```
|
|
ww000.000kg — брутто
|
|
wn000.000kg — нетто
|
|
wt000.000kg — тара
|
|
```
|
|
ASCII, 9600 бод, 8N1.
|
|
|
|
### MQTT JSON payload
|
|
|
|
```json
|
|
{
|
|
"device_id": "scales_01",
|
|
"timestamp": "2026-03-27T16:35:25Z",
|
|
"weight_kg": 15420.5,
|
|
"weight_raw": "ww015420.500kg",
|
|
"stable": true,
|
|
"plate": null
|
|
}
|
|
```
|
|
|
|
Топик: `scales/weighing/event`, QoS: 1, Retain: false.
|
|
|
|
---
|
|
|
|
## Параметры весов Zemic TITAN 9
|
|
|
|
| Параметр | Назначение | Нужное значение |
|
|
|---|---|---|
|
|
| P3 | Скорость RS232 | 9600 (по умолчанию) |
|
|
| P4 | Формат вывода | Стандартный `ww000.000kg` |
|
|
| P5 | Режим передачи | **3** (передача при стабильном весе) — **НЕ НАСТРОЕН** |
|
|
|
|
**Пароль сервисного меню:** `1`
|
|
|
|
---
|
|
|
|
## Текущий статус проекта (на 2026-05-03)
|
|
|
|
✅ ESP32 инициализирует W5500 и подключается к MQTT
|
|
✅ Backend задеплоен, дашборд работает на https://scales.zeroday.su
|
|
✅ MQTT авторизация настроена
|
|
✅ Relay логика реализована в прошивке
|
|
❌ Весы не передают RS232 — параметр P5 = "нет передачи" (не изменён)
|
|
❌ DS3231 обнаруживается нестабильно
|
|
⏳ MQTTS (порт 8883) настроен в nginx, но не активирован в прошивке
|
|
|
|
---
|
|
|
|
## Контакты и ресурсы
|
|
|
|
- Zemic support (настройка P5): +7 (472) 277-71-19
|
|
- Репозиторий: https://git.zeroday.su/admin/weighing-controller
|
|
- Дашборд: https://scales.zeroday.su
|