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?
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
}
}
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
}
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.
Je pense que c'est ce que vous cherchez
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.
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 ...
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();
}
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/
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.