作成中のライブラリにattachInterruptを追加するのに問題があります。よく調べたところ、これが一般的であることに気付きました。間違いですが、私が見つけた答えを完全には理解していません。
問題のエラーは次のとおりです:
sketch_nov04a.ino: In function "void setup()": sketch_nov04a:10: error: argument of type "void (Teste::)()" does not match "void (*)()"
私のライブラリは次のとおりです:
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++; } }
私の実装
#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); }
編集:エラーを更新し、Ignacioが引用した問題を修正しました
回答
問題は、wspeedIRQ()
がメンバー関数である(つまり、Teste
クラスの一部である)ことです。 、ただしattachInterrupt()
expe非メンバー関数をctsします(つまり、静的であるか、クラスの一部ではない関数)。
これは、コンパイラが舞台裏で関数を呼び出す方法に影響を与えるため、C ++では非常に重要な違いです。残念ながら、attachInterrupt()
でメンバー関数を直接使用する方法はありません。
ただし、さまざまな回避策が可能です。最も簡単なのは、メンバー関数を呼び出すラッパー関数を作成することです。例:
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); }
補足として、wspeedIRQ()
の実装は現時点ではコンパイルされません。 。理由は、this.
が無効であるためです。これはポインタであるため、正しい構文はthis->
です。
(実際には、通常、メンバーデータにアクセスするためにthis
を使用する必要はありません。名前の競合がない限り、C ++は自動的にそれを判断します。
回答
通常、digitalPinToInterrupt(pin)を使用して、実際のデジタルピンをピンスイッチの比較ではなく特定の割り込み番号に変換する必要があります。attachInturrupt(、、) arduino unoのピン2、3に制限されています…またはもっとお金を使う場合は…ここにリストがあります。
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()動作しないb / c値はmillis()から返されません(理由は聞かないでください) https://www.arduino.cc/en/Reference/AttachInterrupt 最初の人を暗証させてくれるようなinturruptsの使い方を説明しますg
割り込みは、マイクロコントローラープログラムで自動的に発生させるのに役立ち、タイミングの問題を解決するのに役立ちます。割り込みを使用するための適切なタスクには、ロータリーエンコーダーの読み取り、ユーザー入力の監視などがあります。…何とか何とか
ピートが言及しなかったのは、割り込みサービスルーチンとは何か…そしてこれらの特別な機能c ++のような他の関数にはない固有の制限があります。c文字列から構造体、オーバーロード、f構造体、tテンプレートまで。ISRは可能な限り短く、何も返さないはずです。安くて「arduinoに5ドル以上を費やしたくない場合は、スケッチを使用して複数のisrを使用できます」それらを優先度として設定できます
ただし、非メンバー関数は揮発性でグローバルである必要があります…そしてmillis()は割り込みに依存してカウントするため、ISR内でインクリメントすることはありません。 delay()が機能するには割り込みが必要なため、ISR内で呼び出された場合は機能しません。 micros()は最初は機能しますが、1〜2ミリ秒後に不規則に動作し始めます。 delayMicroseconds()はカウンターを使用しないため、通常どおり機能します。および….グローバル変数は、ISRとメインプログラムの間でデータを渡すために使用されます。 ISRとメインプログラム間で共有される変数が正しく更新されるようにするには、それらを揮発性として宣言します。