mirror of https://github.com/LaskaKit/ESPlan.git
142 lines
4.6 KiB
C++
Executable File
142 lines
4.6 KiB
C++
Executable File
/*
|
|
* ESPlan_RS485_Relay.ino
|
|
* 8 / 16-kanalovy RS485 rele modul (Modbus-RTU)
|
|
*
|
|
* Hardware : LaskaKit ESPlan (ESP32 + LAN8720)
|
|
* Modul : 8-ch / 16-ch 12V rele 250VAC/10A RS485 DIN
|
|
* https://www.laskakit.cz/8-kanalu-12v-rele-modul-250vac-10a--rs485--din/
|
|
*
|
|
* Soubory projektu:
|
|
* cfg.h - HW konstanty, registry, datove struktury
|
|
* mb_client.h/cpp - Modbus RTU klient (FC03, FC06)
|
|
* relay.h/cpp - Ovladani rele (set/toggle/latch/momentary/delay/all/read)
|
|
* i18n_str.h - Preklady CZ / EN
|
|
* ws_server.h/cpp - HTTP webserver
|
|
*
|
|
* Modbus protokol (datasheet 8ch_rele_rs485_protocols.pdf):
|
|
* FC 0x06 (Write Single Register), 8N1
|
|
* Adresa modulu se nastavuje DIP prepinaci A0-A5 (rozsah 0-47)
|
|
* Baudrate (HW pady M1/M2): 9600 (default) / 2400 / 4800 / 19200
|
|
*
|
|
* reg 0x0001..0x0010 - rele 1..16 (jednotlive kanaly)
|
|
* val 0x0100 = Open (sepne)
|
|
* val 0x0200 = Close (rozepne)
|
|
* val 0x0300 = Toggle (self-locking)
|
|
* val 0x0400 = Latch (inter-locking)
|
|
* val 0x0500 = Momentary (1s puls)
|
|
* val 0x06xx = Delay xx s (0-255)
|
|
* reg 0x0000 - vsechny kanaly
|
|
* val 0x0700 = Vsechny ON
|
|
* val 0x0800 = Vsechny OFF
|
|
*
|
|
* FC 0x03 cteni stavu: reg 0x0001..0x0010, vrati 0x0001=ON / 0x0000=OFF
|
|
*/
|
|
|
|
#include <Arduino.h>
|
|
#include <WiFi.h>
|
|
#include <ETH.h>
|
|
#include <Preferences.h>
|
|
|
|
#include "cfg.h"
|
|
#include "mb_client.h"
|
|
#include "relay.h"
|
|
#include "ws_server.h"
|
|
|
|
// ─── Globalni objekty ─────────────────────────────────────────────────────────
|
|
Preferences prefs;
|
|
RelayState relayState;
|
|
RelayConfig relayCfg;
|
|
ModbusClient modbusClient;
|
|
|
|
static bool ethGotIP = false;
|
|
static uint32_t lastReadMs = 0;
|
|
static const uint32_t READ_INTERVAL_MS = 5000; // 5s pravidelna sync z modulu
|
|
|
|
// ─── ETH udalosti ─────────────────────────────────────────────────────────────
|
|
void onEthEvent(WiFiEvent_t event) {
|
|
switch (event) {
|
|
case ARDUINO_EVENT_ETH_START:
|
|
Serial.println(F("[ETH] Inicializace..."));
|
|
ETH.setHostname("espplan-relay");
|
|
break;
|
|
case ARDUINO_EVENT_ETH_CONNECTED:
|
|
Serial.println(F("[ETH] Pripojen (fyzicka vrstva)"));
|
|
break;
|
|
case ARDUINO_EVENT_ETH_GOT_IP:
|
|
Serial.print(F("[ETH] IP: "));
|
|
Serial.println(ETH.localIP());
|
|
ethGotIP = true;
|
|
break;
|
|
case ARDUINO_EVENT_ETH_DISCONNECTED:
|
|
Serial.println(F("[ETH] Odpojeno"));
|
|
ethGotIP = false;
|
|
break;
|
|
case ARDUINO_EVENT_ETH_STOP:
|
|
Serial.println(F("[ETH] Zastaveno"));
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
// ─── Setup ────────────────────────────────────────────────────────────────────
|
|
void setup() {
|
|
Serial.begin(115200);
|
|
delay(500);
|
|
Serial.println(F("\n=== ESPlan RS485 Relay 8/16ch ==="));
|
|
Serial.println(F(" LaskaKit 8/16-ch Modbus-RTU "));
|
|
Serial.println(F("============================="));
|
|
|
|
// Nacteni konfigurace z NVS
|
|
prefs.begin("rs485rel", true);
|
|
loadConfig(prefs, relayCfg);
|
|
prefs.end();
|
|
|
|
Serial.printf("[CFG] Modbus addr=%d baud=%d\n",
|
|
relayCfg.modbusAddr,
|
|
relayCfg.baudRate);
|
|
|
|
// RS485 / Modbus
|
|
modbusClient.begin(relayCfg.baudRate, relayCfg.modbusAddr);
|
|
|
|
// ETH
|
|
WiFi.onEvent(onEthEvent);
|
|
ETH.begin(ETH_PHY_TYPE,
|
|
ETH_PHY_ADDR,
|
|
ETH_PHY_MDC,
|
|
ETH_PHY_MDIO,
|
|
ETH_PHY_POWER,
|
|
ETH_CLK_MODE);
|
|
|
|
uint32_t t0 = millis();
|
|
while (!ethGotIP && (millis() - t0 < 10000)) {
|
|
delay(100);
|
|
}
|
|
if (!ethGotIP) {
|
|
Serial.println(F("[ETH] VAROVANI: IP neziskano - web nebude dostupny!"));
|
|
}
|
|
|
|
// Webserver
|
|
webServerBegin(relayState, relayCfg, prefs, modbusClient);
|
|
|
|
// Pokus o nacteni stavu (pokud modul podporuje FC03)
|
|
Serial.println(F("[REL] Pokus o sync stavu z modulu..."));
|
|
relayReadAll(modbusClient, relayState, relayCfg);
|
|
|
|
Serial.println(F("[SYS] Inicializace dokoncena."));
|
|
}
|
|
|
|
// ─── Loop ─────────────────────────────────────────────────────────────────────
|
|
void loop() {
|
|
webServerHandle();
|
|
|
|
// Periodicky pokus o aktualizaci stavu (volitelne)
|
|
uint32_t now = millis();
|
|
if (now - lastReadMs >= READ_INTERVAL_MS) {
|
|
lastReadMs = now;
|
|
relayReadAll(modbusClient, relayState, relayCfg);
|
|
}
|
|
|
|
delay(5);
|
|
}
|