Je partage mon code, car il me rend de très grands services. Si quelqu'un se sent d'en faire une lib, qu'il ne se gêne pas!
Qu'est-ce que ça fait?
Ca lance la fonction de son choix au bout d'un certain temps, sans bloquer le reste du code. Une bonne alternative à la fonction delay().
Ca monopolise quoi?
Le timer 2, donc toutes les libs temporelles utilisant le timer2 seront en conflit (lib servo par exemple).
Utilisation : on copie ce code dans le sketch (de préférence au début)
/************************
* Lancements retardés *
************************/
/********************************************************
* Permet de lancer une void au bout d'un certain temps *
* exprimé en millisecondes (max 65 535 ms, soit 1min et 5 sec).*
********************************************************/
// il est possible d'augmenter le temps max en déclarant ms et T2_cmpt en long
// (on atteint alors plus de 4 milliards de ms, soit plus de 1 110 heures...)
#include <arduino.h>
#ifdef __cplusplus
extern "C"{
#endif
typedef void (*voidFuncPtr)(void);
#ifdef __cplusplus
} // extern "C"
#endif
static volatile voidFuncPtr launch_void; // fonction à lancer
volatile word T2_cmpt;
void delay_void(word ms, void (*userFunc)(void)) {
launch_void = userFunc; // prise en compte de la fonction à utiliser
TCCR2A = 0x02; // mode CTC sur OCR2A
TIMSK2 = 0x02; // autoriser int OC2A
OCR2A = 125; // 125 x 8µs = 1ms
TCNT2 = 0; // RAZ timer
T2_cmpt = ms; // initialiser le décompte
TCCR2B = 0x05; // lancer le timer 2
}
ISR(TIMER2_COMPA_vect) { // interruption appelée toutes les 1ms
T2_cmpt--;
if(T2_cmpt == 0) { // on est arrivé au bout du décompte?
TCCR2B = 0x00; // arrêter le timer
if(launch_void) launch_void(); // lancer la void
launch_void = 0;
}
}
dans le sketch, il suffit d'appeler la void delay_void(), par exemple :
void maFonction() {
digitalWrite(13, HIGH); // allumer la led pin 13
}
void loop() {
(...) faire des trucs
if(bouton == appuyé) {
digitalWrite(13, LOW); // éteindre la led
delay_void(10000, maFonction); // allumera la led 13 dans exactement 10 secondes
}
(...) faire d'autres trucs
}
Lors de l'appui sur le bouton, ça éteindra la led si elle est déjà allumée, ça déclenchera la minuterie et le reste du code continuera à tourner (faire d'autres trucs, puis faire des trucs). Au bout de 10 secondes, maFonction() sera exécutée, donc la led s'allumera toute seule.
Je l'utilise pour faire du débounce sur un clavier : dans la fonction qui lit les touches du clavier, ça interdit toute prise en compte des évènements du clavier, ça lance la minuterie et ça retourne direct à la suite du programme. au bout de cette minuterie, la fonction se contente de réactiver le clavier, alors que le reste du programme a déjà repris son cours. Perso, je suis très fier de moi!
EDIT du 24/10/2015 : erreur au niveau de delay_void(), corrigé.