Tengo problemas para agregar attachInterrupt en una biblioteca que estoy creando. Investigué mucho y noté que esto es un problema común error, pero no entiendo bien las respuestas que encontré.
El error en cuestión es este:
sketch_nov04a.ino: In function "void setup()": sketch_nov04a:10: error: argument of type "void (Teste::)()" does not match "void (*)()"
Mi biblioteca es la siguiente :
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++; } }
mi implementación
#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 : Actualizó el error y corrigió el problema citado por Ignacio
Respuesta
El problema es que wspeedIRQ()
es una función miembro (es decir, es parte de la clase Teste
) , pero attachInterrupt()
expe cts una función no miembro (es decir una función que es estática y / o no forma parte de una clase).
Esta es una distinción muy importante en C ++ porque afecta cómo el compilador llama a la función detrás de escena. Desafortunadamente, no hay forma de usar una función miembro directamente con attachInterrupt()
.
Sin embargo, son posibles varias soluciones. La más simple es escribir una función contenedora que llame a la función miembro. Por ejemplo:
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); }
Como nota al margen, su implementación de wspeedIRQ()
no se compilará en este momento de todos modos . El motivo es que this.
no es válido. Es «un puntero, por lo que la sintaxis correcta es this->
.
( En la práctica, normalmente no es necesario utilizar this
para acceder a los datos de los miembros. C ++ lo averigua automáticamente, a menos que haya un conflicto de nombres.
Respuesta
Normalmente, debería usar digitalPinToInterrupt (pin) para traducir el pin digital real al número de interrupción específico, no al interruptor de comparación adjuntoInturrupt (,,) que es limitado al pin 2,3 en un arduino uno … o si gastas más dinero bien … aquí «una lista.
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 () no «no funcionan los valores b / c» no regresan de millis () (no preguntes por qué) https://www.arduino.cc/en/Reference/AttachInterrupt explica cómo usar los inturrupts como déjame recitar el principio g
Las interrupciones son útiles para hacer que las cosas sucedan automáticamente en programas de microcontroladores y pueden ayudar a resolver problemas de sincronización. Las buenas tareas para usar una interrupción pueden incluir leer un codificador rotatorio o monitorear la entrada del usuario … bla, bla,
lo que Pete no mencionó es qué eran las rutinas de servicio de interrupción … y cómo estas funciones especiales tienen limitaciones únicas, otras funciones como en c ++ no …. desde c-strings hasta structs, sobrecargas, f-structs y t-templates. ¡Los ISR son lo más cortos posible y no deberían devolver nada! si es barato y no quiere gastar más de $ 5 por un arduino, puede usar sketch para usar múltiples isr, puede configurarlos como prioridad
pero sus funciones no miembros deben ser volátiles y globales … y millis () se basa en las interrupciones para contar, por lo que nunca se incrementará dentro de un ISR. Dado que delay () requiere interrupciones para funcionar, no funcionará si se llama dentro de un ISR. micros () funciona inicialmente, pero comenzará a comportarse de manera errática después de 1-2 ms. delayMicroseconds () no usa ningún contador, por lo que funcionará normalmente. y …. las variables globales se utilizan para pasar datos entre un ISR y el programa principal. Para asegurarse de que las variables compartidas entre un ISR y el programa principal se actualicen correctamente, declararlas como volátiles.