Am probleme cu adăugarea attachInterrupt într-o bibliotecă pe care o creez. Am cercetat mult și am observat că acesta este un lucru obișnuit greșeală, dar nu înțeleg prea bine răspunsurile pe care le-am găsit.
Eroarea în cauză este aceasta:
sketch_nov04a.ino: In function "void setup()": sketch_nov04a:10: error: argument of type "void (Teste::)()" does not match "void (*)()"
Biblioteca mea este următoarea :
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++; } }
implementarea mea
#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 : Actualizarea erorii și corectarea problemei citate de Ignacio
Răspuns
Problema este că wspeedIRQ()
este o funcție membru (adică face parte din clasa Teste
) , dar attachInterrupt()
expe cts o funcție nemembră (adică o funcție care este statică și / sau nu face parte deloc dintr-o clasă).
Aceasta este o distincție foarte importantă în C ++, deoarece afectează modul în care compilatorul apelează funcția din culise. Din păcate, nu există nicio modalitate de a utiliza o funcție membru direct cu attachInterrupt()
.
Totuși sunt posibile diferite soluții. Cel mai simplu este să scrieți o funcție wrapper care apelează funcția membru. De exemplu:
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); }
Ca o notă laterală, implementarea wspeedIRQ()
nu va fi compilată oricum în acest moment Motivul este că this.
este nevalid. Este „un indicator, astfel încât sintaxa corectă este this->
.
( În practică, de obicei nu este necesar să utilizați this
pentru a accesa datele despre membri. C ++ le calculează automat, cu excepția cazului în care există un conflict de denumire.)
Răspuns
În mod normal, ar trebui să utilizați digitalPinToInterrupt (pin) pentru a traduce pinul digital efectiv la numărul de întrerupere specific, nu compararea pin switch attInturrupt (,) limitat la pinul 2,3 pe un arduino uno … sau dacă cheltuiți mai mulți bani bine … aici „o listă.
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 () a câștigat „nu funcționează valorile b / c a câștigat” nu a revenit de la milis () (nu întrebați de ce) > explică cum să folosesc inturrupturi, cum ar fi permiteți-mi să recit begginin g
Întreruperile sunt utile pentru ca lucrurile să se întâmple automat în programele de microcontroler și pot ajuta la rezolvarea problemelor de sincronizare. Sarcinile bune pentru utilizarea unei întreruperi pot include citirea unui codificator rotativ sau monitorizarea intrării utilizatorului … bla bla
ceea ce pete nu a menționat este ceea ce au fost rutinele de servicii de întrerupere … și modul în care aceste funcții speciale au limitări unice și alte funcții ca în c ++ nu …. de la c-șiruri la structuri la supraîncărcare la f-structuri la șabloane t. ISR-urile sunt cât mai scurte posibil și nu ar trebui să returneze nimic! dacă dvs. ieftin și nu doriți să cheltuiți mai mult de 5 USD pentru un arduino, puteți utiliza schița pentru a utiliza mai multe ISR, le puteți configura ca prioritate
dar funcțiile dvs. care nu sunt membre ar trebui să fie volatile și globale … și millis () se bazează pe întreruperi pentru a conta, deci nu va crește niciodată în interiorul unui ISR. Deoarece delay () necesită întreruperi pentru a funcționa, nu va funcționa dacă este apelat în interiorul unui ISR. micros () funcționează inițial, dar va începe să se comporte neregulat după 1-2 ms. delayMicroseconds () nu folosește niciun contor, deci va funcționa normal. și …. variabilele globale sunt folosite pentru a transmite date între un ISR și programul principal. Pentru a vă asigura că variabilele partajate între un ISR și programul principal sunt actualizate corect, declarați-le ca fiind volatile.