← Electroválvulas con máquina de estados en un PLC ESP32
Piso móvil hidráulico (app BLE)ESP32 PLC 38RGPIOBLEControl
Electroválvulas con máquina de estados en un PLC ESP32 — ejemplo completo
Controla electroválvulas hidráulicas con seguridad desde un ESP32 PLC 38R usando una máquina de estados con timeouts. Ejemplo Arduino con salidas de relé.
Programa completo y ejecutable para el ESP32 PLC 38R (load-unload-solenoid-valves-38r.ino): incluye cabecera de conexionado, requisitos y notas de integración.
Descarga el pack completo del proyecto — gratisEste ejemplo + los relacionados + lista de materiales
Vista de solo lectura.
/*
* COMPLETE EXAMPLE — Load/unload solenoid valve control
*
* Hardware: ESP32 PLC 38R (Industrial Shields)
* Based on: hydraulic moving floor project, main.cpp (state machine)
*
* Wiring:
* I0_0 Physical LOAD push button
* I0_1 Physical UNLOAD push button
* I0_2 Physical STOP push button
* R0_1 Main solenoid valve (EVG)
* R0_2 Unload solenoid valve (EVD)
* R0_3 Load solenoid valve (EVC)
* R0_4 Load indicator LED
* R0_5 Unload indicator LED
*
* Logic:
* - Three states: MOTION_LOAD / MOTION_UNLOAD / MOTION_NONE (idle).
* - Each state sets the combination of the 3 solenoid valves and the LEDs
* at a single point in the code (atomic transition, no mixed states).
* - Driven by physical push buttons; in the real project also over
* BLE with [M]1* / [M]2* / [M]0* frames from the mobile app.
* - Safety timeout: a motion never lasts longer than MAX_MOTION_MS.
*
* Integration with other catalog modules:
* - Remote control over BLE: ejemplos/piso-movil/ble-mobile-app-control-38r.ino
* - Overpressure stop with 4-20 mA sensors:
* ejemplos/piso-movil/pressure-temperature-4-20ma-sensors-38r.ino
*/
#define BTN_LOAD I0_0
#define BTN_UNLOAD I0_1
#define BTN_STOP I0_2
#define OUTPUT_EVG R0_1 // main solenoid valve
#define OUTPUT_EVD R0_2 // unload solenoid valve
#define OUTPUT_EVC R0_3 // load solenoid valve
#define LED_LOAD R0_4
#define LED_UNLOAD R0_5
#define MAX_MOTION_MS 30000 // a motion never lasts longer than 30 s
enum Motion { MOTION_NONE, MOTION_LOAD, MOTION_UNLOAD };
Motion motion = MOTION_NONE;
uint32_t motionStartMs = 0;
// The only point in the code that touches the solenoid valves:
// impossible to end up in a mixed load+unload state.
void setMotion(Motion m) {
motion = m;
motionStartMs = millis();
switch (m) {
case MOTION_LOAD: // load: EVC + EVG open
digitalWrite(OUTPUT_EVC, HIGH);
digitalWrite(OUTPUT_EVD, LOW);
digitalWrite(OUTPUT_EVG, HIGH);
digitalWrite(LED_LOAD, HIGH);
digitalWrite(LED_UNLOAD, LOW);
Serial.println("State: LOAD");
break;
case MOTION_UNLOAD: // unload: EVD + EVG open
digitalWrite(OUTPUT_EVC, LOW);
digitalWrite(OUTPUT_EVD, HIGH);
digitalWrite(OUTPUT_EVG, HIGH);
digitalWrite(LED_LOAD, LOW);
digitalWrite(LED_UNLOAD, HIGH);
Serial.println("State: UNLOAD");
break;
default: // idle: everything closed
digitalWrite(OUTPUT_EVC, LOW);
digitalWrite(OUTPUT_EVD, LOW);
digitalWrite(OUTPUT_EVG, LOW);
digitalWrite(LED_LOAD, LOW);
digitalWrite(LED_UNLOAD, LOW);
Serial.println("State: IDLE");
}
}
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)");
}
void loop() {
// Physical push buttons with edge detection
static bool prevLoad = false, prevUnload = false, prevStop = false;
bool load = digitalRead(BTN_LOAD);
bool unload = digitalRead(BTN_UNLOAD);
bool stop = digitalRead(BTN_STOP);
if (stop && !prevStop) setMotion(MOTION_NONE);
else if (load && !prevLoad && motion == MOTION_NONE)
setMotion(MOTION_LOAD);
else if (unload && !prevUnload && motion == MOTION_NONE)
setMotion(MOTION_UNLOAD);
prevLoad = load; prevUnload = unload; prevStop = stop;
// Safety: no motion can stay active indefinitely
if (motion != MOTION_NONE && millis() - motionStartMs > MAX_MOTION_MS) {
Serial.println("Motion TIMEOUT -> automatic stop");
setMotion(MOTION_NONE);
}
delay(20);
}
Descarga el pack completo del proyecto — gratisEste ejemplo + los relacionados + lista de materiales