[Résolu]Capturer le temps et stopper son évolution.

Bonjour,

Je reviens comme toujours avec un nouveau problème. C'est comme ça quand les projets prennent de l'ampleur, on bloque souvent ^^!

Voilà mon problème :

Est-il possible de capturer le temps dans une variable et empêcher que cette variable temps évolue ?

Lorsque je fais ceci : temps = millis(); j'aimerai que temps garde sa valeur au moment où je lui affecte millis();

Le problème est que "temps" évolue constamment :( ! J'ai même essayer de réaffecter millis() à une autre variable du genre :

temps = millis();
temps2=millis();    // Pourquoi pas ^^

Mais bien sûr ça ne marche pas.

Je vous remercie.

Pourrais-tu donner ton code complet ?

Si tu affectes temps=millis(); dans loop, c'est mis à jour continuellement.

Soit tu affectes ce temps dans le setup() (et tu déclares "temps" comme globale), soit tu définis un booléen que tu mets à true dès que tu as affecté temps, et tu vérifie que tu n'as pas affecté temps via ce booléen.

XavierMiller: Pourrais-tu donner ton code complet ?

Si tu affectes temps=millis(); dans loop, c'est mis à jour continuellement.

Soit tu affectes ce temps dans le setup() (et tu déclares "temps" comme globale), soit tu définis un booléen que tu mets à true dès que tu as affecté temps, et tu vérifie que tu n'as pas affecté temps via ce booléen.

Il est assez long voire très long mon code. La situation est la suivante : J'ai un bouton qui doit rester appuyé pour faire tourner un moteur. Lorsque le bouton est laché le moteur doit s'arrêter et attendre 2 secondes. Si au bout de 2 secondes le bouton n'est pas re-appuyé le programme fait autre chose. Et le problème c'est justement capturé l'instant où le bouton est lâché pour faire les 2 secondes. Je sèche...

Pas bien compliqué en fait.

1- Appui sur le bouton
2- Rotation moteur.

3- Si bouton “On” puis “Off” → arrêt moteur, mise en route du chrono

4- Si millis() - chrono >= 2000, on fait aut’chose.

@+

Zoroastre.

zoroastre:
3- Si bouton “On” puis “Off” → arrêt moteur, mise en route du chrono

4- Si millis() - chrono >= 2000, on fait aut’chose.

Justement comment tu mets le “chrono” en route (pour reprendre ton expression) ?

Sachant que si tu fais chrono=millis(); ça ne marchera pas.

Merci

Comment définirais-tu un chrono ?

Pour afficher un temps relatif, il faut connaître l'heure du start (chrono = millis()) et l'heure courante (millis), et le nombre de secondes écoulées comme... [A suivre]

On suppose qu'à l'instant "t" mon bouton est lâché, j'active donc mon chrono, chez arduino ça veut dire :

chrono=millis();

Pour dire que 2 secondes se sont écoulées, l'idée serait de faire : if(millis()-chrono>2000) { .... }. C'est ce qui me semble logique sauf que ça ne marche pas malheureusement parce que "chrono" évolue en même temps que millis(). Ce n'est pas une valeur figée et donc (millis()-chrono) = 0 tout le temps. Ce qui m'embête parce que je ne peux capturer l'instant où le bouton est relaché .

Bonjour, donc pour resumer, tu refuses de donner ton code mais tu demandes que l'on trouve une erreur dans ton code !! Logique ? Jacques

Bonjour,

akuma8: Justement comment tu mets le "chrono" en route (pour reprendre ton expression) ?

Sachant que si tu fais chrono=millis(); ça ne marchera pas.

Merci

Tu dois préciser une condition où le chrono débute. Comme je te l'ai préciser plus haut, tu dois en premier lieu détecter l'appui sur le bouton puis ensuite son relâchement. Seulement lorsque ces 2 conditions sont remplies, tu sauvegardes millis() dans la variable chrono. Cette variable n'évoluera pas si les conditions ne sont pas à nouveau remplies. Il te reste en suite à faire plus loin dans ton code, la soustraction entre le temps qui continue à défiler (fonction millis()) et la sauvegarde temporelle chrono.

1- Appui sur le bouton 2- Rotation moteur.

3- Si bouton "On" puis "Off" -> arrêt moteur, mise en route du chrono

4- Si millis() - chrono >= 2000, on fait aut'chose.

un truc du genre...

unsigned long chrono = 0, timer = 0;
byte etat = 0, etat_precedent = 0, chrono_start = 0;

void setup() { }
void loop()
{
    byte _bouton = digitalRead(bouton); // lecture du bouton

    if (_bouton == 1) { etat = 1; rotation_moteur(); }
    if (_bouton == 0 && etat == 1) { 

          arret_moteur();
          
          if (etat =! etat_precedent) { timer = millis(); chrono_start = 1; etat_precedent = etat; }
    }

    if (chrono_start) { if (millis() - timer > 2000) { action(); chrono_start = 0; chrono = (millis() - timer) / 1000; etat = 0; etat_precedent = 0; }

}

Pas trés propre ni testé...mais l'idée est là.

Le fonction de chronomètre est effectué par timer et chrono_start. La variable chrono divisée par 1000 peut servir à renvoyer le temps écoulé depuis l'arrêt du moteur (elle sera de toute façon égale à 2 sec).

L'astuce principale se situe au niveau des états, on utilise 2 variables etat et etat_precedent pour dire au programme de sauter une partie du code déjà réalisée une fois, puisque etat = etat_precedent. Ainsi, la variable temp est réalisée une seule fois et enregistre le moment exprimé par millis() à un instant t.

Ce type de programmation est indispensable si l'on ne veux pas répéter des commandes inutiles, enclencher maintes fois un moteur, un relais, etc.

Observe la différence entre ces 2 bouts de code ci-dessous :

if (bouton) { variable_mémoire(); }
if (bouton) { etat = 1; if (etat =! etat_precedent) { variable_mémoire(); etat_precedent = etat; }

Dans le premier cas, tu commandes la variable mémoire à chaque cycle si la condition est obtenue. Dans le second cas, tu commandes une seule fois la variable mémoire tant que les variables etat et etat_precedent sont egales. Elles sont différentes, on commande ; elles sont égales, on ne commande plus.

Ça permet de conserver une action, une variable en l'état, de la mémoriser tant que l'on ne change pas les conditions. J'utilise beaucoup cette manière de faire dans mes programmes.

@+

Zoroastre.

N'ayant pas tout saisi de ton code Zoroastre, j'ai voulu faire autrement, voici une partie de mon code :

if(_bouton){

     mode_f=1;
     moteurTourne();
}

else { // Bouton fermeture est laché

       if(mode_f){
        // Bip Bip Bip Bip
        Serial.println("BOUTON FERMETURE LACHE                         !!!!!!");
        digitalWrite(V,LOW);
        arretMoteur();
                tmp=millis(); // Variable juste pour voir l'instant où on a laché le bouton 
                chrono_start=1;

         }

         if (chrono_start)
      { 
          if(millis()-capture > 2000) // Condition toujours vraie :( 
                 {
           digitalWrite(R,HIGH); 
           //delay(20);
           Serial.println("!!!!!!!!!!!! 2 SECONDES SE SONT ECOULEES TROP TARD     !!!!!!");
           //chrono=(millis()-capture)/1000;   /*Je ne l'utilise pas parce que je ne sais pas trop le pourquoi de cette variable*/
                   chrono_start =0;
           mode_f=0;
                   capture=millis();
                   travail();
          }    
       }

 }

Sauf que j'ai l'impression que ça va trop vite, il faut peut-être que je revois l'initialisation de ma variable capture. Je te remercie en tout cas, je vais bien analyser ton code parce que ça m'a l'air assez astucieux, pour l'inclure dans mon programme. Merci en tout cas.

Yep!

Ça m'a l'air pas trop mal, sauf que effectivement dans ton bout de code on ne voit pas la variable capture.

L'initialisation doit se faire, à mon humble avis, au moment du relâchement du bouton. Si tu remplaces capture par tmp, ça doit aller mieux.

@+

Zoroastre.

Re :) !

ça a l'air de marché mais je préfère largement ta méthode ! Je viens de comprendre comment tu procèdes et ce n'est pas mal du tout ;) !

if (bouton) { etat = 1; if (etat =! etat_precedent) { variable_mémoire(); etat_precedent = etat; }

Tu y accèdes une fois et seulement une fois, ça marche comme un verrou, bien vu bien vu ;) ! Par contre la division "chrono = (millis()-capture)/1000"... Je ne vois toujours pas l'utilité...

Merci en tout cas...

Impec! ;)

Ce n'est pas toujours facile d'expliquer ce qui semble simple pour moi. Je suis content que tu ais compris l'astuce.

En fait, chrono = (millis()-capture)/1000 sert simplement à afficher le chrono en seconde si le besoin se faisait sentir.

@+

Zoroastre.

zoroastre: Je suis content que tu ais compris l'astuce.

Moi aussi parce que je compte l'utiliser souvent maintenant ;) !

zoroastre: En fait, chrono = (millis()-capture)/1000 sert simplement à afficher le chrono en seconde si le besoin se faisait sentir.

Zoroastre.

Dac, pourquoi pas, on ne sait jamais :)!

Je mets résolu vu que je ne vois pas la touche où cliquer pour indiquer que c'est résolu ^^ !

Merci

Il faut éditer ton premier message, et ajouter [RESOLU] au titre du topic.

Bonjour,

akuma8: Je mets résolu vu que je ne vois pas la touche où cliquer pour indiquer que c'est résolu ^^ !

Pour mettre en résolu, il faut éditer ton premier topic et insérer [résolu] dans le titre du topic