AttachInterrupt v knihovně

Mám potíže s přidáním attachInterrupt v knihovně, kterou vytvářím. Hodně jsem zkoumal a všiml jsem si, že je to běžné chyba, ale nechápu docela dobře odpovědi, které jsem našel.

Dotyčná chyba je tato:

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

Moje knihovna je následující :

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++; } } 

moje implementace

#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 : Aktualizována chyba a opraven problém citovaný Ignacio

Odpovědět

Problém je v tom, že wspeedIRQ() je členská funkce (tj. je součástí třídy Teste) , ale attachInterrupt() expe cts nečlenskou funkci (tj. funkce, která je statická a / nebo vůbec není součástí třídy).

Toto je v C ++ velmi důležitý rozdíl, protože ovlivňuje to, jak kompilátor volá funkci v zákulisí. Bohužel neexistuje žádný způsob, jak přímo použít členskou funkci s attachInterrupt().

Jsou však možná různá řešení. Nejjednodušší je napsat obálkovou funkci, která volá členskou funkci. Například:

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); } 

Jako vedlejší poznámku vaše implementace wspeedIRQ() v tuto chvíli stejně nebude kompilována . Důvod je ten, že this. je neplatný. Je to ukazatel, takže správná syntaxe je this->.

( V praxi obvykle pro přístup k datům členů není nutné používat this. C ++ to zjistí automaticky, ledaže by došlo ke konfliktu názvů.)

Odpověď

Za normálních okolností byste měli použít digitalPinToInterrupt (pin) k překladu skutečného digitálního pin na konkrétní číslo přerušení, nikoli na srovnání pin přepínače attachInturrupt (,) omezeno na pin 2,3 na arduino uno … nebo pokud utratíte více peněz dobře … zde „je seznam.

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 () nebude fungovat hodnota b / c nebude vrácena z millis () (nezeptám se proč) https://www.arduino.cc/en/Reference/AttachInterrupt vysvětluje, jak používat inturrupty jako dovolte mi přednášet begginin g

Přerušení jsou užitečná pro automatické dělání věcí v programech mikrokontrolérů a mohou pomoci vyřešit problémy s načasováním. Dobré úkoly pro použití přerušení mohou zahrnovat čtení rotačního kodéru nebo monitorování vstupu uživatele …. bla bla

to, co Pete nezmínil, je to, co byly Interrupt Service Routines … a jak tyto speciální funkce mají jedinečná omezení, jiné funkce jako v C ++ nemají …. od řetězců C přes struktury přes přetížení až po f struktury ke šablonám t. ISR jsou co nejkratší a neměly by nic vracet! pokud vaše levné a nechcete utratit více než 5 $ za arduino, můžete použít skicu k použití více isr, můžete je nastavit jako prioritní

ale vaše nečlenské funkce by měly být nestálé a globální … a millis () se při počítání spoléhá na přerušení, takže se uvnitř ISR nikdy nezvýší. Vzhledem k tomu, že delay () vyžaduje pro práci přerušení, nebude fungovat, pokud bude voláno uvnitř ISR. micros () funguje zpočátku, ale začne se chovat nevyzpytatelně po 1-2 ms. delayMicroseconds () nepoužívá žádné počítadlo, takže bude fungovat jako obvykle. a …. globální proměnné se používají k předávání dat mezi ISR a hlavním programem. Abyste se ujistili, že proměnné sdílené mezi ISR a hlavním programem jsou správně aktualizovány, deklarujte je jako těkavé.

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *