Completado
-
Sin categorizar
-
- Cuestionario
-
- Cuestionario
-
- Cuestionario
-
- Cuestionario
-
- Cuestionario
-
- Cuestionario
-
- Cuestionario
Structuring PLC logic in Arduino C++: state machines instead of long loops
A single loop() that keeps growing with if statements becomes unreadable and hard to debug fast. In this course you will build one project from start to finish: the control of a pump station with a tank. In this first lesson you give it a solid structure with a state machine, the pattern most PLC logic in Arduino C++ eventually needs.
What you will learn
- Replace nested ifs with named states and explicit transitions.
- Write a three-state machine with a safe way out of a fault.
- Decide when a new condition deserves a new state.
The project: a start button on I0_0, an emergency stop on I0_1, a pump contactor on Q0_0 and an alarm beacon on Q0_1. Later lessons add the tank level, timing, Modbus, memory, a watchdog and a dashboard.
Why a long loop() breaks down
As a sketch grows, one big loop() checking dozens of conditions becomes hard to read, hard to test and easy to break with an unrelated change. A state machine gives your program a small set of named states and clear rules for moving between them.
The pump station as a state machine
enum State { IDLE, RUNNING, FAULT };
State currentState = IDLE;
void setup() {
pinMode(I0_0, INPUT); // start button
pinMode(I0_1, INPUT); // emergency stop
pinMode(Q0_0, OUTPUT); // pump contactor
pinMode(Q0_1, OUTPUT); // alarm beacon
digitalWrite(Q0_0, LOW);
digitalWrite(Q0_1, LOW);
}
void loop() {
switch (currentState) {
case IDLE:
digitalWrite(Q0_0, LOW);
if (digitalRead(I0_0) == HIGH) {
currentState = RUNNING;
}
break;
case RUNNING:
digitalWrite(Q0_0, HIGH);
if (digitalRead(I0_1) == HIGH) {
currentState = FAULT;
}
break;
case FAULT:
digitalWrite(Q0_0, LOW);
digitalWrite(Q0_1, HIGH);
if (digitalRead(I0_1) == LOW && digitalRead(I0_0) == HIGH) {
digitalWrite(Q0_1, LOW);
currentState = IDLE;
}
break;
}
}
Each case is exactly one state, and a state only changes inside its own case, which makes it easy to trace how the machine went from IDLE to FAULT. Note the way out of FAULT: the machine only returns to IDLE when the emergency stop is released and the operator presses start again as an acknowledgement. A fault state with no exit is a common design mistake.
Expected result: pressing I0_0 turns on Q0_0, activating I0_1 turns it off and lights Q0_1, and the system is armed again only after releasing I0_1 and acknowledging with I0_0.
Visualizing the states and transitions
When to add a new state instead of a new if
If you ask what mode the machine is in right now and the answer depends on three other variables, that combination is probably a missing state. A new condition is a signal for a new state, not another nested if inside an existing one.
States and the PLC scan cycle
Unlike a traditional PLC scan, an Arduino loop() runs as fast as the code allows, with no fixed scan time by default. A state machine does not change that, but it makes each pass predictable: read inputs, evaluate the current state, set outputs, move on.
Go deeper
- Arduino PLC vs ESP32 PLC vs Raspberry Pi PLC: which to choose
- 8 signs your prototype isn't production ready
Next lesson: timing without blocking, so the pump station can wait and still react. Take the quiz below first.
No hay comentarios por ahora.