millis dans une boucle for

bonjour a tous

j’ai un petit soucis d’optimisation de mon programme.
je souhaite enlever mes fonctions “delay” pour les remplacer par millis.
cela a très bien marcher dans ce cas:

   if(z==0){ telephone();
    if(temps - temps_precedent >=interval){
      temps_precedent=temps;
      z++;}}
if(z==1){telephone_raccrocher();
if(temps - temps_precedent >=interval){
      temps_precedent=temps;
      z=0;}}

mais dans l’autre cas je me retrouve dans un boucle “for” et la c le drame lol.
je n’arrive pas a faire a boucler correctement et j’avoue avoir tourné cela dans tout les sens mais je ne trouve pas mon erreur.
en gros la boucle tourne mais ne prend pas en compte l’intervalle.
je suppose que c’est tout simple mais la je pèche, je rame et je coule.

 for(byte y=0;y<=6;y++){
        temps1=millis(); 
        Serial.println(y);
        cadenas_ferme();
        cadenas_ferme1();
        cadenas_ferme2();
        cadenas_ferme3();
        cadenas_ferme4();
        cadenas_ferme5();
        digitalWrite(ledok,HIGH);
        if(temps1 - temps_precedent1 >=interval1){
        temps_precedent1=temps1;
        Serial.println(temps1);
        cadenas_ouvert();
        cadenas_ouvert1();
        cadenas_ouvert2();
        cadenas_ouvert3();
        cadenas_ouvert4();
        cadenas_ouvert5();
        digitalWrite( ledok,LOW);
        Serial.println("ouvert");}
         }

si quelqu’un pouvais m’aider :slight_smile: :slight_smile:
devrais-je plutôt mettre cela dans un switch case?

dans le premier cas vous avez une variable (z) qui vous dit à quelle étape vous en êtes. il faudrait un truc similaire pour votre boucle for, comme ça quand la loop() boucle et vous revenez dans le for() vous ne refaites pas ce que vous avez fait la dernière fois mais l'étape suivante quand c'est le bon moment.

hello

merci JML en fait ma boucle for est dans une fonction en dehors de la loop, je ne pense pas que cela change grand chose ,c’est d’ailleurs pareil pour le premier cas.
vous avez raison j’ai oublié une variable.
du coup j’ai un peu réécris le code et voila le meilleur résultat que j’ ai pu obtenir.
ce n’est pas ce que je souhaite mais visuellement sur l’ecran LCD c’est propre.

 for(byte y;y<=50; y++){
        static byte q=0;
        temps1=millis();
        Serial.println(q);
        Serial.println(y);
        if(q==0){

        cadenas_ferme();
        cadenas_ferme1();
        cadenas_ferme2();
        cadenas_ferme3();
        cadenas_ferme4();
        cadenas_ferme5();
        digitalWrite(ledok,HIGH);
        Serial.println("fermer");
        if(temps1 - temps_precedent1 >=interval1){
        temps_precedent1=temps1;
         q++;
         Serial.println(temps1);}
        }
        if(q==1){
        cadenas_ouvert();
        cadenas_ouvert1();
        cadenas_ouvert2();
        cadenas_ouvert3();
        cadenas_ouvert4();
        cadenas_ouvert5();
        digitalWrite( ledok,LOW);
        Serial.println("ouvert");
        if(temps1 - temps_precedent1 >=interval1){
        temps_precedent1=temps1;
        q=0; }
        }
      
        }

En gros je suis obliger de mettre ma variable “y” a 50 pour que mon animation soit correcte.
Mais moi je souhaite que ma boucle for fasse tourner cette animation 5x.
c’est là que je bloque. D’après ce que j’observe sur mon Serial.print l’incrémentation de “y” se fait
correctement mais plusieurs fois pendant un cycle, c’est à dire pendant que “q==0” ma boucle for va s’incrémenter 3 fois et vis vers ça quand “q==1” d’où la valeur de y à 50.
je pense que c’est juste une erreur de syntaxe du code mais j’avoue ne pas savoir où.

bonjour Acedar, pour l'avoir expérimenter il n'y a pas longtemps!

millis() dans une boucle for! c'est pas top du tout!!Sur le serial, c'est presque comme si tu n'avais rien mis en fait!!Non? comme si ça ne tenais pas compte de millis()!!

Puis comme m'ont dit Vileroi et Kamill, while et for sont bloquante, donc tu peut utiliser delay, qui lui marchera.

Afin de pouvoir me servir de millis() comme je le souhaiter, je suis passer par IF. donc je suppose que switch sera une bonne alternative pour ton cas.

tiens, je te me le lien du post que j'avais fait, ça pourra p'tetre te servir.

Salut , il faudrait faire un truc du genre :

for (byte y=0; y<=6 && (temps1 - temps_precedent1 >=interval1) ; y++ ) {
// mes trucs 
}

mais ca reste evidemment bloquant !

votre fonction est en dehors de la loop() mais sans doute appelée depuis la loop().
ce qu’il faudrait c’est que au lieu de faire une boucle for dans cette fonction, vous ne fassiez qu’une seule itération de la boucle et puis laisser la loop() revenir vous demander de faire quelque chose.

par exemple pour faire une boucle de 0 à 99 qui fait quelque chose toutes les secondes, vous écririez une fonction comme celle là:

void maFonction(bool initialisation = false;)
{
 static uint32_t chrono = 0;
 static int index = 0;
 static bool enMarche = false;

 if (initialisation) { // pour amorcer
    index = 0;
    chrono = millis();
    enMarche = true;
    return;
 }


  if (enMarche  && (millis() - chrono >= 1000)) { // tout les secondes on fait un truc puis on passe à l'index suivant

    // ********* FAIRE UN TRUC **********

    Serial.println(index);

    // *********************************

    enMarche  = (++index < 100);
    chrono = millis();
  }

}

pour amorcer la boucle vous appelez maFonction(true); et ensuite vous pouvez appeler juste maFonction(); continuellement dans la loop.

(sinon dans les boucles, n’oubliez pas de donner une valeur de départ à votre variable)

J-M-L:
votre fonction est en dehors de la loop() mais sans doute appelée depuis la loop().
ce qu'il faudrait c'est que au lieu de faire une boucle for dans cette fonction, vous ne fassiez qu'une seule itération de la boucle et puis laisser la loop() revenir vous demander de faire quelque chose.

(et dans les boucles, n'oubliez pas de donner une valeur de départ à votre variable)

  • 1

si vous faites comme ca , ca devrait marcher sans soucis , void loop s' occupant de faire la boucle automatiquement et ca prend en compte le millis differentiel :

void setup() {
    // put your setup code here, to run once:

}

void loop() {
    // put your main code here, to run repeatedly:
	maFonction();
}

void maFonction () {
	if(temps - temps_precedent >= interval) {
          // mes trucs 
        }
}

Merci à tous pour vos réponses.

Mes doutes étaient donc fondés lol, la boucle for est bloquante donc je me suis casser la tête pour rien.
Mais c'est pas grave j'ai appris bien des choses sur ce coup.
Au vu de mon programme dans son intégralité le "delay" fera très bien l'affaire(vu qu'il est a 300 ms).
De plus cette fonction est dans une autre fonction qui est elle appelée depuis la loop.
En gros je vérifie un code si le code est bon je lance cette animation et si le code est mauvais j'en lance une autre.
Le but de mettre millis était , je l'avoue, un simple entrainement pour moi qui a toujours des soucis avec cette dernière fonction, d'où cet apprentissage très enrichissant, encore merci à tous.
Il n'y a que dans le premier cas où millis est très utile, et celui ci fonctionne très bien.

Voici le post avec tout le programme pour ceux qu'il veulent y jeter un coup d’œil. Le code a quelque peu changé depuis la publication de ce post mais l’idée générale est toujours la même.

la boucle for en elle même n'est pas bloquante, c'est si vous mettez une attente à l'interieur qu'elle devient longue :slight_smile:

si vous integrez vos fonctions dans la loop , ce qui est quasiment le cas tout le temps , ca ne devient plus bloquant , pendant le " temps d' attente " , loop fait autrechose si on le lui demande .

ce n ' est que si vous mettez un delay () ou un millis () a l' interieur d' une autre boucle elle meme appellée dans loop que ca devient bloquant comme l' a dit J-M-L.

ceci etant souvent on a une mauvaise vu d' ensemble sur un gros programme .

mais 95 % du temps les fonctions sont appelées dans la loop , car sinon ca n ' aurait pas grand interet .

les fonctions appelées dans la loop qui appellent d' autres fonctions ,c ' est tres courant .

pour se rendre compte a peu pres du deroulement d ' un programme il faut demarrer par la loop et faire un schema , du style un tour de boucle en prenant chaque appel aux fonctions .

apres avoir fait ce schema rapide , on sait si on a besoin que la boucle soit bloquante ou pas , car on visualise si on a besoin de recuperer toutes les données avant de continuer( generalement c ' est le cas courant et ca ne comprends pas de delay ou millis )ou pas en fonction de ce qu ' on veut faire par la suite .

si vous avez besoin d' un delay ou millis dans votre boucle , la meilleure des solutions est souvent de faire une fonction avec des conditions et / ou de mettre un millis dans la loop en condition , comme dans l' exemple donné sur mon post precedent .

Si on a besoin d’un truc non bloquant, un bon moyen c’est de comprendre les machines à états (cf mon tuto éventuellement)