Skip to Content

← All functionalities

Hydraulic moving floor (BLE app)ESP32 PLC 38RGPIOBLEControl

Safe solenoid valve sequencing on an ESP32 PLC with a state machine

Three solenoid valves and two directions of motion can produce dangerous combinations if outputs are toggled from scattered places in the code. This ESP32 PLC valve control example, distilled from a real mobile hydraulic machine deployment, funnels every actuation through a single state machine: load, unload or idle. Each state sets all three relay outputs and the indicator LEDs atomically, so a mixed load-plus-unload condition simply cannot exist in the firmware.

One function owns the outputs

The setMotion() function is the only place in the entire firmware where the general, load and unload valve outputs are written. Buttons, BLE commands and safety timeouts all request a state instead of touching pins directly, and every state writes all five outputs in one block. This makes the valve truth table reviewable at a glance and turns "why did both valves open at once?" from a debugging nightmare into an impossible question.

Physical buttons and remote control coexist

The example wires load, unload and stop push buttons with simple edge detection, while the production machine accepts the same three transitions over BLE as [M]1*, [M]2* and [M]0* frames sent from a smartphone app. Because both input paths converge on the same state machine, remote and local control can never disagree about what the valves are doing — and the physical stop button always works, even with the app connected.

Timeouts as a safety net

A hydraulic movement that never ends usually means a stuck command, a lost BLE connection or an operator who walked away. Every state change records its start time, and any motion older than 30 seconds is forced back to idle automatically, no acknowledgment required. Combined with the overpressure stop from the 4-20 mA sensor module in this series, the firmware always fails toward the safe condition: every valve closed.

A snippet from the implementation

Straight from the example as deployed on the ESP32 PLC 38R — copy it freely:

void setup() {
  Serial.begin(115200);

  pinMode(BTN_LOAD, INPUT);
  pinMode(BTN_UNLOAD, INPUT);
  pinMode(BTN_STOP, INPUT);
  pinMode(OUTPUT_EVG, OUTPUT);
  pinMode(OUTPUT_EVD, OUTPUT);
  pinMode(OUTPUT_EVC, OUTPUT);
  pinMode(LED_LOAD, OUTPUT);
  pinMode(LED_UNLOAD, OUTPUT);

  setMotion(MOTION_NONE);   // always start in safe idle
  Serial.println("Solenoid valve control ready (ESP32 PLC 38R)");
}

The full example is a complete program — wiring header, setup and main loop — ready to adapt to your application.

Frequently asked questions

Can the ESP32 PLC 38R drive solenoid valves directly?

Yes, its relay outputs switch typical 12/24 V DC hydraulic solenoid coils directly. Check the coil current against the relay rating and add flyback suppression for inductive loads if not already fitted.

Why use a state machine instead of toggling outputs directly?

Because every output combination becomes explicit and reviewable. With direct toggling, two code paths can disagree and leave conflicting valves open; with a state machine, illegal combinations are unreachable by construction.

How do I add a new movement, like a slow-speed mode?

Add a new enum value and one case in setMotion() defining its exact valve combination. No other code changes — buttons or BLE commands just request the new state.

Related functionalities