cycle_machine.ino
Le patron automate à états d'un programme Arduino : cycle marche → temporisation → pause → fin, sans delay bloquant, avec arrêt prioritaire. Transposable à toute séquence industrielle (dosage, convoyeur, presse) en changeant les temps.
Matériel requis
Une Opta PLC STMicroelectronics (STM32H747 temps réel + coprocesseur sécurisé i.MX RT1052) programmée avec l'environnement Arduino PLC, alimentée en 24 V DIN. Bouton NO sur IN1, bouton NF sur IN2, contacteur moteur sur RO1, voyant sur RO2.
Câblage
Boutons 24 V vers IN1/IN2 (COM au 0 V) ; RO1 via un contacteur de puissance et protection thermique, RO2 vers voyant 24 V.
Fonctionnement
Une machine à états énumère les phases ; millis() pilote les temporisations sans bloquer la boucle ; l'arrêt NF force l'état ARRET à chaque tour, donc coupure immédiate.
Exécution
Installez le gestionnaire de cartes Arduino PLC, sélectionnez « Opta PLC », câblez en USB/DFU puis téléversez. Le programme tourne sur le STM32H747 côté temps réel.
Variantes
Ajouter un compteur de cycles vers MQTT, un échantillonnage du courant moteur (AI) pour détecter un bourrage, ou un mode pas-à-pas.
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);
}