Jeg har problemer med at tilføje attachInterrupt i et bibliotek, som jeg opretter. Jeg undersøgte meget, og jeg bemærkede, at dette er en almindelig fejl, men forstår ikke helt de svar, jeg fandt.
Den pågældende fejl er denne:
sketch_nov04a.ino: In function "void setup()": sketch_nov04a:10: error: argument of type "void (Teste::)()" does not match "void (*)()"
Mit bibliotek er som følger :
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++; } }
min implementering
#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 : Opdateret fejlen og rettet problemet citeret af Ignacio
Svar
Problemet er, at wspeedIRQ()
er en medlemsfunktion (dvs. det er en del af klassen Teste
) , men attachInterrupt()
expe cts en ikke-medlemsfunktion (dvs. en funktion, der er statisk og / eller slet ikke er en del af en klasse).
Dette er en meget vigtig forskel i C ++, fordi det påvirker, hvordan kompilatoren kalder funktionen bag kulisserne. Der er desværre ingen måde at bruge en medlemsfunktion direkte med attachInterrupt()
.
Forskellige løsninger er dog mulige. Det enkleste er at skrive en indpakningsfunktion, der kalder medlemsfunktionen. For eksempel:
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); }
Som en sidebemærkning vil din implementering af wspeedIRQ()
alligevel ikke t kompilere i øjeblikket Årsagen er, at this.
er ugyldig. Det er en markør, så den korrekte syntaks er this->
.
( I praksis behøver du normalt ikke bruge this
for at få adgang til medlemsdata. C ++ regner det automatisk ud, medmindre der er en navngivningskonflikt.)
Svar
Normalt skal du bruge digitalPinToInterrupt (pin) til at oversætte den aktuelle digitale pin til det specifikke interruptnummer, ikke pin switch sammenligning attachInturrupt (,,) det vil sige begrænset til pin 2,3 på en arduino uno … eller hvis du bruger flere penge godt … her “en 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
forsinkelse () vandt “t arbejde b / c-værdier vinder ikke t fra millis () (spørg ikke hvorfor) https://www.arduino.cc/en/Reference/AttachInterrupt forklarer, hvordan man bruger inturrupts som lad mig recitere tiggeriet g
Interrupts er nyttige til at få ting til at ske automatisk i mikrocontroller-programmer og kan hjælpe med at løse timingproblemer. Gode opgaver til brug af en afbrydelse kan omfatte læsning af en roterende indkoder eller overvågning af brugerindgang …. bla bla
hvad pete ikke nævnte, hvad Interrupt Service Routines var … og hvordan disse specielle funktioner har unikke begrænsninger andre funktioner som i c ++ ikke …. fra c-strenge til structs til overbelastning til f-structs til t-skabeloner. ISR er så korte som muligt og skal ikke returnere noget! hvis din billige og ikke vil bruge mere end $ 5 til en arduino, kan du bruge skitse til at bruge flere isrer, kan du indstille dem som prioritet
men dine ikke-medlemsfunktioner skal være ustabile og globale … og millis () er afhængige af afbrydelser for at tælle, så det vil aldrig forøges inde i en ISR. Da forsinkelse () kræver afbrydelser for at arbejde, fungerer den ikke, hvis den kaldes inde i en ISR. micros () fungerer oprindeligt, men begynder at opføre sig uretmæssigt efter 1-2 ms. delayMicroseconds () bruger ikke nogen tæller, så den fungerer som normalt. og …. globale variabler bruges til at overføre data mellem en ISR og hovedprogrammet. For at sikre, at variabler, der deles mellem en ISR og hovedprogrammet, opdateres korrekt, skal du erklære dem som flygtige.