En cours Faire clignoter une led en dehors du programme principal

  • Auteur de la discussion gaston83
  • Date de début
gaston83
gaston83
Compagnon
17 Fev 2016
1 433
FR-71520
  • Auteur de la discussion
  • #17
Bonjour,

Une première: à quoi correspondent les nombres 10 et 9 ...?

Pour le reste , je pense avoir saisi....
 
jpbbricole
jpbbricole
Compagnon
26 Mai 2016
2 204
Corsier-sur-Vevey (Vaud)
Bonjour Gaston

Ta demande était, une impulsion de 0,1 sec toutes les secondes.
Sur la suggestion de @petit_lulu, j'ai créé un compteur qui divise la seconde en 10 x 0,1 sec.
Donc, l'interruption va dans la routine d'interruption (flash) 10x par seconde.

MsTimer2::set(100, flash);

Au 9ème dixième de seconde on allume la LED et au 10ème on éteind et remets le compteur à 0.

Cordialement
jpbbricole
 
zed
zed
Ouvrier
26 Juil 2016
487
Ouest Toulousain
Bonjour,

la ligne :
MsTimer2::set(100, flash);

initialise l'exécution de la procédure "Flash" tous les 100ms
Le 9 correspond à 900ms et le 10 à 1000ms (soit 1s)
Dans la procédure "Flash", la LED n'est allumée qu'entre 9 et 10, soit 100ms.
Et comme le compteur est remis à 0 quand il atteint 10 (soit toutes les 10 x 100ms) l'opération se réinitialise toutes les secondes...

Edit :
Trop lent, grillé par jpbbricole ! :wink:
 
gaston83
gaston83
Compagnon
17 Fev 2016
1 433
FR-71520
  • Auteur de la discussion
  • #20
Hé ben voilà, c'est derrière l'oreille.... :smt023

Merci et bon appétit....

++
 
RacingMat
RacingMat
Compagnon
30 Oct 2016
612
Marseille
j'arrive un peu après la bataille mais je trouve qu'il y a plus simple sans librairie supplémentaire (je ne connais pas cette MsTimer)

Pour les interruptions, c'est super mais certainement trop compliqué pour le besoin (il y a des contraintes (déclaration en volatile, leur nombre est limité...))

> un allumage de 100 ms toutes les secondes

la seule chose à faire est de respecter la formule qui compare des durées
et pas celle-ci qui compare des horodatages
car sinon au dépassement de capacité de millis ça va planter (au bout de 49 jours tout de même)
 
RacingMat
RacingMat
Compagnon
30 Oct 2016
612
Marseille
super, comme ça tu as le choix :)
 
T
tronix
Compagnon
6 Mar 2012
1 428
Toulouse
tu n'as pas le droit d'utiliser delay(100) dans ta routine d'interruption ? (je sais que les delay sont à éviter, mais 100 ms c'est pas encore trop long....
Arrgh... Je m'étrangle ! Rien que la led va bouffer 10% du cpu et allonger les délais de réaction jusqu'à 100ms. Comment transformer une Formule 1 en trottinette, même pas électrique.
Une façon simple de gérer ce genre de problème avec timings non critiques est d'utiliser un timer à 1kHz, qui va juste s'occuper d'incrémenter un compteur de temps chaque ms. Ensuite, la tâche principale appelle régulièrement les fonctions les unes après les autres, et qui rendent la main dès qu'elles n'ont rien à faire. Si une tâche est trop longue, pour ne pas pénaliser le reste, on rend la main quand-même et on finira au coup suivant. Des machines d'états simples suffisent à gérer l'endroit où on est.
Pour la led, cela devient trivial, en mémorisant le compteur de ms depuis le dernier changement d'état, on sait s'il faut allumer ou éteindre, et avoir des temps d'allumage et d'extinction différents n'est pas plus compliqué. Le jitter dépendra de l'exécution du reste du code, mais ne doit pas dépasser quelques ms (voire beaucoup moins, presque imperceptible) si le reste du code est bien fait.
Un mini ordonnanceur en fait.
Si on applique ça à tout le code, et sur un processeur un peu rapide, on a une excellente réactivité sans abuser des interruptions qui sont alors réservées aux fonctions qui en on réellement besoin.
 
Dernière édition:
RacingMat
RacingMat
Compagnon
30 Oct 2016
612
Marseille
il faut bien garder en tête qu'un Arduino qui tourne à 16MHz peut effectuer 16 000 instructions pendant une seule petite milliseconde :eek:

le delay() c'est le mal !! :smt077
 
CNCSERV
CNCSERV
Compagnon
27 Déc 2007
5 667
FR-28360
DigitaWrite c'est pas mieux, ça bouffe au moins 10 cycles juste pour actionner une sortie. On peut le faire en 1 cycle.
 
T
tronix
Compagnon
6 Mar 2012
1 428
Toulouse
Oui, mais si on met dix cycles au lieu d'un seul pour une mise à jour de led toutes les 100ms, la différence sera négligeable globalement. Le savoir est utile cependant pour changer de méthode si cela a réellement un impact. En revanche, le delay() dans une fonction appelée régulièrement est catastrophique. S'il n'y a qu'une seule fonction, c'est la solution de facilité. Mais dès qu'il faudra faire tourner autre chose en même temps, ce handicap sera vite insurmontable. Et plus le processeur sera rapide, et plus la chute de performance sera énorme. J'utilise des processeurs à 200MHz, pendant un delay(1ms), on pourrait passer en gros 200 000 instructions à la place...
Delay() est à proscrire si on n'en voit pas la portée. A réserver éventuellement aux initialisations de périphériques, qui n'ont lieu qu'une fois et au démarrage du processeur.
J'ajoute aussi qu'une interruption doit être la plus courte possible, d'autant plus que sa priorité sera grande.
Donc, un delay(100ms) dans une interruption, je suis mort.:smt021
 
Dernière édition:
jpbbricole
jpbbricole
Compagnon
26 Mai 2016
2 204
Corsier-sur-Vevey (Vaud)
Bonsoir
Arrgh... Je m'étrangle ! Rien que la led va bouffer 10% du cpu et allonger les délais de réaction jusqu'à 100ms. Comment transformer une Formule 1 en trottinette, même pas électrique.
C'est un peu dramatiser, non? :eek:, surtout que ça a été corrigé au post #14.
Bien sûre, delay() est dit bloquant, mais il faut savoir raison garder, surtout au vu de la question posée.
Si le contexte de l'utilisation avait été clairement posé, la réponse aurait été tout autre!

Cordialement
jpbbricole
 
  • Réagir
Reactions: zed
zed
zed
Ouvrier
26 Juil 2016
487
Ouest Toulousain
Comme dit jpbbricole, le code du post #14 est tout à fait efficace et propre.
La seule correction que j'y ferai, c'est la ligne de la procédure flash : if (ledCptMillis == 10) que je changerai en if (ledCptMillis >= 10)
On ne sait jamais, sur un malentendu comme dirait l'autre... :wink:
 
Haut