AttachInterrupt dans une bibliothèque

Jai du mal à ajouter attachInterrupt dans une bibliothèque que je suis en train de créer. Jai beaucoup recherché, et jai remarqué que cest un problème erreur, mais je ne comprends pas très bien les réponses que jai trouvées.

Lerreur en question est la suivante:

sketch_nov04a.ino: In function "void setup()": sketch_nov04a:10: error: argument of type "void (Teste::)()" does not match "void (*)()" 

Ma bibliothèque est la suivante :

Teste.h

#ifndef TESTE_H #define TESTE_H #include <Arduino.h> class Teste { public: volatile long lastWindIRQ; volatile byte windClicks; void wspeedIRQ(); }; #endif 

Teste.cpp

#include "Teste.h" void Teste::wspeedIRQ() { if (millis() - this.lastWindIRQ > 10) { this.lastWindIRQ = millis(); this.windClicks++; } } 

mon implémentation

#include <Teste.h> Teste teste; void setup() { Serial.begin(9600); pinMode(2, INPUT); digitalWrite(2, HIGH); attachInterrupt(0, teste.wspeedIRQ, FALLING); } void loop() { Serial.println(teste.windClicks); delay(3000); } 

EDIT : Mise à jour de lerreur et correction du problème cité par Ignacio

Réponse

Le problème est que wspeedIRQ() est une fonction membre (cest-à-dire quelle « fait partie de la classe Teste) , mais attachInterrupt() expe cts une fonction non membre (i.e. une fonction qui est statique et / ou qui ne fait pas du tout partie dune classe).

Cest une distinction très importante en C ++ car elle affecte la façon dont le compilateur appelle la fonction en arrière-plan. Il ny a malheureusement aucun moyen dutiliser une fonction membre directement avec attachInterrupt().

Différentes solutions de contournement sont cependant possibles. Le plus simple est décrire une fonction wrapper qui appelle la fonction membre. Par exemple:

Teste teste; // This is a non-member function... void isr() { // ...which calls the member function: teste.wspeedIRQ(); } void setup() { //... // Setup interrupt to use a non-member function attachInterrupt(0, isr, FALLING); } 

En remarque, votre implémentation de wspeedIRQ() ne sera pas compilée pour le moment de toute façon . La raison en est que this. nest pas valide. Il « sagit dun pointeur donc la syntaxe correcte est this->.

( Dans la pratique, vous n’avez généralement pas besoin d’utiliser this pour accéder aux données des membres. C ++ le détecte automatiquement, sauf en cas de conflit de dénomination.

Réponse

Normalement, vous devriez utiliser digitalPinToInterrupt (pin) pour traduire la broche numérique réelle en numéro dinterruption spécifique et non en comparaison de commutateur de broche attachInturrupt (,,) limité à la broche 2,3 sur un arduino uno … ou si vous dépensez bien plus dargent … voici « une liste.

Board Digital Pins Usable For Interrupts Uno, Nano, Mini, other 328-based 2, 3 Mega, Mega2560, MegaADK 2, 3, 18, 19, 20, 21 Micro, Leonardo, other 32u4-based 0, 1, 2, 3, 7 Zero all digital pins, except 4 MKR1000 Rev.1 0, 1, 4, 5, 6, 7, 8, 9, A1, A2 Due all digital pins all digital pins (Only pins 2, 5, 7, 8, 10, 11, 12, 13 work with CHANGE 

delay () « t work b / c values won » t return from millis () (dont ask why) https://www.arduino.cc/en/Reference/AttachInterrupt explique comment utiliser les inturrupts comme laissez-moi réciter le début g

Les interruptions sont utiles pour que les choses se produisent automatiquement dans les programmes de microcontrôleur, et peuvent aider à résoudre les problèmes de synchronisation. Les bonnes tâches pour utiliser une interruption peuvent inclure la lecture dun encodeur rotatif, ou la surveillance des entrées utilisateur …. bla bla

ce que Pete na pas mentionné est ce quétaient les routines de service dinterruption … et comment ces fonctions spéciales ont des limitations uniques, les autres fonctions comme en C ++ ne le font pas …. des chaînes de caractères aux structures en passant par la surcharge des structures f aux modèles en T. Les ISR sont aussi courts que possible et ne doivent rien renvoyer! si vous ne voulez pas dépenser plus de 5 $ pour un arduino, vous pouvez utiliser sketch pour utiliser plusieurs isr, vous pouvez les configurer en priorité

mais vos fonctions non membres doivent être volatiles et globales … et millis () sappuie sur les interruptions pour compter, donc il ne sincrémentera jamais à lintérieur dun ISR. Puisque delay () nécessite des interruptions pour fonctionner, il ne fonctionnera pas sil est appelé à lintérieur dun ISR. micros () fonctionne initialement, mais commencera à se comporter de manière erratique après 1-2 ms. delayMicroseconds () nutilise aucun compteur, il fonctionnera donc normalement. et …. les variables globales sont utilisées pour transmettre des données entre un ISR et le programme principal. Pour vous assurer que les variables partagées entre un ISR et le programme principal sont correctement mises à jour, déclarez-les comme volatiles.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *