cycle_machine.ino
El patrón de autómatas de máquina de estados en Arduino: marcha → temporización → pausa → fin, sin delay bloqueante y con parada prioritaria. Transponible a cualquier secuencia industrial (dosificación, transportador, prensa) cambiando los tiempos.
Hardware
Una Opta PLC de STMicroelectronics (STM32H747 en tiempo real + coprocesador seguro i.MX RT1052) programada con el entorno Arduino PLC, alimentada a 24 V DIN. Botón NO en IN1, botón NC en IN2, contactor de motor en RO1, testigo en RO2.
Cableado
Botones 24 V a IN1/IN2 (COM al 0 V); RO1 mediante contactor de potencia con protección térmica, RO2 a testigo de 24 V.
Funcionamiento
Una máquina de estados enumera las fases; millis() gestiona las temporizaciones sin bloquear el bucle; la parada NC fuerza ARRET en cada vuelta, corte inmediato.
Ejecución
Instala el gestor de placas Arduino PLC, selecciona «Opta PLC», conecta USB/DFU y vuelca el programa. El sketch corre por el STM32H747 en tiempo real.
Variantes
Añadir contador de ciclos por MQTT, muestreo de corriente del motor (AI) para detectar atascos, o modo paso a paso.
cycle_machine.ino
// Opta PLC : cycle automatique — marche/arrêt, temporisations non bloquantes.
// IN1=Marche (NO), IN2=Arrêt (NF), RO1=moteur, RO2=voyant marche.
#include "PLCContainer.h"
PLCContainer PLC;
enum Etat { ARRET, MOTEUR, ATTENTE, RETOUR };
Etat etat = ARRET;
unsigned long tEtat = 0;
const unsigned long T_MOTEUR = 5000; // moteur tourne 5 s
const unsigned long T_ATTENTE = 2000; // pause 2 s
void setup() {
Serial.begin(115200);
PLC.begin();
PLC.DigitalIn.setMode(OPTA_IN_1, PLCDigitalIn::PULL_UP);
PLC.DigitalIn.setMode(OPTA_IN_2, PLCDigitalIn::PULL_UP);
}
bool marche() { return !PLC.DigitalIn.read(OPTA_IN_1); } // NO -> 0 au clic
bool arret() { return PLC.DigitalIn.read(OPTA_IN_2); } // NF -> 0 si ouvert
void eteint() { PLC.Relay[0].off(); PLC.Relay[1].off(); }
void loop() {
if (arret()) { etat = ARRET; } // l'arrêt prime sur tout
switch (etat) {
case ARRET:
eteint();
if (marche()) { etat = MOTEUR; tEtat = millis();
PLC.Relay[0].on(); PLC.Relay[1].on();
Serial.println("Cycle : MOTEUR"); }
break;
case MOTEUR:
if (millis() - tEtat > T_MOTEUR) {
PLC.Relay[0].off(); etat = ATTENTE; tEtat = millis();
Serial.println("Cycle : ATTENTE"); }
break;
case ATTENTE:
if (millis() - tEtat > T_ATTENTE) {
etat = ARRET; Serial.println("Cycle : FIN"); }
break;
}
delay(2);
}