Timer

Bonjour,

Je cherche a créer un programme, je souhaite lancer un timer a un moment donné qui compte 90 seconde et qui s arrete.

En gros

If moncapteur = true
Elese wait
If moncapteur = false
compte 90 sec

quelqu'un peut il me donner un ptit coup de main ?

tu a:

delay(90000); //(qui attend 90sec)bloquante

ou

unsigned long time1,time2;

time1=milis();

if (time1>=(time2+90000)) // non bloquante !
{time2=millis();}

L'utilisation de delay() pour ce genre de chose est a proscrire car tu bloques ton CPU à ne rien faire pendant ce temps.
Tu ne peux pas utiliser ce temps perdu pour une autre tâche.

Regarde la bibliotheque SoftTimer que j'ai publié dans la partie Tuto du forum. Elle permet de gérer facilement des timeout, taches repetitives,.. Et autres fonctions basées sur le temps sans utiliser de timer hardware.

Sinon après si tu préfère utiliser un timer hardware, tu peux chercher la bibliotheque TimerOne sur le playground.

@skizoh
Ton code part sur une bonne idée mais il est faux. Tu compare avec milli2 qui est lu après.
De plus ton if va poser un problème au moment ou millis() va reboucler. Il faut écrire la comparaison comme ci dessous.
Je suggère :

unsigned long time_start;
enum { ATTENTE, EN_COURS } etat = ATTENTE;
void loop()
{
  switch( etat )
  {
  case ATTENTE:
    if ( mon_capteur() == false )
    {
      // demarrage du comptage de 90 secondes
      time_start = millis();
      etat = EN_COURS;
    }
    break;
  case EN_COURS:
    if ( (millis() - time_start) >= 90000 )
    {
      // fin des  90 secondes
      etat = ATTENTE;
      // faire ce qu'il y a a faire au bout des 90 secondes
      // ....
    }
    break;
  }
}

Oups, j'ai encore réussi à coller un exemple basé sur une machine d'état :wink:

Bonjour,

SuPeRBaLoO:
Je cherche a créer un programme, je souhaite lancer un timer a un moment donné qui compte 90 seconde et qui s arrete.

En gros

If moncapteur = true
Elese wait
If moncapteur = false
compte 90 sec

quelqu'un peut il me donner un ptit coup de main ?

Regarde cest deux tutoriels du playground :

lol, non sérieux sa marche ce truc je m'en sert pour l'heure et moyennant +6 secondes par heure je ne prend pas de retard, mais le tien est nettement plus propre on est d'accord surtout que je partage ton avis sur les machines d'états, c'est "LA BASE !" ^^' bref aujourd'hui j'ai testé mon système de gestion de ronde sur le terrain, je vais en faire le résumé, mais en tout cas tout c'est bien passé ! :smiley:

Skizo !

Si tu dois gérer un évenement périodique, il ne faut pas reprendre l'heure de départ a chaque fois.

Par exemple ce code est mauvais :

unsigned long temps_ref;
#define PERIODE 10000

void setup()
{
  temps_ref = millis();
}

void loop()
{
  if ( (millis() - temps_ref) >= PERIODE )
  {
    // Evenement !
    // .... faire ce qu'il y a a faire ...
    // pour le prochain
    temps_ref = millis();
  }
  // Autre tâches
  // .....
}

Pourquoi ce code là n'est-il pas bon ?
Par ce que tu reprend le temps de référence de manière absolue.
Or si tu perd un peu de temps dans les autres tâches tu viendras traiter l'évenement en retard.
Et donc tu reprend une nouvelle date de départ décalée.
Ce qui implique une dérive permanente, une horloge qui retarde.

Dans ma lib SoftTimer c'est écrit de la manière suivante :

void loop()
{
  if ( (millis() - temps_ref) >= PERIODE )
  {
    // Evenement !
    // .... faire ce qu'il y a a faire ...
    // pour le prochain
    temps_ref += PERIODE;
  }
  // Autre tâches
  // .....
}

Ce principe permet de toujours garder une période moyenne égale à PERIODE, parce que tu recalcule un nouveau temps de référence qui est décalé de la valeur exacte de ta période.

A+

lol ok ok, bref tant fait je n'utilise pas trop millis en général c'est trop peux précis puis en plus au bout des 70h ou je sais plus combien ça boucle et revient donc à 0 donc petit problème a ce moment la :s bref merci de tes explications :slight_smile:

Skizo !

Interro écrite.
Dis moi exactement au bout de combien de temps reboucle millis() et au bout de combien de temps reboucle micros().
Calculatrice autorisée.

barbudor:
Interro écrite.
Dis moi exactement au bout de combien de temps reboucle millis() et au bout de combien de temps reboucle micros().
Calculatrice autorisée.

millis() : rollover aprés 4294967296 millisecondes, soit 4294967 secondes, soit 1193 heures, soit 49,71 jours :grin:
micros() : rollover aprés 4294967296 microsecondes, soit 4294967 millisecondes, soit 4294 secondes, soit 71,58 minutes :grin:

J'ai droit à un cookies ? :stuck_out_tongue:

Ps: au passage il existe plein de méthodes pour détecter un rollover de millis() ou de micros(), exemple : http://www.faludi.com/2007/12/18/arduino-millis-rollover-handling/

Skywodd, tu n'es pas dans cette classe !
Laisse les petits répondre :smiley:

barbudor:
Skywodd, tu n'es pas dans cette classe !
Laisse les petits répondre :smiley:

Mais heu ... faut bien que je trouve une utilité à la calculette windows !
T'as pensé à tout les dév µsoft qui ont passé des semaines à débugger (sans sucées) la calculette Windows ? :grin:

merci pour vos reponses j essaye ce code :

seulement ca ne fonctionne pas

#include <NXTTouch.h>
#include <Wire.h>
#include <NXShield.h>
#include <NXTTouch.h>
#include <NXTLight.h>
#include <SumoEyes.h>
#include <ACCLNx.h>
#include <NXTUS.h>

//
// declare the NXShield(s) attached to your Arduino.
//
NXShield    nxshield;

//
// declare the i2c devices used on NXShield(s).
//

//
// declare analog devices attached to nxshields.
//
NXTTouch    touch1;

 
  

unsigned long time_start;
enum { ATTENTE, EN_COURS } etat = ATTENTE;
void loop()
{
  switch( etat )
  {

  nxshield.init( SH_SoftwareI2C );
  touch1.init( &nxshield, SH_BBS1 );

  
  case ATTENTE:
    if ( touch1() == false )
    {
      // demarrage du comptage de 90 secondes
      time_start = millis();
      etat = EN_COURS;
    }
    break;
  case EN_COURS:
    if ( (millis() - time_start) >= 90000 )
    {
      // fin des  90 secondes
      etat = ATTENTE;
      // faire ce qu'il y a a faire au bout des 90 secondes
      // ....
    }
    break;
  }
}

Qu'est-ce qui ne marche pas ?
Soit plus précis.

Où est setup() ?
Pourquoi les fonctions d'init ne soit pas dans setup() au lieu d'être dans loop() ?

Où est le reste du code ?
Par ce que le peu que tu en montre va pas faire grand chose à part compter 90 secondes....

En fait je débute dans la programmation.

J explique mon cas, j'encadre une equipe de jeune qui va participer a la coupe de france de robotique. Moi meme je participe depuis quelques années, cependant je m'occupe de la mécanique et pas de la programmation.

Nous avons monté une structure en lego, et nous souhaitons la programmer avec une carte arduino : http://www.generationrobots.com/carte-arduino-mega-adk-pour-android,fr,4,ARDUINO-MEGA-ADK.cfm

et un nxt shield : http://www.generationrobots.com/nxshield-m-pour-arduino-mega-ou-arduino-adk-mindsensors,fr,4,NXShield-M-Arduino.cfm

le programme que je souhaite créer serait de la sorte :

- Programme en attente
- Choix de la couleur avec le bouton de nxt-shield - allumage de la led selon la couleur choisis
- si couleur = bleu -> programme bleu sinon -> programme rouge
- Programme Bleu
- Programme en attente
- Si touch 1 = true else :

- démarrage chrono 90 seconde (si chrono = 90 seconde alors on arrête tout)
- sous programme détection avant on
- sous programme avancer de 100 pas
- sous programme detection off
- sous programme tourner a droite de 45°
- sous programme détection avant on
- sous programme reculer de 20 pas
etc ...

si touch1 = false else on arrête tout : arrêt d'urgence
Void(détection avant on)

allumer le capteur sonar et vérifier tout les 10 ms que la distance de détection est inférieur a 30 cm sinon mettre programme en attente jusqu’à a que détection fini
- Void (avancer de x pas)

allumer les moteur en marche avant a vitesse 2
compter x pas sur les codeurs
a x pas -20% rallentir les moteur a vitesse 1
 a x pas arreter les moteur
- Void ( programme détection off)

éteindre le capteur sonar
- Void (tourner a droite de 45°)

allumer moteur 1 en marche avant et moteur 2 en marche arrière
compter x pas sur codeur 1 et -x pas sur codeur 2
a x pas -20% ralentir les moteur a vitesse 1
a x pas sur codeur 1 et -x pas sur codeur 2
- Void( reculer de X pas)

allumer les moteur en marche arriere a vitesse 2
compter -x pas sur les codeurs
a -x pas -20% ralentir les moteur a vitesse 1
a -x pas arrêter les moteur

barbudor: et mince il ma pris de cour je serais plus le chouchou du prof euhh :frowning: lol

Et SuperBaloO euh.. comment te dire que ton programme est faisable mais qu'on te ne le fera pas? on aide mais on fait pas ici !! lool ^^ essaye de faire des premières version et viens vers nous avec des problèmes concret pas des je voudrais faire ça.. et je sais pas le faire ^^ mais je comprend tes soucis les début en C c'est jamais onctueux :p, reviens avec une vrai problématique la tu en est a la phase conception pas dépannage, nous on sera la pour corrigé ton code une fois fait ^^

ps: le copier coller bête et méchant ça na rien de bon !!

Skizo !

alors mes premieres problématique :

comment fait on un appel de fonction ?

skizoh:
ps: le copier coller bête et méchant ça na rien de bon !!

Skizo !

Merci, je suis pas programmeur, mais j ai quelques notions quand meme

lol te vexe pas :wink:

alors appel de fonction:

Fonction:

void hello_word (String hello)
{String hello;

Serial.print(hello);

return 0;
}

appel:

String envoyer ="saluuut";
hello_word(envoyer);

résultat: 

sur la liaison série: saluut

si ta fonction n'a pas besoin de paramètre:

void attendre()
{
delay(10000);//attend 10s
}  

appel:

attendre();//attend 10s

voila tout simplement =)

Skizo !

j ai fait un ptit essai avec quelque chose de cette structure la

#include <Wire.h>
#include <NXShield.h>
#include <NXTTouch.h>
#include <NXTLight.h>
#include <SumoEyes.h>
#include <ACCLNx.h>
#include <NXTUS.h>


//
// declare the NXShield(s) attached to your Arduino.
//
NXShield    nxshield;

//
// declare the i2c devices used on NXShield(s).
//

//
// declare analog devices attached to nxshields.
//
NXTTouch    touch1;


Void main()
{str= 100
serial.void(avancer)

}








Void Avancer()
{
    // Drive both motors forward and backward for a specific number of
    // rotations
    delay(1000);
    sprintf(str, "Both Motors Forward %d Rotations", rotations);
    Serial.println(str);
    str[0] = '\0';
    nxshield.bank_a.motorRunRotations(SH_Motor_Both, 
                     SH_Direction_Forward,
                     SH_Speed_Medium, 
                     rotations, 
                     SH_Completion_Wait_For,
                     SH_Next_Action_BrakeHold);
    delay(1000);
    sprintf(str, "Both Motors Reverse %d Rotations", rotations);
    Serial.println(str);
    str[0] = '\0';
    nxshield.bank_a.motorRunRotations(SH_Motor_Both, 
                     SH_Direction_Reverse,
                     SH_Speed_Medium, 
                     rotations, 
                     SH_Completion_Wait_For,
                     SH_Next_Action_BrakeHold);

    Serial.println("Bank B motors >>");
    
}

alors:

#include <Wire.h>
#include <NXShield.h>
#include <NXTTouch.h>
#include <NXTLight.h>
#include <SumoEyes.h>
#include <ACCLNx.h>
#include <NXTUS.h>


//
// declare the NXShield(s) attached to your Arduino.
//
NXShield  nxshield;


//
// declare analog devices attached to nxshields.
//
NXTTouch  touch1;


Void main()
{
str= 100
avancer(str);// comme ça l'appel de fonction avec paramètre 

}




Void Avancer(int str)
{
int str;

    // Drive both motors forward and backward for a specific number of
    // rotations
    delay(1000);
    sprintf(str, "Both Motors Forward %d Rotations", rotations);
    Serial.println(str);
    str[0] = '\0';//bon reflex =)
    nxshield.bank_a.motorRunRotations(SH_Motor_Both, 
                     SH_Direction_Forward,
                     SH_Speed_Medium, 
                     rotations, 
                     SH_Completion_Wait_For,
                     SH_Next_Action_BrakeHold);
    delay(1000);
    sprintf(str, "Both Motors Reverse %d Rotations", rotations);
    Serial.println(str);
    str[0] = '\0';
    nxshield.bank_a.motorRunRotations(SH_Motor_Both, 
                     SH_Direction_Reverse,
                     SH_Speed_Medium, 
                     rotations, 
                     SH_Completion_Wait_For,
                     SH_Next_Action_BrakeHold);

    Serial.println("Bank B motors >>");
    
}

sinon c'est pas faut mais il faut un pointeur, ou un str défini en globale pour qu'il sois aussi présent dans ta fonction..

Voila.

Skizo !