Skip to content
Tutorial
16 min read
October 17, 2026

ESP32 Relay Control over MQTT with State Feedback

Control relay channels from MQTT with separate command and reported-state topics. Define a safe startup policy, validate commands, handle retained messages carefully and test the relay controller with low-voltage loads.

ESP32 Relay Control over MQTT with State Feedback

An MQTT command that says ON is a request, not confirmation that a relay changed. This project defines separate command and state topics for an ESP32 relay controller, validates received messages and publishes the state firmware applied. The same topic contract can scale from one output to an 8-channel board.

The code and workflow here are a starting point for a low-voltage test setup. Check the exact relay module's input polarity, driver requirements, isolation and ratings before connecting any real load. Do not treat generic module labels as proof of mains safety.

Image pending: Image placeholder: Node-RED or MQTT client sends channel command to ESP32 relay controller; firmware publishes applied state on a separate topic.

1. Use predictable command and state topics

For an eight-channel controller, use separate topics such as:

  • solderhub/lab/relaybox01/command/channel/1
  • solderhub/lab/relaybox01/state/channel/1
  • solderhub/lab/relaybox01/status

Repeat the channel path for the other outputs. Explicit per-channel topics are easy to subscribe to and authorize. An alternative is a documented JSON command containing a channel and desired state, but the firmware must validate the channel range and payload schema before acting.

Use ON/OFF or numeric desired state rather than a toggle-only command. A repeated ON command should leave an output ON rather than switch it back OFF.

Image pending: Image placeholder: topic tree for eight relay channels with command/state pairs and a separate controller availability topic.

2. Establish safe startup and polarity

Confirm whether the relay input is active LOW or active HIGH from the module documentation or a low-voltage test. Configure each output to its intended safe state before network connection is attempted. For many applications this is OFF, but the correct state must be decided for the actual process and load.

Do not connect mains voltage to a breadboard or exposed low-voltage test setup. Use a suitably rated interface, enclosure and protection, and follow local electrical requirements. Local safety logic should continue if Wi-Fi or the broker fails.

Image pending: Image placeholder: low-voltage ESP32-to-relay input wiring and bench LED test, with active-level logic called out. No exposed mains wiring.

3. Core MQTT command validation pattern

This small callback illustrates the command contract; integrate it into your board's full Wi-Fi/MQTT lifecycle and configure the actual channels based on the relay hardware. Avoid executing blocking work inside the callback. A production 8-channel implementation should use an explicit channel allow-list rather than indexing arbitrary user-provided numbers.

C++

The example intentionally leaves relayPins and relayActiveLow to your verified hardware map. Do not paste it as a complete sketch without defining those arrays, initializing every pin and implementing MQTT authentication/reconnection. A channel identifier from a topic must be parsed and checked before indexing the arrays.

Image pending: Image placeholder: code view highlighting an explicit channel-to-GPIO map, active-low configuration and distinct reported-state publication.

4. Retained state and reconnect behavior

Retaining the reported state lets a new subscriber learn the controller's last reported state after subscribing. The command topic should generally remain non-retained unless you have an explicit desired-state policy and have analyzed replay at boot/reconnect.

On startup, initialize outputs safely, connect to MQTT, subscribe to command topics and publish the current output state. On reconnect, resubscribe and reconcile state. If the device reports the commanded GPIO level, label that indicator as firmware-applied state. Independent confirmation of relay contacts needs suitable feedback hardware.

Image pending: Image placeholder: state diagram covering boot-safe OFF, MQTT connected, command validated, GPIO updated, state published and broker disconnect.

5. Commission the controller before real loads

Use one channel and a low-voltage indicator first. Test valid ON/OFF, unexpected payloads, an invalid channel number, repeated identical commands, broker outage, controller restart and new dashboard subscription. Expand to all eight channels only after the mapping is verified. Record board and relay module model, GPIO assignment, input polarity and expected startup state.

Ensure broker ACLs limit who can publish commands. A sensor account should not automatically have permission to activate relay topics. The dashboard must distinguish command request, controller availability and reported output state.

Image pending: Image placeholder: commissioning checklist with one low-voltage test load, channel mapping and command/state/restart test cases.

Signal In

Built from what makers search for

The lookups piling up in SolderHub's search bar every day shape what we publish next — new component pages, board guides, and firmware notes, sent out as they go live.

By subscribing you agree to our Privacy Policy. Unsubscribe anytime.