Mon niveau Arduino comporte essentiellement la lecture d'entrée et activation de sortie basique.
Mais ici, j'ai un projet de machine demandant un minimum de sécurité lors de la fermeture des mâchoires de test.
Voici la démarche:
Appuis sur 2 BP en même temps
Les mâchoires se ferment (temps de fermeture 2 secondes )
Tant que les 2 BP sont enfoncé, décompte du temps (millis)
Les mâchoires se ferment toujours (temps de fermeture 2 secondes )
Si les 2 secondes sont écoulés, on peut relâcher les BP
les mâchoires restent fermées
Je galère complètement!
J'ai fais quelques tests avec des morceaux de programme trouvé un peu partout (notamment sur ce forum je pense)
Mais je ne parviens pas a lui faire faire ce que je souhaite
Premiers essais avec un seul BP
Lors du maintient, la sortie est inactive, je la voudrais active
Voici le code actuel :
const byte Ferm = 24; // Poussoir Fermeture
const byte V10 = 16; // Vanne electrique 10 pour machoire
const byte Ouv = 25; // Poussoir Ouverture
const unsigned long duree = 2000ul;
unsigned long chrono = 0;
bool etatPrecedent = HIGH;
void setup() {
pinMode(Ferm,INPUT_PULLUP);
pinMode(V10,OUTPUT);
pinMode(Ouv, INPUT_PULLUP);
}
void loop() {
bool etatFerm = digitalRead (Ferm); // lecture du poussoir Ferm
if (!etatFerm) { // bouton enfoncé // condition départ chrono
if (etatPrecedent) { // on vient d'enfoncerle bouton
chrono = millis(); // on lance le chrono
delay(30); // debounce button
}
if (millis() - chrono > duree){ // condition duréee impulsion
digitalWrite(V10,HIGH); // la led de la vanne V10 s'allume
}
}
etatPrecedent = etatFerm ;
bool etatOuv = digitalRead (Ouv); // lecture du poussoir Ouv
if (!etatOuv) { // bouton enfoncé
digitalWrite(V10,LOW); // la led de la vanne V10 s'eteind
}
}
Je sèche J'avais également essayé avec 2 poussoirs simultané, mais ca ne fonctionnait pas
Top, je suis tombé dessus juste avant ta réponse.
C'est tout nouveau pour moi ce genre de séquence.
Je vais faire quelques test et repasserai pour donner des nouvelles
Par l'état "en cours" je veux représenter le fait que les sorties pilotant mes vérins soient activent (fermeture mâchoires) pendant le temps chronométré.
Si poussoirs lâché trop tôt, les sortis vérins se désactivent.
Est-ce que le diagramme semble bon au moins a votre avis?
A mon avis, il y a des transitions complexes qui ne servent à rien.
Par exemple pourquoi com+ferm enfoncé depuis 2s, il suffit de mettre tempo échue puisque com ou ferm relaché est traité dans une autre transition.
Le diagramme se simplifie:
Peut être que le diagramme est un peu trop simplifié car si on relâche un bouton pendant la fermeture on passe dans l'état "Mâchoire ouverte verrouillée" alors que la mâchoire est à moitié fermée.
Hmm...
Je ne vois plus trop a quoi devrait ressembler le diagramme du coup. Surtout pour le moment de relâchement des poussoirs trop rapide
Que je comprenne bien la maniere de coder une machine d'état:
Le truc c'est de fonctionner qu'avec des "Case" et chaque évènement fait appel a un des case en fonction des conditions remplies ou non pour l'activer
si BP1 enfoncé et BP2 enfoncé --> fermer
début chrono
si (BP1 relâché ou BP2 relâché) et (chrono < délais voulu) --> ouvrir
sinon si (BP1 enfoncé et BP2 enfoncé) et (chrono >= délais voulu) --> fermer
Fermer et ouvrir seront activés via le switch
Mais je ne suis pas certain que ca permettra d'ouvrir les mâchoires si je relâche trop tôt
Peut être commencer par des noms de variable plus évocateurs :
pour ferm et ouv j'aurais mis bouton1 bouton2
bool etatFerm;
void setup() {
pinMode(pinBTN1,INPUT_PULLUP);
pinMode(V10,OUTPUT);
pinMode(pinBTN2, INPUT_PULLUP);
}
void loop() {
bool bouton1= !digitalRead (pinBTN1); // lecture du poussoir 1
bool bouton2= !digitalRead (pinBTN2); // lecture du poussoir 2
if (bouton1 && bouton2 || etatFerm) { // les 2 boutons enfoncés ou etatFerm
chrono = millis(); // on lance le chrono
digitalWrite(V10,HIGH); // la led de la vanne V10 s'allume
}
else { digitalWrite(V10,LOW); // la led de la vanne V10 s'éteint
etatFerm = false;
}
if (millis() - chrono > duree){ // condition durée impulsion
etatFerm = true; // la led de la vanne V10 est maintenue allumée
}
}
La solution de achess me parle plus que les machines a états qui est, pour le moment, plus complexe pour ma compréhension.
J'ai remanié un peu ce code pour inclure l'ouverture sous condition du délais aussi:
int V1 = 13;
bool Etat_Mach = false;
int Com = 31; // Poussoir Commun
int Ferm = 24; // Poussoir Fermeture
int Ouv = 25; // Poussoir Ouverture
unsigned long chrono; // attention, type unsigned long comme millis()
const unsigned long duree = 15000ul; // 15 secondes (le ul à la fin pour unsigned long)
void setup() {
// Sorties Vannes:
digitalWrite(V1, LOW);
pinMode(V1, OUTPUT);
pinMode(Com,INPUT_PULLUP);
pinMode(Ferm, INPUT_PULLUP);
}
void loop() {
bool Etat_Com= digitalRead (Com); // lecture du poussoir Com
bool Etat_Ferm= digitalRead (Ferm); // lecture du poussoir Ferm
bool Etat_Ouv= digitalRead (Ouv); // lecture du poussoir Ouv
// Fermeture
if (Etat_Com && Etat_Ferm || Etat_Mach) { // les 2 boutons enfoncés ou etatFerm
chrono = millis(); // on lance le chrono
digitalWrite(V1,HIGH); // la led de la vanne V1 s'allume
}
else { digitalWrite(V1,LOW); // la led de la vanne V1 s'éteint
Etat_Mach = false;
}
if (millis() - chrono > duree){ // condition durée impulsion
Etat_Mach = true; // la led de la vanne V10 est maintenue allumée
}
// Ouverture
if (Etat_Com && Etat_Ouv || Etat_Mach) { // les 2 boutons enfoncés ou etatFerm
chrono = millis(); // on lance le chrono
digitalWrite(V1,LOW); // la led de la vanne V1 s'eteint
}
else { digitalWrite(V1,HIGH); // la led de la vanne V1 s'allume
Etat_Mach = true;
}
if (millis() - chrono > duree){ // condition durée impulsion
Etat_Mach = false; // la led de la vanne V10 est maintenue éteinte
}
}
c'est aussi une machine à état: il écoute les évènements et traite ce qui est nécessaire
Attention aux rebonds des boutons dans
if (bouton1 && bouton2 || etatFerm) { // les 2 boutons enfoncés ou etatFerm
chrono = millis(); // on lance le chrono
digitalWrite(V10, HIGH); // la led de la vanne V10 s'allume
}
else {
digitalWrite(V10, LOW); // la led de la vanne V10 s'éteint
etatFerm = false;
}
qui risquent d'envoyer une rafale d'ordres ON/OFF à votre Vanne electrique. (sur la LED ça ne va pas se voir à l'oeil nu)
Dans votre code vous devez différencier les états (ouverts ou fermés) car sinon le test sur les 2 boutons est le même. (➜ machine à état )
J'ai essayé de faire fonctionner le programme de achess, mais je ne comprend pas pourquoi celui-ci reste coincé dans le else et valide jamais la condition :
if ((millis() - chrono) > duree)
chrono ne prend pas une photo de millis(), il est en permanence mis a jour et du coup il n'y a pas l'écart suffisent entre millis() et chrono pour valider cette condition
// Vannes:
int V1 = 13; // vanne 1 de mise sous pression machine ( pas utilisée dans code )
int V9 = 15; // vanne piston
int V10 = 16; // vanne retour piston
// Entrées:
int Com = 31; // Poussoir Commun
int Ferm = 24; // Poussoir Fermeture
int Ouv = 25; // Poussoir Ouverture
// Internes:
bool Etat_Mach = false;
unsigned long chrono; // attention, type unsigned long comme millis()
const unsigned long duree = 2000ul; // 2 secondes (le ul à la fin pour unsigned long)
void setup() {
// Sorties Vannes:
digitalWrite(V1, LOW);
pinMode(V1, OUTPUT);
digitalWrite(V9, LOW);
pinMode(V9, OUTPUT);
digitalWrite(V10, LOW);
pinMode(V10, OUTPUT);
// Entrées:
pinMode(Com,INPUT_PULLUP);
pinMode(Ferm, INPUT_PULLUP);
}
void loop() {
bool Etat_Com= !digitalRead (Com); // lecture du poussoir Com
bool Etat_Ferm= !digitalRead (Ferm); // lecture du poussoir Ferm
// Fermeture
if ((Etat_Com && Etat_Ferm) || Etat_Mach) { // les 2 boutons enfoncés ou etatFerm
delay(10);
chrono = millis(); // on lance le chrono
digitalWrite(V1,HIGH); // la led de la vanne V1 s'allume
if ((millis() - chrono) > duree){ // condition durée impulsion
Etat_Mach = true;
digitalWrite(V9, HIGH); // J'allume la led de la V9 comme témoin
}
}
else {
digitalWrite(V1,LOW); // la led de la vanne V1 s'éteint
Etat_Mach = false;
digitalWrite(V10, HIGH); // J'allume la led de la V10 comme témoin
}
}
le comportement de ceci:
La V10 est allumée dès le début du programme
La V1 s'allume quand j'enfonce Com et Ferm et s'éteint quand je relâche mais après le délais, la V1 n'est pas maintenue active
Je ne vois pas vraiment ce que je rate ici.
Comment faire pour ne pas rester dans ce else
Ne faudrait-il pas plutot controler un changement d'état des poussoirs plutot que si ils sont enfoncés ou relaché?
Tant qu'ils sont enfoncés millis() est enregistré dans chrono
Mais si je passe par un changement d'état des poussoirs, ca devrait regler le problème, non?
Exactement, elles restent en position.
Si on appuie a nouveau sur les 2 boutons Com et Ferm, on relance la fermeture avec contrôle de délais (même délais de 2s)
Pour ouvrir les mâchoires on aurait exactement les mêmes instructions que la fermeture, mais avec les boutons Com et Ouv
Le comportement a l'ouverture sera le même que pour l'ouverture
J'espère que la problématique est un peu plus claire