Bonjour,
J'ai une fonction1 qui défini les paramètres de la fonction2 avant d'appeler la fonction2 .
Sauf que; je ne veux pas que cette fonction2 soit exécutée immédiatement lors de son appel, mais uniquement suite à une interruption externe.
J'ai pensé à la solution suivante;
fonction1 défini les paramètres et les placent dans un tableau
la fonction2 appelée par l'interruption externe ;
regarde si des valeurs sont existantes dans le tableau
avant de l'exécuter complétement
Est ce une bonne solution ?
Ou ???
Merci par avance de votre aide.
Les fonctions appelées par une interruption doivent être aussi courtes que possible, généralement une incrémentation d'un compteur ou la mise d'un indicateur à zéro ou à un et rien d'autre. Appelez la fonction 2 lorsque la fonction 1 détecte ce changement.
C’est un peu extrême… on peut faire plus… sinon Serial, I2C ou SPI ne fonctionneraient pas…
C'est vrai, mais plus c'est court, mieux c'est. Depuis lors de l'entrée dans l'ISR, certaines interruptions de l'avr sont annulées, comme celles utilisées par millis et serial et je ne sais quoi d'autre. Ce n'est pas une affirmation, c'est une question.
Oui plus c’est court mieux c’est car effectivement les interruptions sont désactivées (mais pas perdues) pendant ce temps mais on peut quand même avoir un peu de logique intégrée (encodeur quadratique par exemple en aura besoin). Faut rester raisonnable et comprendre les conséquences
C'est un peu plus compliqué que ça.
L'interruption peut arriver alors que fonction1 est en train d'écrire les paramètres, donc les paramètres ne sont peut-être pas tous à jour.
Suivant le besoin, je vois 2 possibilités:
- fonction2 doit toujours envoyer les paramètres les plus récent et elle peut être légèrement retardée: Il faudrait dans ce cas désactiver les interruptions le temps que fonction1 remplisse le tableau.
- fonction2 doit impérativement envoyer des données lorsque l'interruption arrive même si ce ne sont pas les données les plus fraîches: dans ce cas il faut mettre en place un système de deux tableaux en flip-flop, fonction1 écrit dans un tableau pendant que fonction2 lit l'autre. Et plus tard lorsque fonction2 a terminé on échange la fonction des tableaux
C'est un axiome que je ne partage pas. La seule exigence est que le temps de l'interruption soit plus courte que le temps qui sépare deux appels.
J'ai toujours appris qu'une phrase "ce doit être court", "une grande résistance"... n'était pas scientifique. Par contre "ce doit être court devant" ou "une grande résistance devant une autre" l'est si on définit le rapport.
Pour avoir expérimenté des programme en contradiction:
− quickstep qui fait tourner un pas à pas sous interruption et dont tout les calculs des temps entre les pas sont fait pendant l'interruption (il ne reste plus grand chose à faire pendant le programme principal)
− MTobjects qui ne travaille exclusivement que par interruption, dans lequel tout en gérant des vitesses de servo ou de pas à pas mémorise les actions sur boutons même si on y rajoute des delay(1000) dans le code.
Par défaut, en rentrant dans une fonction d'interruption, on désactive les interruptions. Mais rien n'empêche de les réactiver, par exemple si le traitement est long, pour éviter que millis, l'I2C, la lauson série... ne fonctionnent plus. Il faut alors faire gaffe que l'interruption ne soit interrompue par elle même (bien que cela soit possible si c'est correctement géré).
On peut tout faire, mais plus c'est complexe, plus il faut prendre de précautions.
SI les données sont naturellement dans un tableau, il faut les mettre dans la même structure, c'est plus facile. Maintenant si ce sont des données différentes, on peut les laisser par exemple dans des variables globales. Attention de rajouter le mot volatile pour les variables qui sont lues ou écrites par l'interruption ET par le programme principal.
Si on veut mettre un test pour informer que les données sont valides, il faut que ce soit un indicateur qui soit écrit en une seule instruction. Avec un booléen, c'est bon. Mais il ne faudrait pas prendre un entier avec une Uno.
Bonjour Pb71
Je "vois" ça avec 2 variables booléennes:
boolean fonction1NouveauParametres = false;
volatile boolean fonction2Interruption = false;
Fonction1 défini de nouveaux paramètres:
fonction1NouveauParametres = true;
Dans interruption:
fonction2Interruption = true;
dans loop()
Si fonction2Interruption et fonction1NouveauParametres,
appel fonction2
fonction1NouveauParametres = false;
fonction2Interruption = false;
Si fonction2Interruption et pas fonction1NouveauParametres,
fonction2Interruption = false;
Cordialement
jpbbricole
De manière générale il faut éviter les doubles test sur le drapeau (ici fonction2Interruption) car l’interruption a pu se produire entre le premier et second if
il vaut mieux traiter cela en un seul appel
Si fonction2Interruption alors appel fonction2
Dans fonction2
Si (fonction1NouveauParametres) alors {
… traiter les données
fonction1NouveauParametres = false;
}
fonction2Interruption = false;
Il faut peut être aussi traiter le calcul en mode protégé car l’interruption pourrait se re déclencher pendant fonction2 et on remettrait fonction2Interruption à false sans l'avoir traitée à nouveau (dépend de ce que l'on veut)