Skip to content

Latest commit

 

History

11 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ESP32-S3-ETH-8DI-8RO Firmware

Firmware for the Waveshare ESP32-S3-ETH-8DI-8RO controller that exposes the board as a feature-rich Modbus RTU slave while keeping Ethernet, Wi-Fi, MQTT, Bluetooth, RTC, SD logging, and local buzzer support available for higher level applications (SCADA, HMI, alarm systems, etc.).

Key Features

  • Modbus RTU slave running on UART1 with configurable pulse indications for RX/TX activity.
  • Eight relay outputs and eight digital inputs managed through dedicated WS_* modules.
  • MQTT, Bluetooth, Ethernet, and SD card subsystems initialised during boot for integration flexibility.
  • Up to ten DS18B20 1-Wire temperature sensors with Modbus-accessible telemetry and editable sensor names.
  • Event logging with automatic mirroring to SD (/logs/events.csv) when a card is mounted.
  • Buzzer controller with Modbus-accessible configuration stored persistently in NVS.
  • RGB status LED feedback for Modbus events and error states.

Supported Hardware

  • Waveshare ESP32-S3-ETH-8DI-8RO (ESP32-S3 with PoE Ethernet, 8 DI, 8 relay outputs).
  • MicroSD card (optional) for event log persistence.
  • RS485 transceiver connected to UART1 for Modbus RTU transport.

Development Environment

  • Framework: Arduino (via PlatformIO).
  • Target board: esp32-s3-devkitc-1 with PSRAM enabled.
  • Tooling: PlatformIO CLI or the PlatformIO IDE extension.
  • Key libraries: ArduinoJson, PubSubClient, NimBLE-Arduino, ESPAsyncWebServer, AsyncTCP, Adafruit Sensor suite. Configuration lives in platformio.ini; upload speed is set to 921600 baud and serial monitoring defaults to 115200 baud.

Quick Start

  1. Install PlatformIO (CLI or VS Studio Code extension).
  2. Clone this repository and open the project folder in your IDE or terminal.
  3. Adjust include/WS_Config.h if you need to customise defaults (Wi-Fi SSID, MQTT topics, Modbus device name, RGB colours).
  4. Connect the ESP32-S3 board over USB. For PoE deployments keep the RS485 lines connected but isolated during flashing.
  5. Build and upload from the command line:
    pio run -e esp32s3-poe-eth-8di8ro
    pio run -e esp32s3-poe-eth-8di8ro -t upload
    pio device monitor -b 115200
  6. After boot the serial monitor prints module initialisation messages, including SD card status and Modbus startup confirmation.

Runtime Modules

  • WS_ModbusRTU - Modbus RTU slave implementation with coil and holding register support, RX/TX pulses, CRC validation, and SCADA logging.
  • WS_DS18B20 - One-Wire bridge that polls up to ten DS18B20 sensors, exposes readings over Modbus, and stores user-defined labels in NVS.
  • WS_Relay, WS_DIN, WS_GPIO - Hardware access layers for relay outputs, digital inputs, and general GPIO.
  • WS_MQTT, WS_Bluetooth, WS_ETH, WS_SD - Networking stacks providing MQTT cloud connectivity, BLE, Ethernet, and SD card services.
  • WS_Buzzer - PWM-based buzzer manager with queued events, manual control, and Modbus-mapped configuration registers backed by NVS.
  • WS_EventLog - Thread-safe event log with circular buffer, UART mirroring, and optional SD persistence.

Modbus RTU Interface

Serial Parameters

  • UART: Serial1 (TXD1 = GPIO17, RXD1 = GPIO18)
  • Slave ID: 0x01
  • Baud rate: 9600
  • Frame format: 8 data bits, no parity, 1 stop bit (SERIAL_8N1)

Supported Function Codes

Code Name Description
0x01 Read Coils Returns relay states plus auxiliary coils (RX/TX pulses).
0x05 Write Single Coil Switches one relay output and triggers optional buzzer feedback.
0x0F Write Multiple Coils Updates all relays in one transaction with RGB and buzzer feedback.
0x03 Read Holding Registers Exposes buzzer configuration and status registers.
0x06 Write Single Register Allows SCADA to configure buzzer behaviour and manual pulses.

Unsupported functions yield a warning entry in the event log and flash the RGB LED orange.

Coil Map (FC01, FC05, FC0F)

Coil Address Description
CH1 0x0001 Relay channel 1
CH2 0x0002 Relay channel 2
CH3 0x0003 Relay channel 3
CH4 0x0004 Relay channel 4
CH5 0x0005 Relay channel 5
CH6 0x0006 Relay channel 6
CH7 0x0007 Relay channel 7
CH8 0x0008 Relay channel 8
CH9 0x0009 Modbus RX pulse (true for ~100 ms after each valid request)
CH10 0x000A Modbus TX pulse (true for ~100 ms whenever a response is queued)

Holding Registers (FC03, FC06)

Register Address Access Description
REG_BUZZER_ENABLE 0x0063 R/W Global buzzer enable (0 = disabled, 1 = enabled).
REG_BUZZER_ON_START 0x0064 R/W Play buzzer on system startup.
REG_BUZZER_ON_RELAY 0x0065 R/W Play buzzer when relays change via Modbus.
REG_BUZZER_MANUAL 0x0066 R/W Manual control (0 stop, 1 hold on, 2 release, >2 = duration ms pulse).
REG_BUZZER_STATE 0x0067 R Instantaneous buzzer PWM output state (0/1).
REG_DS18B20_COUNT 0x0100 R Number of DS18B20 sensors that reported valid data during the last poll.
REG_DS18B20_REFRESH 0x0101 R/W Write any non-zero value to rescan the 1-Wire bus; reads as 1 while a rescan is pending.
REG_DS18B20_STATUS 0x0102 R Bitfield: bit0 module initialised, bit1 refresh pending, bits2+ sensor-online mask.
REG_DS18B20_TEMP_BASE + n 0x0110 + n R Temperature for sensor slot n (signed value, degC * 100).
REG_DS18B20_PRESENCE_BASE + n 0x0120 + n R Slot presence word for sensor n (bit0 address valid, bit1 online, bit2 raw valid, bit3 corrected valid, bit4 offset applied, bit5 stale/held value).
REG_DS18B20_OFFSET_BASE + n 0x0130 + n R/W Offset applied to sensor slot n (signed value, degC * 100, persisted).
REG_DS18B20_TEMP_TENTH_BASE + n 0x0140 + n R Temperature for slot n scaled to 0.1 degC (signed value, degC * 10).
REG_DS18B20_SLOT_BASE + (n * 16) + w 0x0150 + (n * 16) + w R Slot metadata (w=0 status, 1 slot id, 2-5 ROM code, 6 temp register, 7 offset register, 8 name base).
REG_DS18B20_NAME_BASE + (n * 8) + w 0x0200 + (n * 8) + w R/W Sensor n name storage (two ASCII chars per register, offset w in [0,7]).

Additional registers can be added in WS_Buzzer.cpp via Buzzer_ModbusWrite and Buzzer_ModbusRead.

  • DS18B20 names persist in NVS; write ASCII pairs through holding registers 0x0200-0x024F. The high byte is stored first (0x0200 high byte = name character 0, low byte = character 1).
  • Temperature offsets persist per sensor via registers 0x0130-0x0139. Values are signed and scaled by 100 (set 5 to apply +0.05 degC). Corrections survive resets and Modbus writes validate ranges automatically.
  • Sensors are rescanned automatically every 60 s (DS18B20_RESCAN_INTERVAL_MS in WS_Config.h). Manual rescans via register 0x0101 still work and force an immediate update/log entry.
  • Metadata per slot lives under 0x0150 with a stride of 16 registers per sensor. Within each block, register +0 returns the same status bits exposed in REG_DS18B20_PRESENCE_BASE + n (bit0 installed, bit1 online, bit2 raw valid, bit3 corrected valid, bit4 offset applied, bit5 stale/held value), +1 exposes the slot index, +2..+5 encode the 64-bit ROM code (little endian pairs), +6 mirrors the temperature register number, +7 the offset register, and +8 the starting register for the sensor name.
  • Temperatures are exposed twice: 0x0110 + n holds degC * 100 (25.37 C -> 2537), while 0x0140 + n mirrors the same reading scaled by 10 (25.3 C -> 253). Offline or missing sensors return 0x8000 (-32768) only after three consecutive failed polls; until then the last valid reading is held and bit5 in the presence word signals that SCADA is seeing cached data.
  • Firmware keeps the last valid reading through up to three consecutive 1-Wire faults before flagging the sensor offline, so SCADA trends stay flat. After the threshold the temperature register switches back to 0x8000, meaning alarms still trip when a probe truly disconnects.

Modbus addressing cheat sheet (SCADA/FUXA)

  • Holding registers are zero-based inside the firmware. Masters that label the first holding as 40001/400001 must add that bias to the offsets below (example: 0x0110 decimal 272 › 400273 when the SCADA’s base is 400001 = offset 0).
  • Slot 1 examples:
    • Temperature (degC * 100) 0x0110 › decimal 272.
    • Temperature (degC * 10) 0x0140 › decimal 320.
    • Presence/status word 0x0120 › decimal 288 (bit0 address valid, bit1 online, bit2 raw valid, bit3 corrected valid, bit4 offset applied, bit5 stale/held value).
    • Offset register 0x0130 › decimal 304 (signed, degC * 100).
  • In FUXA: set the tag type to signed 16-bit, use divisor 100 for 0x0110 or divisor 10 for 0x0140; the presence word can be broken into booleans via bit masks without extra firmware changes.

RX/TX Pulse Indicators

  • Coils 00009 and 00010 expose RX/TX activity to SCADA. They latch to true when a frame is received or a reply is staged and automatically revert to false once MODBUS_PULSE_MS (default 100 ms) has elapsed.
  • Pulses update even during FC1 requests so polling masters can detect transmissions without timing gaps.
  • Manual clearing is possible through FC05/FC0F if your SCADA requires explicit resets.

Event Logging

  • EventLog_Add() pushes human-readable messages into an in-memory ring buffer and prints them to the USB serial console.
  • When SD_Init() mounts a card successfully, log entries also append to /logs/events.csv on the SD card (CSV header auto-created on first run).
  • Logging covers system startup, Modbus requests, relay changes, SD status, buzzer actions, and warnings (CRC errors, unsupported function codes, etc.).

Buzzer Configuration Persistence

  • The buzzer module relies on the ESP32 Preferences API to persist the configuration namespace buzzer.
  • Buzzer_LoadConfig() restores the last saved state during Buzzer_Init(), ensuring settings survive power loss.
  • Any write via Modbus registers 0x0063-0x0066 is immediately stored in NVS, and the event log records the change for traceability.

SCADA Integration Tips

  • Poll coils at 5-10 Hz to reliably observe RX/TX pulses and relay updates without saturating the UART link.
  • Use holding registers to keep buzzer behaviour aligned with plant safety rules (disable audible feedback on night shifts, enable manual alarm pulses, etc.).
  • Monitor /logs/events.csv for diagnostics; the CSV structure is timestamped for direct import into analysis tools.

Troubleshooting

  • No response on Modbus: verify UART1 wiring (GPIO17/18) and ensure the master is using slave ID 0x01. The RGB LED flashes red on CRC errors.
  • SD log missing: confirm the card mounts during boot; the serial console reports failures and the event log keeps a copy in RAM even without SD.
  • Buzzer does not sound: check REG_BUZZER_ENABLE (0x0063) and confirm manual hold is not active (REG_BUZZER_MANUAL set to 2).

Repository Layout

  • src/ - Core firmware modules (Modbus, relay control, MQTT, SD, buzzer, etc.).
  • include/ - Public headers and configuration defines (WS_Config.h, WS_ModbusRTU.h, ...).
  • lib/ - Optional space for project-specific libraries (empty scaffolding provided by PlatformIO).
  • platformio.ini - Build configuration for the esp32s3-poe-eth-8di8ro environment.

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages