AttachInterrupt i ett bibliotek

Jag har problem med att lägga till attachInterrupt i ett bibliotek som jag skapar. Jag undersökte mycket och jag märkte att detta är vanligt misstag, men förstår inte riktigt svaren jag hittade.

Felet i fråga är detta:

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

Mitt bibliotek är som följer :

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 : Uppdaterade felet och korrigerade problemet som citerats av Ignacio

Svar

Problemet är att wspeedIRQ() är en medlemsfunktion (dvs. den är en del av klassen Teste) , men attachInterrupt() expe cts en icke-medlem-funktion (dvs. en funktion som är statisk och / eller inte alls ingår i en klass).

Detta är en mycket viktig skillnad i C ++ eftersom den påverkar hur kompilatorn kallar funktionen bakom kulisserna. Det finns tyvärr inget sätt att använda en medlemsfunktion direkt med attachInterrupt().

Olika lösningar är dock möjliga. Det enklaste är att skriva en omslagsfunktion som kallar medlemsfunktionen. Till exempel:

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 sidoanteckning kommer din implementering av wspeedIRQ() inte att kompilera för tillfället ändå Orsaken är att this. är ogiltig. Det är en pekare så att rätt syntax är this->.

( I praktiken behöver du vanligtvis inte använda this för att komma åt medlemsdata. C ++ räknar ut det automatiskt, såvida det inte finns någon namngivningskonflikt.)

Svar

Normalt bör du använda digitalPinToInterrupt (pin) för att översätta det faktiska digitala stiftet till det specifika avbrottsnumret, inte pin-switch-jämförelsen attachInturrupt (,,) som är begränsad till stift 2,3 på en arduino uno … eller om du spenderar mer pengar väl … här ”en 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 

fördröjning () vann ”t arbete b / c-värden kommer inte tillbaka från millis () (fråga inte varför) https://www.arduino.cc/en/Reference/AttachInterrupt förklarar hur man använder störningar som låt mig recitera tiggerin g

Avbrott är användbara för att få saker att hända automatiskt i mikrokontrollerprogram och kan hjälpa till att lösa tidsproblem. Bra uppgifter för att använda ett avbrott kan inkludera läsning av en roterande kodare eller övervakning av användarinmatning …. bla bla

vad pete nämnde inte är vad Interrupt Service Routines var … och hur dessa specialfunktioner har unika begränsningar andra funktioner som i c ++ gör inte …. från c-strängar till struts till överbelastning till f-struts till t-mallar. ISR är så korta som möjligt och ska inte returnera någonting! om din billiga och inte vill spendera mer än $ 5 för en arduino kan du använda skiss för att använda flera isr kan du ställa in dem som prioritet

men dina icke-medlemsfunktioner ska vara flyktiga och globala … och millis () förlitar sig på avbrott för att räkna, så det kommer aldrig att öka i en ISR. Eftersom fördröjning () kräver avbrott för att fungera fungerar det inte om det anropas i en ISR. micros () fungerar initialt, men kommer att börja fungera felaktigt efter 1-2 ms. delayMicroseconds () använder ingen räknare, så det fungerar som vanligt. och … globala variabler används för att skicka data mellan en ISR och huvudprogrammet. För att säkerställa att variabler som delas mellan en ISR och huvudprogrammet uppdateras korrekt, förklara dem som flyktiga.

Lämna ett svar

Din e-postadress kommer inte publiceras. Obligatoriska fält är märkta *