web-dev-qa-db-fra.com

Exécuter une fonction après x heure

Que puis-je utiliser pour exécuter une fonction dans la boucle si aucune des autres conditions de la boucle et leur code n'ont été exécutés après un certain temps? Cela peut-il être fait avec un délai, ou existe-t-il une autre fonction?

10
Markaj

Je ne pense pas qu'il soit possible de l'implémenter car l'Arduino n'a pas d'horloge interne.

EDIT: Il est possible d’utiliser la fonction millis () pour calculer une durée écoulée depuis le début du tableau:

unsigned long previousMillis = 0; // last time update
long interval = 2000; // interval at which to do something (milliseconds)

void setup(){
}

void loop(){
  unsigned long currentMillis = millis();

  if(currentMillis - previousMillis > interval) {
     previousMillis = currentMillis;  

     // do something
  }
}
9
ndeverge

Essayez des interruptions de minuterie Arduino. Pas besoin de bibliothèques externes ni même de matériel supplémentaire, car le processeur peut être considéré comme une horloge ... à 16 MHz.

#include <avr/io.h>
#include <avr/interrupt.h>

void setup ()
{

  // INITIALIZE TIMER INTERRUPTS
  cli(); // disable global interrupts

  TCCR1A = 0; // set entire TCCR1A register to 0
  TCCR1B = 0; // same for TCCR1B

  OCR1A = 15624; // set compare match register to desired timer count. 16 MHz with 1024 prescaler = 15624 counts/s
  TCCR1B |= (1 << WGM12); // turn on CTC mode. clear timer on compare match

  TCCR1B |= (1 << CS10); // Set CS10 and CS12 bits for 1024 prescaler
  TCCR1B |= (1 << CS12);

  TIMSK1 |= (1 << OCIE1A); // enable timer compare interrupt

  sei(); // enable global interrupts

}

// TIMER VECTOR, gets called once a second (depends on prescaler and match register)
ISR(TIMER1_COMPA_vect)
{
  // do your timeing based stuff here
}

besoin de plus d'informations sur les interruptions?

5
mrv

Mon ami delay () et delayMicroseconds () sera toute l'aide dont vous aurez besoin.

En ce qui concerne les autres réponses sont concernés.

mills () - Retourne le nombre de millisecondes depuis que la carte Arduino a commencé à exécuter le programme en cours. Ce nombre débordera (reviendra à zéro) après environ 50 jours.

Voir: http://arduino.cc/en/Reference/millis

De même,

micros () - Retourne le nombre de microsecondes depuis que la carte Arduino a commencé à exécuter le programme actuel. Voir: http://arduino.cc/en/Reference/Micros

Je suppose que vous avez besoin de travailler un peu sur ces deux pour résoudre votre problème.

1
Zeeshan Ali

Je pense que c'est ce que vous cherchez

http://playground.arduino.cc/Code/time

1
Kreker

Essayez la Metro library , qui vous permet d’organiser des événements chronologiques récurrents. Vous pouvez modifier la fréquence de la minuterie dans la boucle, si cela est souhaitable.

1
Dang Khoa

Il existe de nombreuses versions de ces routines de minuterie, toutes supposent que si vous avez atteint ou dépassé le délai d'attente, vous réinitialisez la variable de minuterie à l'aide de millis (). Faux. Que se passe-t-il si vous avez été occupé et que vous avez dépassé de loin la plage horaire, le lot est maintenant épuisé.

Alors disons que nous voulons faire quelque chose toutes les 50ms. Disons que nous avons été bloqués et qu'il est maintenant 55 ms après la dernière vérification .. nous vérifions… nous sommes suffisamment sûrs d'écraser la variable timer pour que nous puissions obtenir une correspondance dans 50 ms. mais maintenant nous sommes 5ms en retard. Nous devons compenser les retards et ce qu'il se passera s'il y a débordement à ce stade ...

1
Peter Scargill

Vous pouvez utiliser l'exemple de code ci-dessous.Voici répétez les étapes toutes les 1 ms.

#include <SimpleTimer.h>

// the timer object
SimpleTimer timer;

// a function to be executed periodically
void repeatMe() 
{
  Serial.print("Uptime (s): ");
  Serial.println(millis() / 1000);
}

void setup()
{
  Serial.begin(9600);
  timer.setInterval(1000, repeatMe);
}

void loop() 
{
  timer.run();
}
1
AMPS

Une minuterie qui survivra au redémarrage de l’Arduino est impossible à implémenter sans composants externes. Le problème est qu’il n’ya aucun moyen de savoir combien de temps la réinitialisation a été déclenchée. De plus, le chargeur de démarrage peut utiliser une quantité de temps inconnue lors du redémarrage. Ainsi, vous auriez besoin d'une horloge temps réel externe.

En ce qui concerne l'exécution périodique des événements, mon favori est la bibliothèque msTimer2. voir ici pour certains de mes exemples:

http://blog.blinkenlight.net/experiments/basic-effects/persistence-of-vision/

http://blog.blinkenlight.net/experiments/removing-flicker/heartbeat/

http://blog.blinkenlight.net/experiments/basic-effects/lighthouses/

1
Udo Klein

La fonction millis() fonctionne normalement assez bien pour cela, à moins que vous ne vouliez que le délai d’attente survive au redémarrage de l’arduino.

Je mettrais en œuvre une classe Timer qui garde la trace de la dernière fois que some_condition a été rencontré:

class Timer
{
public:
    Timer(void);
    void set_max_delay(unsigned long v);
    void set(void);
    boolean check(void);
private:
    unsigned long max_delay;
    unsigned long last_set;
};

Timer::Timer(void)
{
    max_delay = 3600000UL; // default 1 hour
}

void Timer::set_max_delay(unsigned long v)
{
    max_delay = v;
    set();
}

void Timer::set()
{
    last_set = millis();
}

boolean Timer::check()
{
    unsigned long now = millis();
    if (now - last_set > max_delay) {
        last_set = now;
        return true;
    }
    return false;
}

Timer timer;

void setup()
{
   timer.set_max_delay(60000); // 1 minute
}

void loop()
{
   boolean some_condition = false;
   if (some_condition) {
       timer.set();
   }
   if (timer.check()) {
      // nothing happened for a long time
   }
   delay(500);
}

Tant que some_condition n'est pas atteint, la valeur last_set du temporisateur n'est pas mise à jour. En fin de compte, la fonction check() renvoie true (une fois par intervalle, car check() définit la valeur last_set)

Si la vérification doit survivre à une réinitialisation du processeur, vous avez besoin d'une horloge sauvegardée sur batterie (temps réel), puis stockez et récupérez le last_set de l'EEPROM.

1
Anthon