Optimisation et aide [Lavage Camion] [Projet Abandonné mais peut servir]

Bonjour a tous ,
Je souhaiterais savoir s’il y a moyen d’optimiser mon code ? Ou si vous avez des sugguestion pour m’aider a m’améliorer dans ma création ^^

Alors le principe est simple , 1 brosse sur le dessus ,1 a gauche, une a droite, nous avons 1 fin de course (FDC) pour le debut de la piste , 1 fin de course pour la position au repos des brosse (1 sur la brosse du haut quand elle est tout en haut, 1 sur la brosse de droite quand elle est tout a droite et 1 sur la brosse de gauche quand elle est toute à gauche).

Au départ je fais tourner les brosses dans un sens pour “Nettoyer et egoutter les brosses” ensuite le portique avance un peu , je descend et serres mes brosses , ensuite j’avance en injectant de l’eau , le portique va jusqu’a bout du camion avec une tempo , la brosse du haut descend sur les portes arrieres du camion puis remonte jusqu’en haut.

Le portique fait ensuite le cycle inverse et ce remet en attente du bouton marche

Voici mon code :

#define BHD 5 // Brosse Haut descente
#define BHM 6 // Brosse Haut Montée
#define RETOUR 7 // Retour du portique
#define AVANCE 8 // Avance du portique
#define BDS 9 // Brosse Droit Serrage
#define BDDS 10 // Brosse Droit Déserrage
#define BGS 3 // Brosse Gauche Serrage
#define BGDS 4 // Brosse Gauche Déserrage
#define EAU 11 // Alimentation Eau
#define SAVON 12 // Alimentation SAVON
#define BTAV 13 // Alimentation Brosse tourne en avant
#define BTAR 2 // Alimentation Brosse tourne en avant

#define FDCR A0 // Fin de course retour
#define FDCA A1 // Fin de course Avance
#define FDCBH A2 // Fin de course brosse Haute
#define FDCBG A3 // Fin de course brosse Gauche
#define FDCBD A4 // Fin de course brosse Droit
#define MES A5 // Bouton Mise en service

int BoutonMES = 0; // Bouton de mise en marche
int Verification = 0;
int FinEtape1 = 0;
int FinEtape2 = 0;
int FinEtape3 = 0;

unsigned long currentTime = 0;

void setup() {
  Serial.begin(9600);
  Serial.println("Initialisation");
  pinMode(BHD, OUTPUT);
  pinMode(BHM, OUTPUT);
  pinMode(RETOUR, OUTPUT);
  pinMode(AVANCE, OUTPUT);
  pinMode(BDS, OUTPUT);
  pinMode(BDDS, OUTPUT);
  pinMode(BGS, OUTPUT);
  pinMode(BGDS, OUTPUT);
  pinMode(EAU, OUTPUT);
  pinMode(SAVON, OUTPUT);
  pinMode(BTAV, OUTPUT);
  pinMode(BTAR, OUTPUT);
  Serial.println("Etape 1 : PIN OUT INITIALISE");


  pinMode(FDCR, INPUT_PULLUP);
  pinMode(FDCA, INPUT_PULLUP);
  pinMode(FDCBH, INPUT_PULLUP);
  pinMode(FDCBG, INPUT_PULLUP);
  pinMode(FDCBD, INPUT_PULLUP);
  pinMode(MES, INPUT_PULLUP);
  Serial.println("Etape 2 : PIN ENTREE INITIALISE");

}

void loop() {
  // On éteint tout les relais a chaque debut de programme pour eviter les problèmes
  digitalWrite(BHD, LOW);
  digitalWrite(BHM, LOW);
  digitalWrite(RETOUR, LOW);
  digitalWrite(AVANCE, LOW);
  digitalWrite(BDS, LOW);
  digitalWrite(BDDS, LOW);
  digitalWrite(BGS, LOW);
  digitalWrite(BGDS, LOW);
  digitalWrite(EAU, LOW);
  digitalWrite(SAVON, LOW);
  digitalWrite(BTAV, LOW);
  delay(3000);
 Verif();;
 Etape1();
 Etape2();
 Etape3();
}


void Verif() {
  if (Verification == 0) {
    
    Serial.println("Verification du FDC Brosse du haut");
    do {
    digitalWrite(BHM, HIGH);
    }
      while (digitalRead(FDCBH) == HIGH);
        digitalWrite(BHM, LOW);
        Serial.println("Brosse du haut en place");  

    Serial.println("Verification du FDC Brosse de droite");
    do {
    digitalWrite(BDDS, HIGH);
    }
    while (digitalRead(FDCBD) == HIGH);
      digitalWrite(BDDS, LOW);
      Serial.println("Brosse de droite en place");  
  
    Serial.println("Verification du FDC Brosse de gauche");
    do {
    digitalWrite(BGDS, HIGH);
    }
    while (digitalRead(FDCBG) == HIGH);
      digitalWrite(BGDS, LOW);
      Serial.println("Brosse de droite en place");  
  
    Serial.println("Verification du FDC RETOUR");
    do {
    digitalWrite(RETOUR, HIGH);
    }
    while (digitalRead(FDCR) == HIGH);
      digitalWrite(RETOUR, LOW);
      Serial.println("En place");

      
  Verification = 1; // Verrouillage de la verification
  }   
}


void Etape1() { //Avance avec savon et eau + brosse
   
  if (Verification == 1 && BoutonMES == 0) {
  Serial.println("Attente du bouton poussoir");
    
     if (digitalRead(MES) == LOW) { // Lecture du bouton de mise en marche
      
      BoutonMES = 1;
      Serial.println("");
      Serial.println("Demarrage du programme");
       currentTime = millis() + 5000;
       do{
      digitalWrite(BTAV, HIGH);
       } while ((currentTime > millis()));
      
       
        Serial.println("");
        Serial.println("1 - Avance du portique"); 
      currentTime = millis() + 5000; // ------TIMER ICI
       do {
        digitalWrite(BTAV, LOW);
        digitalWrite(AVANCE, HIGH);
       } while ((currentTime > millis()));
         

        Serial.println("");
        Serial.println("2 - On allume l'eau");
       currentTime = millis() + 3000; // ------TIMER ICI
       do {
         // On fait avancer le portique pendant 10 secs ensuite code suivant
        digitalWrite(AVANCE, LOW);
        digitalWrite(EAU, HIGH);
      } while ((currentTime > millis()));
    
       currentTime = millis() + 5000; // ------TIMER ICI
       do {
        digitalWrite(BTAV, HIGH);
       } while ((currentTime > millis()));

    Serial.println("Descente brosse");
        while (digitalRead(FDCBH) == LOW) { // Si le FDCH est activer on descend
          digitalWrite(BHD, HIGH);
        }
        digitalWrite(BHD, LOW);

    Serial.println("Serrage brosse Droit");
        while (digitalRead(FDCBD) == LOW) { // Si le FDC Brosse Droit est activer on serre
          digitalWrite(BDS, HIGH);
        }
        digitalWrite(BDS, LOW);

       Serial.println("Serrage brosse gauche");
        while (digitalRead(FDCBG) == LOW) { // Si le FDC Brosse Gauche est activer on serre
          digitalWrite(BGS, HIGH);
        }
        digitalWrite(BGS, LOW);
        Serial.println("");
        Serial.println("3 - Avance portique");
        
      currentTime = millis() + 5000; // ------TIMER ICI
      do {
       digitalWrite(AVANCE, HIGH);
      } while ((currentTime > millis()));
        Serial.println("");
        digitalWrite(AVANCE, LOW); 
      Serial.println("FIN ETAPE 1"); // ----------- FIN ETAPE 1 ----------- 
      FinEtape1 = 1;
     }    
    }
   
}

void Etape2() {
  if(FinEtape1 == 1) {
      Serial.println("ETAPE 2"); // ----------- FIN ETAPE 1 ----------- 
      Serial.println("2.1 - On descend la brosse jusqu'en bas pour nettoyer les portes arrieres");
      currentTime = millis() + 3000; // ------TIMER ICI
      do {
       digitalWrite(BHD, HIGH);
      } while ((currentTime > millis()));
      digitalWrite(BHD, LOW);
      digitalWrite(EAU, LOW);
      digitalWrite(BTAV, LOW); // On arrete la rotation de la brosse en avant
      digitalWrite(BTAR, HIGH); // On démarre la rotation de la brosse en arriere
      
      Serial.println("2.2 - REMONTE JUSQU'AU FIN DE COURSE");
      do {
       digitalWrite(BHM, HIGH);
      } while (digitalRead(FDCBH) == HIGH);
      digitalWrite(BHM, LOW);

      Serial.println("2.3 - ON REDESCEND LA BROSSE SUR LE TOIT DE LA SEMI");
      do {
       digitalWrite(BHD, LOW);
      } while (digitalRead(FDCBH) == LOW);

      digitalWrite(BHD, HIGH);
      digitalWrite(EAU, HIGH);
      FinEtape2 = 1;
  }
}

void Etape3(){
  if(FinEtape2 == 1) {
  Serial.println("ETAPE 3"); // ----------- FIN ETAPE 2 ----------- 
  Serial.println("3 - On retourne jusqu'a la bute du portique");
  do {
    digitalWrite(RETOUR, HIGH);
  } while (digitalRead(FDCR) == HIGH);
  digitalWrite(RETOUR, LOW);
  Serial.println("FINALE");
  Serial.println("3.1 - On arrete tout les relais");
  digitalWrite(BHD, LOW);
  digitalWrite(BHM, LOW);
  digitalWrite(AVANCE, LOW);
  digitalWrite(BDS, LOW);
  digitalWrite(BDDS, LOW);
  digitalWrite(BGS, LOW);
  digitalWrite(BGDS, LOW);
  digitalWrite(EAU, LOW);
  digitalWrite(SAVON, LOW);
  digitalWrite(BTAV, LOW);
  digitalWrite(BTAR, LOW);
  Serial.println("3.1 - On passe la verification a zero et on attend le prochain cycle");
  FinEtape1 = 0;
  FinEtape2 = 0;
  Verification = 0;
  
  }
}

Merci en tout cas a ceux qui prendrons le temps de lire.

En vous remerciant d’avance

Quelques remarques constructives, pas des bugs majeurs

il n’y a pas besoin je suppose de demander aux pins d’être mise constamment à HIGH en attendant un fin de course. Au lieu de

do {
  digitalWrite(BHM, HIGH);
}
while (digitalRead(FDCBH) == HIGH);
digitalWrite(BHM, LOW);

vous pouvez écrire

digitalWrite(BHM, HIGH); // activation
while (digitalRead(FDCBH) == HIGH) ; // on attend la FDC qui fait passer FDCBH à LOW
digitalWrite(BHM, LOW); // désactivation

vous avez cette construction un peu partout dans le code soit sous cette forme, soit sous celle là

       Serial.println("Serrage brosse gauche");
        while (digitalRead(FDCBG) == LOW) { // Si le FDC Brosse Gauche est activer on serre
          digitalWrite(BGS, HIGH);
        }
        digitalWrite(BGS, LOW);

qui serait plus simple écrite ainsi:

Serial.println("Serrage brosse gauche");
digitalWrite(BGS, HIGH);
while (digitalRead(FDCBG) == LOW) ; // on attend l'activation du FdC
digitalWrite(BGS, LOW);

Généralement on commence les variables par une minuscule et on essaye d’utiliser un type pertinent. Par exemple au lieu de int Verification = 0;vous pourriez fairebool verification = false;et cette variable prendrait les valeurs vrai (true) ou faux (false) puisque vous utilisez cette variable comme cela. Pas besoin d’un int. idem pour les FinEtapeX

La gestion du temps nécessite de traiter les opérations toujours par soustraction pour traiter le moment où millis() reviendra à 0. donc au lieu de

currentTime = millis() + 3000; // ------TIMER ICI
do {
  ...
 } while ((currentTime > millis()));

on préfèrera écrire

 currentTime = millis();
while (millis() - currentTime <= 3000ul) {
  ...
}

sinon il manque un arrêt d’urgence et que se passe-t-il si un fin de course est défectueux ?

Le plus ennuyeux dans ce genre de programme c'est la gestion des erreurs. Faut prévoir tous les cas, et savoir quoi faire dans chaque cas.
Souvent, il y plus de code pour détecter et gérer les problèmes que de code pour faire le taf de base.

Merci pour vos retours !

Alors en fait pour la partie arrêt d'urgence sa sera coupure de courant directement , pas très bon pour l'Arduino mais au moins c'est sécurisant car en cas de plantage de l'Arduino je préfère que tout s'arrête.

Serial.println("Serrage brosse gauche");
digitalWrite(BGS, HIGH);
while (digitalRead(FDCBG) == LOW) ; // on attend l'activation du FdC
digitalWrite(BGS, LOW);

pour cette parti ci du coup , l'arduino attendra la détéction du FDC ? Le fonctionnement restera le même ? il ne passera pas a la suite avant ?

Pour la détection des FDC deffectueux une piste pour lancer des détéction tout au long du code ? y'a t'il une fonction "OU" en programmation ?

Merci en tout cas si vous pouvez m'aiguiller , je vais m'attaquer au modification que vous m'avez proposer et chercher une solution pour les problèmes de FIN DE COURSE même si je pense qu'il n'y a pas trop de solution , il faudrai que je rajoute des timers lors de la vérification au lancement du programme par exemple

digitalWrite(BHM, HIGH); // activation
while (digitalRead(FDCBH) == HIGH && Timer > 30 Secs) ; // on attend la FDC qui fait passer FDCBH à LOW -- Code pour l'exemple
digitalWrite(BHM, LOW); // désactivation

Le plus gros problème sera si un FDC tombe en panne en cours de cycle

J'ai modifier le comme avec les conseil de J-M-L
Je me retrouve avec un petit soucis après qu'il est fait un cycle , il reste planter a "En Place" sur le moniteur serie et il ne ce passe plus rien

Autre info , a certains moment 3 secondes ce transforme en 6 voir 9 secondes

(Je fait un nouveau message car maxi 9000 caractères)
Voila le nouveau code :

#define BHD 5 // Brosse Haut descente
#define BHM 6 // Brosse Haut Montée
#define RETOUR 7 // Retour du portique
#define AVANCE 8 // Avance du portique
#define BDS 9 // Brosse Droit Serrage
#define BDDS 10 // Brosse Droit Déserrage
#define BGS 3 // Brosse Gauche Serrage
#define BGDS 4 // Brosse Gauche Déserrage
#define EAU 11 // Alimentation Eau
#define SAVON 12 // Alimentation SAVON
#define BTAV 13 // Alimentation Brosse tourne en avant
#define BTAR 2 // Alimentation Brosse tourne en avant

#define FDCR A0 // Fin de course retour
#define FDCA A1 // Fin de course Avance
#define FDCBH A2 // Fin de course brosse Haute
#define FDCBG A3 // Fin de course brosse Gauche
#define FDCBD A4 // Fin de course brosse Droit
#define MES A5 // Bouton Mise en service

bool BoutonMES = false; // Bouton de mise en marche
bool verification = false;
bool finetape1 = false;
bool finetape2 = false;
bool finetape3 = false;

unsigned long currentTime = 0;

void setup() {
  Serial.begin(9600);
  Serial.println("Initialisation");
  pinMode(BHD, OUTPUT);
  pinMode(BHM, OUTPUT);
  pinMode(RETOUR, OUTPUT);
  pinMode(AVANCE, OUTPUT);
  pinMode(BDS, OUTPUT);
  pinMode(BDDS, OUTPUT);
  pinMode(BGS, OUTPUT);
  pinMode(BGDS, OUTPUT);
  pinMode(EAU, OUTPUT);
  pinMode(SAVON, OUTPUT);
  pinMode(BTAV, OUTPUT);
  pinMode(BTAR, OUTPUT);
  Serial.println("Etape 1 : PIN OUT INITIALISE");


  pinMode(FDCR, INPUT_PULLUP);
  pinMode(FDCA, INPUT_PULLUP);
  pinMode(FDCBH, INPUT_PULLUP);
  pinMode(FDCBG, INPUT_PULLUP);
  pinMode(FDCBD, INPUT_PULLUP);
  pinMode(MES, INPUT_PULLUP);
  Serial.println("Etape 2 : PIN ENTREE INITIALISE");

}

void loop() {
  // On éteint tout les relais a chaque debut de programme pour eviter les problèmes
  digitalWrite(BHD, LOW);
  digitalWrite(BHM, LOW);
  digitalWrite(RETOUR, LOW);
  digitalWrite(AVANCE, LOW);
  digitalWrite(BDS, LOW);
  digitalWrite(BDDS, LOW);
  digitalWrite(BGS, LOW);
  digitalWrite(BGDS, LOW);
  digitalWrite(EAU, LOW);
  digitalWrite(SAVON, LOW);
  digitalWrite(BTAV, LOW);
  delay(3000);
 Verif();;
 Etape1();
 Etape2();
 Etape3();
}


void Verif() {
  if (verification == false) {
    
    Serial.println("Verification du FDC Brosse du haut");
    digitalWrite(BHM, HIGH);
    while (digitalRead(FDCBH) == HIGH);
    digitalWrite(BHM, LOW);
    Serial.println("Brosse du haut en place");  

    Serial.println("Verification du FDC Brosse de droite");
    digitalWrite(BDDS, HIGH);
    while (digitalRead(FDCBD) == HIGH);
    digitalWrite(BDDS, LOW);
    Serial.println("Brosse de droite en place");  
  
    Serial.println("Verification du FDC Brosse de gauche");
    digitalWrite(BGDS, HIGH);
    while (digitalRead(FDCBG) == HIGH);
    digitalWrite(BGDS, LOW);
    Serial.println("Brosse de droite en place");  
  
    Serial.println("Verification du FDC RETOUR");
    digitalWrite(RETOUR, HIGH);
    while (digitalRead(FDCR) == HIGH);
    digitalWrite(RETOUR, LOW);
    Serial.println("En place");

      
  verification = true; // Verrouillage de la verification
  }   
}


void Etape1() { //Avance avec savon et eau + brosse
   
  if (verification == true && BoutonMES == false) {
  Serial.println("Attente du bouton poussoir");
    
     if (digitalRead(MES) == LOW) { // Lecture du bouton de mise en marche
      
      BoutonMES = true;
      Serial.println("");
      Serial.println("Demarrage du programme");
      currentTime = millis();
      while (millis() - currentTime <= 5000ul) {
        digitalWrite(BTAV, HIGH);
      }
      
       
      Serial.println("");
      Serial.println("1 - Avance du portique"); 
      currentTime = millis();
      while (millis() - currentTime <= 5000ul) {
        digitalWrite(BTAV, LOW);
        digitalWrite(AVANCE, HIGH);
       }
         

        Serial.println("");
        Serial.println("2 - On allume l'eau");
       currentTime = millis();
      while (millis() - currentTime <= 10000ul) {
         // On fait avancer le portique pendant 10 secs ensuite code suivant
        digitalWrite(AVANCE, LOW);
        digitalWrite(EAU, HIGH);
      }
    
      currentTime = millis();
      while (millis() - currentTime <= 5000ul) {
        digitalWrite(BTAV, HIGH);
       }

      Serial.println("Descente brosse");
      digitalWrite(BHD, HIGH);
      while (digitalRead(FDCBH) == LOW);
      digitalWrite(BHD, LOW);

      Serial.println("Serrage brosse Droit");
      digitalWrite(BDS, HIGH);
      while (digitalRead(FDCBD) == LOW);// Si le FDC Brosse Droit est activer on serre
      digitalWrite(BDS, LOW);

       Serial.println("Serrage brosse gauche");
       digitalWrite(BGS, HIGH);
       while (digitalRead(FDCBG) == LOW);
        digitalWrite(BGS, LOW);
        
        Serial.println("");
        Serial.println("3 - Avance portique");
        
      currentTime = millis();
      while (millis() - currentTime <= 5000ul) {
       digitalWrite(AVANCE, HIGH);
      }
      Serial.println("");
      digitalWrite(AVANCE, LOW); 
      Serial.println("FIN ETAPE 1"); // ----------- FIN ETAPE 1 ----------- 
      finetape1 = true;
     }    
    }
   
}

void Etape2() {
  if(finetape1 == true) {
      Serial.println("ETAPE 2"); // ----------- FIN ETAPE 1 ----------- 
      Serial.println("2.1 - On descend la brosse jusqu'en bas pour nettoyer les portes arrieres");
      currentTime = millis();
      while (millis() - currentTime <= 3000ul) {
       digitalWrite(BHD, HIGH);
      }
      digitalWrite(BHD, LOW);
      digitalWrite(EAU, LOW);
      digitalWrite(BTAV, LOW); // On arrete la rotation de la brosse en avant
      digitalWrite(BTAR, HIGH); // On démarre la rotation de la brosse en arriere
      
      Serial.println("2.2 - REMONTE JUSQU'AU FIN DE COURSE");
      digitalWrite(BHM, HIGH);
      while (digitalRead(FDCBH) == HIGH);
      digitalWrite(BHM, LOW);

      Serial.println("2.3 - ON REDESCEND LA BROSSE SUR LE TOIT DE LA SEMI");
      digitalWrite(BHD, HIGH);
      while (digitalRead(FDCBH) == LOW);
      digitalWrite(BHD, LOW);
      digitalWrite(EAU, HIGH);
      finetape2 = true;
  }
}

void Etape3(){
  if(finetape2 == true) {
  Serial.println("ETAPE 3"); // ----------- FIN ETAPE 2 ----------- 
  Serial.println("3 - On retourne jusqu'a la bute du portique");
  digitalWrite(RETOUR, HIGH);
  while (digitalRead(FDCR) == HIGH);
  digitalWrite(RETOUR, LOW);
  Serial.println("FINALE");
  Serial.println("3.1 - On arrete tout les relais");
  digitalWrite(BHD, LOW);
  digitalWrite(BHM, LOW);
  digitalWrite(AVANCE, LOW);
  digitalWrite(BDS, LOW);
  digitalWrite(BDDS, LOW);
  digitalWrite(BGS, LOW);
  digitalWrite(BGDS, LOW);
  digitalWrite(EAU, LOW);
  digitalWrite(SAVON, LOW);
  digitalWrite(BTAV, LOW);
  digitalWrite(BTAR, LOW);
  Serial.println("3.1 - On passe la verification a zero et on attend le prochain cycle");
  finetape1 = false;
  finetape2 = false;
  verification = false;
  
  }
}

Au cas ou vous voudriez voir une simulation :
TinkerKad - AUTOMATION LAVAGE - Dylan
Merci pour vos retours :slight_smile:

Je souhaiterais savoir s’il y a moyen d’optimiser mon code ? Ou si vous avez des sugguestion pour m’aider a m’améliorer dans ma création

Sauf bien entendu si je me trompe, ce qui est une de mes spécialités…

En regardant le code de loop, je vois que l’on fait systématiquement et dans l’ordre les codes complets (dans les if) de Verif, puis Etape1 puis Etape2, puis Etape3. On ne peut pas faire une routine dans le désordre. si elle n’est pas à sa place. Si on ne fait rien, loop boucle et passe sont temps à désactiver tous les relais qui étaient déjà désactivés avant.
Chacune des 4 étapes (Verif est pour moi l’étape 0) est bloquante, c’est à dire que l’on reste dedans tant qu’elle n’est pas finie et que l’on ne retourne pas à loop.

Du coup, on peut supprimer les if dans les 4 étapes et rester bloqué dedans, vu que l’on ne peut pas faire autrement que de faire les étapes les une à la suite des autres…


while (digitalRead(FDCBH) == HIGH);

digitalRead est déja un boléen, on peut donc écrire:

while (digitalRead(FDCBH));

ou encore:

while ((((digitalRead(FDCBH) == HIGH) == HIGH) == HIGH) == HIGH);

Je choisis en général la plus courte!

if (digitalRead(MES) == LOW) { // Lecture du bouton de mise en marche

peur aussi s’écrire:

if (!digitalRead(MES)) { // Lecture du bouton de mise en marche

unsigned long currentTime = 0;

Pourquoi l’initialiser à 0 quand:

  • le compilateur de toutes façon le met à 0
  • si il était initalisé aléatoirement, cela n’aurait aucune importance, la première chose que l’on fait sera un currentTime = millis ( )

Quand j’initialise à 0 une variable qui l’est déjà, c’est pour insistr que j’ai vraiment besoin qu’elle soit à 0. Mais ceci est personnel.


      currentTime = millis();
      while (millis() - currentTime <= 5000ul) {
        digitalWrite(BTAV, HIGH);
      }

est équivalent à

:      digitalWrite(BTAV, HIGH);
      currentTime = millis();
      while (millis() - currentTime <= 5000ul);

car BTAV est bistable (il ne revient pas à LOW si on ne lui donne pas d’ordre. Et les 2 dernières lignes sont bloquantes et donc équivalentes à un delay. Le premier code est donc fonctionnellement équivalent à

:      digitalWrite(BTAV, HIGH);
      delay(5000ul);

Si on écritSerial.println("Vérification du FDC Brosse du haut"); la chaîne de caractère est mise en RAM(espace pour les variables globales), et en général, on manque de RAM avant la FLASH (espace de stockage de programmes). Si l’on encadre la chaîne par une macro F( ):Serial.println(F("Vérification du FDC Brosse du haut")); la chaîne est mise dans la FLASH. Ce n’est pas important ici car le programme est fini, mais c’est une habitude à prendre pour l’avenir. Si le programme tourne sur une Uno, ce programme utilise déjà la moitié de la RAM, pour 13% de la FLASH. Autant mettre les chaînes constantes là ou il y a de la place.

hello
il y a deux façons de caber les fdc:

celle que tu as appliquée:
entrée en input pullup et le fdc cablé en NO sur GND. et tu surveilles le passage de l'entrée à "0".

et l'autre...
entrée en input pullup et le fdc cablé en NC sur GND. et tu surveilles le passage de l'entrée à "1"
cette deuxième façon de cabler te permet:
de savoir si le fil de retour du fdc est coupé,
de savoir si le fdc est HS(dans la plupart des cas)

vileroi:
Sauf bien entendu si je me trompe, ce qui est une de mes spécialités....

le commentaire ci dessous est à classer en partie dans cette catégorie :slight_smile:

while (digitalRead(FDCBH) == HIGH);

digitalRead est déja un boléen, on peut donc écrire:

while (digitalRead(FDCBH));

ou encore:

while ((((digitalRead(FDCBH) == HIGH) == HIGH) == HIGH) == HIGH);

Je choisis en général la plus courte!

digitalRead() retourne un entier (int). Donc l'affirmation est fausse.
Mais... Les entiers sont promus effectivement automatiquement en booléens s'ils sont utilisés dans une condition logique et 0 devient faux et tout le reste devient vrai. Inversement dans une comparaison avec un entier un booléen devient 1 s'il est vrai et 0 s'il est faux.

Votre remarque n'est donc valable que parce que HIGH est défini comme valant 1, ce qui est un choix arbitraire (origines historique et technique).

De plus comme on peut câbler une pin en PULL-UP ou PULL-DOWN, signifier avec quelle valeur on veut comparer est un important point de documentation du code et démontre l'intention.

Enfin, ça ne coûte pas plus cher puisque le compilateur fera sans doute la même chose que vous mettiez == HIGH ou pas.

à des fins de sécurité de fonctionnement on double ou triple les systèmes en utilisant des technologies différentes.

Vous pourriez par exemple tester le courant consommé sur les moteurs: Une élévation anormale (à définir) signifierait que le moteur "bloque" et qu'il faut donc déclencher un arrêt d'urgence (ou considérer que le FdC est défectueux et qu'il faut arrêter le mouvement en cours).

ou une cellule laser pour déterminer si le sommet du camion est trop proche

...

Larousse:
Booléen: se dit d’une variable susceptible de prendre deux valeurs s’excluant mutuellement, par exemple 0 et 1.

Correspond donc à ce que retourne digitalRead (0x0000 ou 0x001) qui retourne un entier 16 bits mais ne pouvant prendre que deux valeurs.

C’est pour moi un reste d’assembleur dans lequel il n’y a pas de contrôle du type (booléen, signé ou non signé ).

Là ou cela devient un peu plus problématique si on considère que le retour est entier et pas booléen, c’est si on transforme le code pour utiliser digitalReadFast; il faudrait alors écrire:
while (digitalReadFast(FDCBH) == 4);FDCBH étant sur PC2 sur une Uno ou PF2 sur une Mega:

Pour preuve simple:

#include "digitalWriteFast.h"

#define FDCBH A2 // Alimentation Brosse tourne en avant

void setup()
{
  Serial.begin(115200);
  pinMode(FDCBH,INPUT_PULLUP); // Pin à 5V

  if (digitalRead    (FDCBH) == HIGH) Serial.println("FDCBH est HIGH"); else Serial.println("FDCBH n'est pas HIGH");
  if (digitalReadFast(FDCBH) == HIGH) Serial.println("FDCBH est HIGH"); else Serial.println("FDCBH n'est pas HIGH");
}

void loop(){}

Donne comme résultat:

FDCBH est HIGH
FDCBH n’est pas HIGH

Ce qui est exact car digitalReadFast(FDCBH) vaut 4

Et les nom des E/S ne serviraient plus à rien car la Uno et Mega ne sont pas compatibles avec digitalReadFast car pour BTAR, digitalReadFast retourne 0 ou 4 avec une uno, et 0 ou 16 avec une Mega.
Reste encore (!digitalReadFast(BTAR) == LOW) qui fonctionne toujours dans les deux cas.

Si jamais le code de notre ami était trop long (pas encore, mais cela viendra!), on ne peut plus lui conseiller d’utiliser des “Fast” pour les E/S, pourtant sur son code qui fait 4308 octets (dont 444 octets sont certainement pris pas le système, c’est la taille d’un programme qui ne fait rien) on passerait à 3402 octets, soit un gain de 23%, presque 1/4 du programme. Par contre en boycottant les HIGH, le code fonctionnerait.

OK pour la définition Larousse. Etant sur un forum de programmation j'avais compris que vous parliez du type bool.

Ensuite votre point me semble "irrelevant" comme disent les anglais... Si vous y allez par là votre code ne marche pas non plus de la même façon suivant si j'ai un PULLUP ou PULLDOWN puisque vous êtes dépendant d'une décision que HIGH c'est 1 qui est promu en true dans un test de condition par le compilateur (vous n'êtes pas en assembleur).

Si vous utilisez digitalReadFast(), il faut tenir compte de la spécification de cette fonction. La fonction ne retourne pas HIGH mais un masque par contre LOW reste LOW (0).

Si vous voulez de la portabilité, dans ce cas il suffit d'écrire

  if (digitalRead    (FDCBH) != LOW) Serial.println("FDCBH est HIGH"); else Serial.println("FDCBH n'est pas HIGH");
  if (digitalReadFast(FDCBH) != LOW) Serial.println("FDCBH est HIGH"); else Serial.println("FDCBH n'est pas HIGH");

vileroi:
Sauf bien entendu si je me trompe, ce qui est une de mes spécialités…

En regardant le code de loop, je vois que l’on fait systématiquement et dans l’ordre les codes complets (dans les if) de Verif, puis Etape1 puis Etape2, puis Etape3. On ne peut pas faire une routine dans le désordre. si elle n’est pas à sa place. Si on ne fait rien, loop boucle et passe sont temps à désactiver tous les relais qui étaient déjà désactivés avant.
Chacune des 4 étapes (Verif est pour moi l’étape 0) est bloquante, c’est à dire que l’on reste dedans tant qu’elle n’est pas finie et que l’on ne retourne pas à loop.

Du coup, on peut supprimer les if dans les 4 étapes et rester bloqué dedans, vu que l’on ne peut pas faire autrement que de faire les étapes les une à la suite des autres…


while (digitalRead(FDCBH) == HIGH);

digitalRead est déja un boléen, on peut donc écrire:

while (digitalRead(FDCBH));

ou encore:

while ((((digitalRead(FDCBH) == HIGH) == HIGH) == HIGH) == HIGH);

Je choisis en général la plus courte!

if (digitalRead(MES) == LOW) { // Lecture du bouton de mise en marche

peur aussi s’écrire:

if (!digitalRead(MES)) { // Lecture du bouton de mise en marche

unsigned long currentTime = 0;

Pourquoi l’initialiser à 0 quand:

  • le compilateur de toutes façon le met à 0
  • si il était initalisé aléatoirement, cela n’aurait aucune importance, la première chose que l’on fait sera un currentTime = millis ( )

Quand j’initialise à 0 une variable qui l’est déjà, c’est pour insistr que j’ai vraiment besoin qu’elle soit à 0. Mais ceci est personnel.


      currentTime = millis();

while (millis() - currentTime <= 5000ul) {
       digitalWrite(BTAV, HIGH);
     }



est équivalent à


:      digitalWrite(BTAV, HIGH);
     currentTime = millis();
     while (millis() - currentTime <= 5000ul);



car BTAV est bistable (il ne revient pas à LOW si on ne lui donne pas d'ordre. Et les 2 dernières lignes sont bloquantes et donc équivalentes à un delay. Le premier code est donc fonctionnellement équivalent à 


:      digitalWrite(BTAV, HIGH);
     delay(5000ul);






---



Si on écrit


Serial.println(“Vérification du FDC Brosse du haut”);



la chaîne de caractère est mise en RAM(espace pour les variables globales), et en général, on manque de RAM avant la FLASH (espace de stockage de programmes). Si l'on encadre la chaîne par une macro F( ):


Serial.println(F(“Vérification du FDC Brosse du haut”));



la chaîne est mise dans la FLASH. Ce n'est pas important ici car le programme est fini, mais c'est une habitude à prendre pour l'avenir. Si le programme tourne sur une Uno, ce programme utilise déjà la moitié de la RAM, pour 13% de la FLASH. Autant mettre les chaînes constantes là ou il y a de la place.

J’avais quelque soucis quand je compilais , des fois aléatoirement il passait a l’étape 2 alors que la 1 n’était pas faite du coup j’ai préféré mettre des verrouillages.
Merci pour l’info du F("")
J’ai utiliser des While car je voulais me faire du au cas ou si j’ai des choses a rajouter dans le temps d’attente , vérification d’un bug fin de course a l’avenir ou autre.
Merci pour vos réponse sa m’aide grandement.
Je vais basculer mon code sur une MEGA afin de pouvoir améliorer le code et avoir plus d’entrée pour y rajouter plus tard des capteurs additionnels.
Je voulais savoir aussi comment protéger mes entrées , car elle seront relier directement a un contact NO ou NC de mes fin de course (Normalement aucune tension, contact sec) ? Resistance ou autre ?
Merci a tous pour les réponses que vous me donnez , je vais préparer mon montage et commencer a faire des essaies ce weekend je pense en grandeur nature afin de pouvoir mètre mes tempos correctement

Je voulais savoir aussi comment protéger mes entrées , car elle seront relier directement a un contact NO ou NC de mes fin de course (Normalement aucune tension, contact sec) ? Resistance ou autre ?

un fin de course c’est un simple bouton. Vous le câblez en INPUT_PULLUP

pin <—> FdC <—> GND

et vous déclarez la pin en INPUT_PULLUP.

elle sera HIGH par défaut et tombe à LOW quand la FdC est détectée.

câblé de cette façon vous n’avez pas besoin de protéger quoi que ce soit d’une surtension à mon avis.

De manière plus générale, si vous voulez protéger des pins, vous pouvez toujours utiliser un opto-coupleur par exemple.

Super merci J-M-L pour ces informations précieuse je prend note.

Je souhaiterais augmenter la sécurité de mon code et me lance dans un codeur incrémental, j'ai trouver des codes sur internet mais ils me bloquent un peut

En utilisant les codes donnée je tombe sur des déplacement qui me font de 1 ou -1 , mais pas d'incrémentation ...

Sur place j'ai une roue codeuse incrémental de ce type :
roue.JPG
Je souhaite savoir le sens et le nombre de pale qui passe pour me faire un avancement a la place de ma tempo , sa sera sécuritaire.

int pinA = 2;   // Le port D2 est associé à l'interruption 0
int pinB = 4;
volatile int pos = 0;  // Position (en nombre de pas) du codeur
 
void setup()  {
   Serial.begin(115200);
   Serial.println("Codeur incremental");
   pinMode(pinB, INPUT);
   attachInterrupt(0, front, FALLING);  // Détection des fronts descendants
}
 
void loop()   {
   delay(10);
}
 
void front()   {
   int s = digitalRead(pinB);
   if (s == LOW)   {
      ++pos;
   }
   else   {
      --pos;
   }
   Serial.println(pos);   // Ligne à supprimer après les tests, car elle ralenti le dispositif
}

C'est un code trouver sur internet , je ne sais vraiment pas dans quelle sens partir , si jamais vous pouvez m'aiguiller

Merci encore

roue.JPG

Ne vous cassez pas la tête à coder cela vous même, prenez la bibliothèque pour les encodeurs rotatifs des teensy (code source à télécharger sur GitHub)- elle fonctionne très bien même à grande vitesse notamment si vous choisissez des pins supportant les interruptions (par exemple 2 et 3 sur UNO).

Merci de l'infos je viens de tester avec 2 bouton poussoirs , c'est une merveille ! Si je suis autoriser a vous filmez le portique en action une fois mon projet terminer je vous partagerais sa , sa ma grandement aider ! J-M-L vous etes un AS !

Je reviendrais sur le topics si j'ai d'autre question merci !

Cool

sinon pour simplifier votre gestion des boutons et fin de course éventuellement utilisez la librairie de @bricoleau

Bonsoir les pros,

J’ai un soucis avec mon arduino mega … il fait n’importe quoi

Voila le code que j’ai injecter du coup

#define BHD 2 // Brosse Haut descente
#define BHM 3 // Brosse Haut Montée
#define RETOUR 4 // Retour du portique
#define AVANCE 5 // Avance du portique
#define BDS 6 // Brosse Droit Serrage
#define BDDS 7 // Brosse Droit Déserrage
#define BGS 8 // Brosse Gauche Serrage
#define BGDS 9 // Brosse Gauche Déserrage
#define EAU 10 // Alimentation Eau
#define SAVON 11 // Alimentation SAVON
#define BTAV 12 // Alimentation Brosse tourne en avant
#define BTAR 14 // Alimentation Brosse tourne en avant

#define FDCR A0 // Fin de course retour
#define FDCA A1 // Fin de course Avance
#define FDCBH A2 // Fin de course brosse EN HAUT
#define FDCBB A3 // Fin de course brosse EN BAS
#define FDCBG A4 // Fin de course brosse Gauche
#define FDCBD A5 // Fin de course brosse Droit
#define MES A6 // Bouton Mise en service

bool BoutonMES = false; // Bouton de mise en marche
bool verification = false;
bool finetape1 = false;
bool finetape2 = false;
bool finetape3 = false;

unsigned long currentTime = 0;

void setup() {
  Serial.begin(9600);
  Serial.println("Initialisation");
  pinMode(BHD, OUTPUT);
  pinMode(BHM, OUTPUT);
  pinMode(RETOUR, OUTPUT);
  pinMode(AVANCE, OUTPUT);
  pinMode(BDS, OUTPUT);
  pinMode(BDDS, OUTPUT);
  pinMode(BGS, OUTPUT);
  pinMode(BGDS, OUTPUT);
  pinMode(EAU, OUTPUT);
  pinMode(SAVON, OUTPUT);
  pinMode(BTAV, OUTPUT);
  pinMode(BTAR, OUTPUT);
  
  digitalWrite(BHD, HIGH);
  digitalWrite(BHM, HIGH);
  digitalWrite(RETOUR, HIGH);
  digitalWrite(AVANCE, HIGH);
  digitalWrite(BDS, HIGH);
  digitalWrite(BDDS, HIGH);
  digitalWrite(BGS, HIGH);
  digitalWrite(BGDS, HIGH);
  digitalWrite(EAU, HIGH);
  digitalWrite(SAVON, HIGH);
  digitalWrite(BTAV, HIGH);
  digitalWrite(BTAR, HIGH);
  Serial.println("Etape 1 : PIN OUT INITIALISE");


  pinMode(FDCR, INPUT_PULLUP);
  pinMode(FDCA, INPUT_PULLUP);
  pinMode(FDCBH, INPUT_PULLUP);
  pinMode(FDCBB, INPUT_PULLUP);
  pinMode(FDCBG, INPUT_PULLUP);
  pinMode(FDCBD, INPUT_PULLUP);
  pinMode(MES, INPUT_PULLUP);
  Serial.println("Etape 2 : PIN ENTREE INITIALISE");

}

void loop() {
  // On éteint tout les relais a chaque debut de programme pour eviter les problèmes
  digitalWrite(BHD, HIGH);
  digitalWrite(BHM, HIGH);
  digitalWrite(RETOUR, HIGH);
  digitalWrite(AVANCE, HIGH);
  digitalWrite(BDS, HIGH);
  digitalWrite(BDDS, HIGH);
  digitalWrite(BGS, HIGH);
  digitalWrite(BGDS, HIGH);
  digitalWrite(EAU, HIGH);
  digitalWrite(SAVON, HIGH);
  digitalWrite(BTAV, HIGH);
  digitalWrite(BTAR, HIGH);
 Verif();
 Etape1();
 Etape2();
 Etape3();
}


void Verif() {
  if (verification == 0) {
    
    Serial.println("Verification du FDC Brosse du haut");
    digitalWrite(BHM, LOW);
    while (digitalRead(FDCBH) == HIGH);
    digitalWrite(BHM, HIGH);
    Serial.println("Brosse du haut en place");  

    Serial.println("Verification du FDC Brosse de droite");
    digitalWrite(BDDS, LOW);
    while (digitalRead(FDCBD) == HIGH);
    digitalWrite(BDDS, HIGH);
    Serial.println("Brosse de droite en place");  
  
    Serial.println("Verification du FDC Brosse de gauche");
    digitalWrite(BGDS, LOW);
    while (digitalRead(FDCBG) == HIGH);
    digitalWrite(BGDS, HIGH);
    Serial.println("Brosse de droite en place");  
  
    Serial.println("Verification du FDC RETOUR");
    digitalWrite(RETOUR, LOW);
    while (digitalRead(FDCR) == HIGH);
    digitalWrite(RETOUR, HIGH);
    Serial.println("En place");
    BoutonMES = false;
    verification = true; // Verrouillage de la verification
  }   
}


void Etape1() { //Avance avec savon et eau + brosse
   
  if (verification == true && BoutonMES == false) {
  Serial.println("Attente du bouton poussoir");
    
     if (digitalRead(MES) == LOW) { // Lecture du bouton de mise en marche
      
      Serial.println("");
      Serial.println("Demarrage du programme");
      Serial.println("1.0 - On fait tourner les brosse 5 SECS");
      digitalWrite(BTAV, LOW);
      delay(5000);
      digitalWrite(BTAV, HIGH);
       
      Serial.println("");
      Serial.println("1.1 - Avance du portique jusqu'au camion");
      digitalWrite(AVANCE, LOW); 
      currentTime = millis();
      while (millis() - currentTime == 22500ul);  // TIMER AVANCE JSUQU'AU CAMION
        digitalWrite(AVANCE, HIGH);
        digitalWrite(EAU, LOW);
        delay(2000);
        digitalWrite(BTAV, LOW);
        
      Serial.println("1.1a - Descente brosse");
      digitalWrite(BHD, LOW);
      while (digitalRead(FDCBH) == LOW);
      delay(1500);
      digitalWrite(BHD, HIGH);

      Serial.println("1.1b - Serrage brosse Droit");
      digitalWrite(BDS, LOW);
      while (digitalRead(FDCBD) == LOW);// Si le FDC Brosse Droit est activer on serre
      delay(1500);
      digitalWrite(BDS, HIGH);

       Serial.println("1.1c - Serrage brosse gauche");
       digitalWrite(BGS, LOW);
       while (digitalRead(FDCBG) == LOW);
       delay(1500);
        digitalWrite(BGS, HIGH);
        
        Serial.println("");
        Serial.println("1.2 - Avance portique jusqu'a la fin de la semi");
        digitalWrite(AVANCE, LOW);
      currentTime = millis();
      while (millis() - currentTime <= 120000ul);// TIMER AVANCE JUSQU'AU BOUT DE LA REMORQUE
      Serial.println("");
      digitalWrite(AVANCE, HIGH); 
      Serial.println("FIN ETAPE 1"); // ----------- FIN ETAPE 1 ----------- 
      finetape1 = true;
     }    
    }
   
}

void Etape2() {
  if(finetape1 == true) {
    delay(2000);
      Serial.println("ETAPE 2"); // ----------- FIN ETAPE 1 ----------- 
      Serial.println("2.1 - On descend la brosse jusqu'en bas pour nettoyer les portes arrieres");
      digitalWrite(BHD, LOW);
      while (digitalRead(FDCBB) == HIGH);
      digitalWrite(BHD, HIGH);
      
      digitalWrite(BTAV, HIGH); // On arrete la rotation de la brosse en avant
      delay(2000);
      digitalWrite(BTAR, LOW); // On démarre la rotation de la brosse en arriere
      
      Serial.println("2.2 - REMONTE JUSQU'AU FIN DE COURSE");
      digitalWrite(BHM, LOW);
      while (digitalRead(FDCBH) == HIGH);
      digitalWrite(BHM, HIGH);

      Serial.println("2.3 - ON REDESCEND LA BROSSE SUR LE TOIT DE LA SEMI");
      digitalWrite(BHD, LOW);
      while (digitalRead(FDCBH) == LOW);
      delay(1500);
      digitalWrite(BHD, HIGH);
      digitalWrite(EAU, LOW);
      finetape2 = true;
  }
}

void Etape3(){
  if(finetape2 == 1) {
    delay(2000);
  Serial.println("ETAPE 3"); // ----------- FIN ETAPE 2 ----------- 
  Serial.println("3 - On retourne jusqu'a la bute du portique");
  digitalWrite(RETOUR, LOW);
  while (digitalRead(FDCR) == HIGH);
  digitalWrite(RETOUR, HIGH);
  digitalWrite(EAU, HIGH);
  Serial.println("FINALE");
  Serial.println("3.1 - On arrete tout les relais");
  digitalWrite(BHD, HIGH);
  digitalWrite(BHM, HIGH);
  digitalWrite(AVANCE, HIGH);
  digitalWrite(BDS, HIGH);
  digitalWrite(BDDS, HIGH);
  digitalWrite(BGS, HIGH);
  digitalWrite(BGDS, HIGH);
  digitalWrite(EAU, HIGH);
  digitalWrite(SAVON, HIGH);
  digitalWrite(BTAV, HIGH);
  digitalWrite(BTAR, HIGH);
  Serial.println("3.1 - On passe la verification a zero et on attend le prochain cycle");
  finetape1 = false;
  finetape2 = false;
  verification = false;
  
  }
}

Il ne respecte aucun delay(); , il oublie des detection de fin de course, j’ai limpression qu’il saute des ligne, des fois au lieu d’avancer il reste sur place et termine le programme en reparte a la verification sans avoir bouger les brosses

Le seul délais qu’il arrive a tenir a chaque cycle est le while (millis() - currentTime == 22500ul); // TIMER AVANCE JSUQU’AU CAMION
Merci pour votre aide

Cordialement , Dylan

Hum ce i est une erreur de logique

 while (millis() - currentTime == 22500ul);
...
while (millis() - currentTime <= 120000ul);

ca ne doit pas faire grand chose au mieux attendre une milli seconde… il faut utiliser <= si vous voulez attendre 22.5s ou 2 minutes

mais pourquoi utiliser millis comme cela, autant faire

delay(22500ul);
...
delay(120000ul);
while (millis() - currentTime == 22500ul);

millis() ne compte pas exactement les ms! Il y a 2,4% de valeurs entières que millis() ne prendra jamais. Pour peu que l’on tombe dessus. C’est pour cela qu’il faut toujours employer > < <= ou >=, mais jamais ==
Plus d’informations à ce sujet: Mon désamour pour la gestion de l’horloge système d’Arduino

Pour des autres tempos, je ne vois pas ce qui pourrait ne pas fonctionner. En cas de problème encadrer les delay incriminées par deux Serial.println Cela permet de voir si c’est la tempos qui débloque ou si c’est une erreur de logique