Remplacer mes "Delay" en "Millis"

Bonsoir au forum Arduino FR !

Je suis à la recherche d'un petit bout de code pour remplacer mes "delay();" en millis.

J'ai lu pleins de trucs mais je n'arrive pas à le transposer sur mon code.

Avec un écran led sur lequel je développe des animations, j'écris mon code pour allumer ou non certaines led de ma matrice.
Image par image et un "delay();" entre elles, pour espacer mes "images".
Un peu comme du stop motion.

Ça ressemble à cela :

 dmd.clearScreen( true );
 dmd.drawFilledBox( 5, 3, 9, 60, GRAPHICS_NORMAL );
 delay(3);

 dmd.clearScreen( true );
 dmd.drawFilledBox( 6, 3, 10, 60, GRAPHICS_NORMAL );
 delay(3);

 dmd.clearScreen( true );
 dmd.drawFilledBox( 7, 3, 11, 60, GRAPHICS_NORMAL );
 delay(3);

 dmd.clearScreen( true );
 dmd.drawFilledBox( 8, 3, 12, 60, GRAPHICS_NORMAL );
 delay(200);

Ça marche super, sauf que dans mon projet j'ai intégré un bouton pour changer d'animation.. d'où l'importance du "millis();"

Le delay(); bloque la lecture de mon Arduino et par conséquent la lecture de l'état de mon bouton.

J'utilise la function delay pour laisser l'image un certain moment sur mon écran avant de l'effacer pour laisser place à l'image suivante.

Merci de votre aide :wink:
Et vive la communauté Arduino !

Salut

Un truc "sale" qui doit marcher ... si c'est pas le cas , désolé mais c'est la fin du wknd .

A remettre en ordre ..

// dans le setup
// top  = millis();
////

boolean STEP1 = false;
boolean STEP2 = false;
boolean STEP3 = false;
boolean STEP4 = false;

//loop

dmd.clearScreen( true );
dmd.drawFilledBox( 5, 3, 9, 60, GRAPHICS_NORMAL );
if (STEP1 == false) {
  top = millis();
}
STEP1 = true;
t1 = millis();

if ((t1 - top) >= 3) && (STEP1 == true))
{

  dmd.clearScreen( true );
  dmd.drawFilledBox( 6, 3, 10, 60, GRAPHICS_NORMAL );
  if (STEP2 == false) {
    top = millis();
  }
  STEP2 = true;
  t1 = millis();

  if ((t1 - top) >= 3) && (STEP2 == true))
  {

    dmd.clearScreen( true );
    dmd.drawFilledBox( 7, 3, 11, 60, GRAPHICS_NORMAL );
    if (STEP3 == false) {
      top = millis();
    }
    STEP3 = true;
    t1 = millis();

    if ((t1 - top) >= 3) && (STEP3 == true))
    {

      dmd.clearScreen( true );
      dmd.drawFilledBox( 8, 3, 12, 60, GRAPHICS_NORMAL );
      if (STEP4 == false) {
        top = millis();
      }
      STEP4 = true;
      t1 = millis();

      if ((t1 - top) >= 200) && (STEP4 == true))
      {

        STEP1 = false;
        STEP2 = false;
        STEP3 = false;
        STEP4 = false;
      }
    }
  }
}

Une autre possibilité (à creuser) peut-être plus simple, serait de remplacer les delay par une fonction à toi qui surveille le bouton (je le suppose connecté en INPUT_PULLUP)

bool myDelay (int duration) {
 unsigned long chrono = millis();
 bool button = true;
 while (millis() - chrono < duration) { 
   button = digitalRead(pinButton);  // mettre ici le numéro de la pin
   if (!button) {
     delay (15); // debounce : à enlever si trop long pour ton delai
// Ici les actions si le bouton est appuyé (sinon, tu peux les faire dans la loop après l'appel de la fonction
   }
 }
return !button; // renvoie true si appuyé, false si pas appuyé
}

Pas nécessaire de l’appeler pour des durées trop faibles (typiquement qq ms)

Merci de vos conseils, je vais essayer toutes vos propositions !

Une autre solution c'est de mettre la lecture du bouton par fonction d'interruption. Autant je trouve cela compliqué pour mettre en place un timer, autant je trouve cela simple pour un bouton. Il faut regarder du côté de attachInterrupt()

Il ne faut pas que tout soit bloquant, mais cela ne sert pas forcément à grand chose d'avoir que des fonctions non bloquantes. Si le programme fonctionne et est bloquant qu'on le garde, et c'est le bouton que l'on va libérer.