Datasheet & User Manual · Board owledge (MODEL E04SD) ·
Document rev 1.0 · 2026-06-18
The E04 Modbus I/O Module is an ESP32-based industrial I/O device with 4 digital inputs and 4 digital outputs. It is exposed simultaneously over Modbus TCP (Ethernet) and Modbus RTU (RS-485), sharing one register map, and is discoverable on the LAN via mDNS / Zeroconf. A supervisory platform browses mDNS, reads capability metadata from TXT records, then polls/controls the device — no static IP or manual register-map documentation required for integration.
| Parameter | Value |
|---|---|
| MCU | ESP32-WROOM-32U V2.1 (Xtensa dual-core, no PSRAM) |
| Flash | 4 MB (DIO, 40 MHz) |
| Firmware | e04_modbus v1.0.0, built on ESP-IDF 5.4 |
| Inputs | 4 × digital, debounced (3 consistent reads @ 10 ms) |
| Outputs | 4 × digital (on/off, push-pull GPIO) |
| Ethernet | 10 Mbps, full-duplex |
| Serial | RS-485 half-duplex, auto-direction transceiver (no DE/RE pin) |
| Protocols | Modbus TCP (port 502) + Modbus RTU, concurrent; mDNS |
| Addressing | DHCP client; static IP fallback configurable |
| ESP32 GPIO | Function | Notes |
|---|---|---|
| 12 | Status LED | single colour; strapping pin (MTDI) — driven after boot |
| 14 | Config-mode button | hold LOW at boot → provisioning |
| 39 | Digital input 1 | input-only pin (external pull on board) |
| 36 | Digital input 2 | input-only pin (external pull on board) |
| 35 | Digital input 3 | input-only pin (external pull on board) |
| 34 | Digital input 4 | input-only pin (external pull on board) |
| 25 | Digital output 1 | |
| 26 | Digital output 2 | |
| 27 | Digital output 3 | |
| 4 | Digital output 4 |
| ESP32 GPIO | ENC28J60 |
|---|---|
| 5 | CS |
| 18 | SCLK |
| 19 | MISO |
| 23 | MOSI |
| N/A | INT (not connected — driver runs in polling mode) |
| ESP32 GPIO | Function |
|---|---|
| 17 | UART2 TX → RS-485 transceiver |
| 16 | UART2 RX ← RS-485 transceiver |
| N/A | DE/RE — none (auto-direction transceiver) |
All 4 inputs are digital. Each is debounced (3 consistent reads at a 10 ms poll interval)
and reported over Modbus as 0 / 1 in its input register.
Each of the 4 outputs is driven from its output register: any non-zero value drives the GPIO high (ON), zero drives it low (OFF). Writes take effect immediately. At boot and during fail-safe the outputs are forced to a defined state.
e02-<wifi_mac_no_colon>.local
(shared device-family prefix; the model TXT distinguishes E04)edge_modbus._tcp.local, port 502TXT records (capability advertisement):
| Key | Example | Meaning |
|---|---|---|
model | e04_modbus | Device model |
fw | 1.0.0 | Firmware version |
i | 4 | Input channels |
o | 4 | Output channels |
unit | 1 | Modbus unit/slave ID |
proto | modbus-tcp | Protocol identifier |
mac | B4E62DDE225D | WiFi MAC (no colons) |
| Parameter | TCP | RTU |
|---|---|---|
| Role | Slave / Server (both run concurrently, shared registers) | |
| Transport | Ethernet, port 502 | RS-485, UART2 |
| Address | Unit ID (MBAP) | Slave address = Unit ID register |
| Default line | — | 9600 baud, 8N1 (configurable) |
| Function codes | 03 (read holding), 06 (write single holding) | |
| Byte order | Big-endian (standard Modbus) | |
RTU baud / parity / stop-bits and the unit/slave id take effect after a reboot (the Modbus controllers are created once at startup).
Read with FC 03, write with FC 06. Layout: configuration block first, then live I/O.
| Addr | Register | Access | Persist | Notes |
|---|---|---|---|---|
| 0 | Unit ID / RTU address | R/W | NVS | 1–247; effective after reboot |
| 1 | Fail-safe output bitmask | R/W | NVS | bits 0–3 → outputs 1–4 |
| 2 | Fail-safe timeout (s) | R/W | NVS | 0 = disabled |
| 3 | RTU enable | R/W | NVS | 0/1; effective after reboot |
| 4 | RTU baud / 100 | R/W | NVS | 96=9600 … 1152=115200 |
| 5 | RTU parity | R/W | NVS | 0=none, 1=odd, 2=even |
| 6 | RTU stop bits | R/W | NVS | 1 or 2 |
| 7 | Input 1 value | R | — | 0 / 1 (debounced) |
| 8 | Input 2 value | R | — | 0 / 1 |
| 9 | Input 3 value | R | — | 0 / 1 |
| 10 | Input 4 value | R | — | 0 / 1 |
| 11 | Output 1 | R/W | — | 0 = OFF, non-zero = ON |
| 12 | Output 2 | R/W | — | 0 / 1 |
| 13 | Output 3 | R/W | — | 0 / 1 |
| 14 | Output 4 | R/W | — | 0 / 1 |
| 15 | Status flags | R | — | bitfield (below) |
| Bit | Mask | Meaning |
|---|---|---|
| 0 | 0x01 | Ethernet link / IP up |
| 1 | 0x02 | Modbus master polled recently (any transport) |
| 4 | 0x10 | Outputs forced to fail-safe |
| 5 | 0x20 | RTU transport enabled |
Bits 2–3 (wire-break) are defined in the shared register layout but are only meaningful on the E02 (4–20 mA) variant; they read 0 on the E04.
| State | LED | Meaning |
|---|---|---|
| Provisioning | Fast blink | Config mode (SoftAP portal active) |
| Initializing | Slow blink | Booting, network not ready |
| Running | Solid ON | Normal operation (Modbus serving) |
Boot sequence: init GPIO + safe outputs (LED slow-blink) → bring up Ethernet, acquire DHCP → start mDNS + Modbus TCP/RTU slaves (LED solid) → enter input-poll loop.
Write configuration registers (0–6) with FC 06. Config values persist to NVS. Transport/serial params (unit id, RTU baud/parity/stop/enable) apply on the next reboot; fail-safe bitmask/timeout and the outputs apply live.
E02-xxxxxx (password edge12345).http://192.168.4.1/ and set unit id, fail-safe (outputs bitmask /
timeout), RS-485 (enable/baud/parity/stop) and optional static IP.Toolchain: ESP-IDF v5.4, target esp32. The E04SD variant is a
compile-time Kconfig choice (CONFIG_BOARD_E04SD=y, in sdkconfig.e04sd).
Managed components (esp-modbus v2.x, mdns, enc28j60) download on first build.
idf.py set-target esp32
idf.py -B build_e04 -DSDKCONFIG=sdkconfig.e04 \
-DSDKCONFIG_DEFAULTS="sdkconfig.defaults;sdkconfig.e04sd" build
idf.py -B build_e04 -p /dev/ttyUSB0 flash monitor
Binary ~979 KB; factory partition 3.88 MB (4 MB flash, no OTA).
| Symptom | Check |
|---|---|
| No IP / not discoverable | Ethernet cable & ENC28J60 wiring (CS5/SCLK18/MISO19/MOSI23); DHCP server present; LED stuck slow-blink = no IP yet |
| TCP master can't connect | Confirm IP (serial log), port 502 open, only the needed master polling |
| RTU no response | RTU enabled (reg 3); matching baud/parity/stop & slave address; A/B lines & ground; UART2 = GPIO17/16 |
| Input always 0 or 1 | GPIO 34–39 need external pull resistors; verify field wiring & signal level |
| Output doesn't switch | Write to registers 11–14; check fail-safe isn't active (status bit 4) |
| Can't enter config mode | GPIO14 must read LOW at boot; LED should switch to fast blink |