J’ai besoin d’un délai précis (1 à 20 ms environ) entre la détection d’une interruption (INT n° 1) et le passage de la sortie de commande à l’état haut.
L’extrait de code concerné se présente comme suit :
void setup() {
//… code
attachInterrupt(1, detectedSignal, RISING);
flagOK =0;
//Suite du code
}
void loop()
{
//Autre code
doFlash() ;
/ /Site du code
}
//*****Fonctions********
void detectedSignal()
{
flagOK = 1;
}
void doFlash()
{
if (flagOK ==1)
{
delay(flashDelay); //retard d’activation du flash.
digitalWrite(digitalFlashOutput, HIGH); //Flash activé
delay(flashDuration); //Juste pour les besoins du flash
digitalWrite(digitalFlashOutput, LOW); //Flash désactivé.
flagOK = 0;
//Suite du code
}
}
La fonction activée dès détection de l’interruption est « detectedSignal() » ; pour être aussi courte que possible, elle positionne le drapeau « flagOK » à 1 .
La fonction « doFlash () » se trouvant dans la boucle « loop » n’est donc exécutée que si « flagOK » est à 1.
Du fait de l'appel des 2 fonctions (interruption et doFlash()), le délai nécessaire à Arduino entre l’apparition de l’interruption et l'exécution de la ligne « delay(flashDelay); » ne sera-t-il pas prépondérant par rapport au délai précis demandé ?
Eventuellement, existe-t-il un moyen plus évolué de réaliser ce délai ?
L’électronique de commande est pas finalisée mais je ne pourrais vérifier ce délai qu’en réalisant des photos…
J’ai besoin d’un délai précis (1 à 20 ms environ) entre la détection d’une interruption (INT n° 1) et le passage de la sortie de commande à l’état haut.
...
Eventuellement, existe-t-il un moyen plus évolué de réaliser ce délai ?
L’électronique de commande est pas finalisée mais je ne pourrais vérifier ce délai qu’en réalisant des photos…
Cordialement.
Bonsoir
déjà utiliser delay() pour gerer de la ms va te contraindre à seulement 20 pas possible .
pour obte,ir une resolution plus fine , il faut passer par delayMicroseconds() qui offre pour un arduino basique une résolution de 4µs.
L'utilisation de digitalWrite() n'est pas non plus très adaptée. Il faudrait utiliser la librairie digitalWriteFast ou écrire directement dans les ports d'entrée/sortie
En plus d'utiliser les fonction "delay" pur "Arduino" il est possible d'utiliser celle de l'AVR-LIBC.
L'avr-lib est la base du système de programmation des micros utilisés par Arduino.
Merci Artouste, fdufnews et 68tjs pour vos réponses.
Désolé pour le retard à la réponse, mais j’avais omis de cocher la notification automatique de réponse dans le profil…
Pour Artouste
La précision de delay() varie suivant les forums :
entre 4 microsondes pour une horloge de 16 MHz ;
à 2 mS (!) avec la nouvelle version de delay(). Oups…
Je vais donc utiliser une ligne du style :
long depart = millis();
si les résultats ne sont pas concluants.
Pour fdufnews
J’ai ressorti le livre « Programmation en C des microcontrôleurs RISC AVR » de Florian Schaeffer qui traite, entre autre, de l’écriture directe dans les DDRx et PORTx.
Du temps sera donc gagné entre la fin du délai et l’activation de la sortie à l’état haut. D’après les informations recueillies sur le web, on peut espérer une réduction du temps de commutation de 46 fois.
Je vais regarder "digitalWriteFast" que je ne connaissais pas ; merci pour cette information.
En tous cas, je modifie le code avec DDRx et PORTx.
Pour 68tjs
J’avais déjà rencontré ce lien, mais il a été oublié dans le fond du cerveau. Je réactive cette zone cérébrale et surtout ce site ! Merci également.
Le montage avance (voir photo ci-dessous).
Une partie est propre (circuits verts) ; reste la partie électronique à câbler en dur… Détection de mircobruit par électret, de passage par IR et microchoc par piézo.
standardUser:
Merci Artouste, fdufnews et 68tjs pour vos réponses.
Désolé pour le retard à la réponse, mais j’avais omis de cocher la notification automatique de réponse dans le profil…
Pour Artouste
La précision de delay() varie suivant les forums :
entre 4 microsondes pour une horloge de 16 MHz ;
à 2 mS (!) avec la nouvelle version de delay(). Oups…
Je vais donc utiliser une ligne du style :
long depart = millis();
si les résultats ne sont pas concluants.
bonjour
quelque soit ta méthode
delay ou millis renvoint une valeur entiere de ms
que ce soit avec delay ou millis si tu veux évoluer/choisir entre 0 et 20 ms, tu n'aura (au mieux) que 20 pas possibles
time1 = micros(); // nota : la précision n'est pas de 1 us mais multiple de 4 us
Dans ton cas, si tu as besoin de 1 à 20 ms, je suis sûr que cela suffira.
Ce ne sont pas les qq dizaines de micro-sec qui changeront quelque chose sur le plan pratique.
Sauf si tu veux le faire plus précis pour une question de principe.
De plus, le plus grand écart viendra de la gigue inévitable puisque :
ton interruption te fixe un drapeau immédiatement, certes, mais ensuite,
en fonction de ta position dans la boucle loop, il faudra passer sur le test du drapeau et là ... délai variable.
Voir si tu ne pourrais pas faire autrement pour éviter la gigue.