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 490
FR-71520
  • Auteur de la discussion
  • #1
Bonjour à tous,

Tout est dans le titre... je suppose qu'il va falloir que je tripote les interruptions ... :wink:
 
gaston83
gaston83
Compagnon
17 Fev 2016
1 490
FR-71520
  • Auteur de la discussion
  • #4
edit:

Ha, je viens de m'apercevoir que c'est pas pour les 32U4. Je viens de tester...

J'ai rien dit... ça marche... la pin 13 était déjà prise.

Merci...

++
 
Dernière édition:
gaston83
gaston83
Compagnon
17 Fev 2016
1 490
FR-71520
  • Auteur de la discussion
  • #5
Par contre, aurais-tu une idée pour pour faire un allumage de 100 ms toutes les secondes ... :smt017
 
gégé62
gégé62
Compagnon
26 Fev 2013
2 903
Harnes (Pas de Calais)
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....
 
petit_lulu
petit_lulu
Compagnon
11 Jan 2015
836
gers
je precise que je ne connais pas arduino mais:
-tu cree une interuption toute les 100ms avec ton timer ou 10ms si c'est trop long
-dans la routine d'interuption tu incremente un compteur et quand il est a 10 (ou 100 si 10ms) tu le passe a 0 (ne pas oublier de le mettre a 0 a l'initialisation du µC)
-de plus dans cette meme routine tu test si le compteur est a 0 (ou inferieur a 11 si 10ms):
--si a 0 (< a 11) alors tu allume la led
--si <>0 (> a 11) tu eteint

c'est simple et ca monopolise pas le µC pendant 100ms.
 
remi30132
remi30132
Compagnon
8 Août 2016
606
nimes
Si le problème est l'utilisation des delay() tu peux utiliser des millis dans des if
 
F
francis75
Ouvrier
19 Sept 2013
429
Paris 10e
Par contre, aurais-tu une idée pour pour faire un allumage de 100 ms toutes les secondes ... :smt017
Bonjour,
C'est typiquement une fonctionnalité PWM (Modulation de largeur d'impulsion). Je n'ai pas sous les yeux les specs de l'Arduino, mais les timers permettent en général de faire ça (souvent pénible à configurer). Sinon, avec 2 timers.


PS
---
En principe on ne met pas de temporisation, délais, ou gros code dans une fonction d'interruption, afin d'en sortir au plus vite.
 
Dernière édition:
gégé62
gégé62
Compagnon
26 Fev 2013
2 903
Harnes (Pas de Calais)
En principe on ne met pas de temporisation, délais, ou gros code dans une fonction d'interruption, afin d'en sortir au plus vite.
c'est vrai, ça peut poser ds problèmes, mais je pense que ça dépend du contexte, ici on ne le connait pas.
 
CNCSERV
CNCSERV
Compagnon
27 Déc 2007
5 852
FR-28360
tu n'as pas le droit d'utiliser delay(100) dans ta routine d'interruption
Non, on interrompt pas une routine d'interruption :wink:
Le compteur à lulu est a mon avis la bonne solution et le plus simple.
 
jpbbricole
jpbbricole
Compagnon
26 Mai 2016
2 248
Corsier-sur-Vevey (Vaud)
gaston83
gaston83
Compagnon
17 Fev 2016
1 490
FR-71520
  • Auteur de la discussion
  • #15
Hé bien, encore une fois ....:smt023 un grand merci Messieurs... ça fonctionne nickel.... :prayer:

C'est bien beau, mais maintenant il faut j'assimile la procédure .... je ne veux pas faire du recopiage tout bête ... il n' y aurait aucun intérêt. :wink:

++
 
gaston83
gaston83
Compagnon
17 Fev 2016
1 490
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 248
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
Compagnon
26 Juil 2016
508
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 490
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
613
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
613
Marseille
super, comme ça tu as le choix :)
 
T
tronix
Compagnon
6 Mar 2012
1 478
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
613
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 852
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 478
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 248
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
Compagnon
26 Juil 2016
508
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:
 
Sujets similaires Forum Date
Fraiseuses CNC industrielles de type portique
Finitions
Electricité, variateurs, convertisseurs et moteurs
Electronique spécifique CNC
Electricité, variateurs, convertisseurs et moteurs
Outils et accessoires
Divers projets et réalisations
Électricité/électronique (Hors usinage)
Electricité, variateurs, convertisseurs et moteurs
Outils et accessoires
Électricité/électronique (Hors usinage)
Autres procédés de fabrication
Electricité, variateurs, convertisseurs et moteurs
Electricité, variateurs, convertisseurs et moteurs
Divers projets et réalisations
Haut