5

超音波距離センサー用の単純なライブラリを作成していて、割り込みを使用してみようと思いました。

ただし、メソッドに関数をattachCallback正しく設定できません。

ピンがそれぞれハイとローになったときに呼び出しHCSR04Interrupt::echoHigh()ます。HCSR04Interrupt::echoLow()

私はこれを無駄にグーグルで検索しました。Ardiuno IDE は次のように述べています。

./Arduino/libraries/HCSR04/HCSR04Interrupt.cpp: In member function 'void HCSR04Interrupt::getDistance()':
./Arduino/libraries/HCSR04/HCSR04Interrupt.cpp:31: error: argument of type 'void (HCSR04Interrupt::)()' does not match 'void (*)()'
./Arduino/libraries/HCSR04/HCSR04Interrupt.cpp: In member function 'void HCSR04Interrupt::echoHigh()':
./Arduino/libraries/HCSR04/HCSR04Interrupt.cpp:47: error: argument of type 'void (HCSR04Interrupt::)()' does not match 'void (*)()'

これが私のヘッダーです:

#ifndef _HCSR04Interrupt_
#define _HCSR04Interrupt_

#include "Arduino.h"

#define HCSR04_CM_FACTOR 58.0
#define HCSR04_IN_FACTOR 148.0
#define HCSR04_CM_MODE 0
#define HCSR04_IN_MODE 1

class HCSR04Interrupt {
  public:
    double distance;

    HCSR04Interrupt(int trigger_pin, int echo_pin, void (*callback)());

    void setUnits(int units);

    void getDistance();
  private:
    int _trigger_pin;
    int _echo_pin;
    int _units;
    unsigned long _micros_start;
    void (*_callback)();

    void initialize();
    void echoHigh();
    void echoLow();
};

#endif

そして、私の実装(attachInterruptステップを通過できないため、完全ではありません):

#include "Arduino.h"
#include "HCSR04Interrupt.h"

HCSR04Interrupt::HCSR04Interrupt(int trigger_pin, int echo_pin, void (*callback)()) {
  _trigger_pin = trigger_pin;
  _echo_pin = echo_pin;
  _callback = callback;

  initialize();
}

void HCSR04Interrupt::setUnits(int units) {
  _units = units;
}

void HCSR04Interrupt::initialize() {
  pinMode(_trigger_pin, OUTPUT);
  pinMode(_echo_pin, INPUT);

  digitalWrite(_trigger_pin, LOW);
}

void HCSR04Interrupt::getDistance() {
  //Listen for the RISING interrupt
  attachInterrupt(_echo_pin - 2, echoHigh, RISING);

  //The trigger pin should be pulled high,
  digitalWrite(_trigger_pin, HIGH);

  //for 10 us.
  delayMicroseconds(20);

  //Then reset it.
  digitalWrite(_trigger_pin, LOW);
}

void HCSR04Interrupt::echoHigh() {
  _micros_start = micros();

  detachInterrupt(_echo_pin - 2);
  attachInterrupt(_echo_pin - 2, echoLow, FALLING);
}

void HCSR04Interrupt::echoLow() {
  detachInterrupt(_echo_pin - 2);

  unsigned long us = micros() - _micros_start;

  distance = us;

  (*_callback)();
}
4

4 に答える 4

5

そのため、 (IDE ではなく)コンパイラが正確に何が問題なのかを教えてくれます。

argument of type 'void (HCSR04Interrupt::)()' does not match 'void (*)()

そのため、 whileattachInterrupt()は type の関数ポインターを受け取りますが、それを非静的メンバー関数void (*)()に渡そうとしていますが、これはできません。メンバー関数の作成とキャストを試すことができます。static

static void echoHigh();

// ...

attachInterrupt(_echo_pin - 2, reinterpret_cast<void (*)()>(&echoHigh), RISING);
于 2013-03-27T20:48:39.540 に答える
2

Arduino の割り込みハンドラは関数のみです。オブジェクトのメソッドを割り込みハンドラにしようとしています。したがって、コンパイラは不平を言います。

より正確に言うと、オブジェクト メソッドは関数に似ていますが、オブジェクト インスタンスを指定する「隠し」パラメーターを受け取るかのようです。したがって、それらは実際にはプレーンな関数とは異なる型シグネチャを持っています。これにより、関数が探しているのが単純な関数ポインターである場合、メソッドポインターを渡すことができなくなります。

echoHigh()解決策は、 andをクラスechoLow()の外に移動しHCSR04Interrupt、単純な関数にすることです。

于 2013-03-27T20:47:36.020 に答える
1

この質問に出くわしましたが、受け入れられた回答がなかったので、見つけたものを書きます。

割り込みは、グローバル ラッパーによって呼び出される必要があります。このラッパーhandleInteruptは、クラスの関数を呼び出す必要があります。したがって、クラスを知る必要があります。これは、グローバル変数に格納することで実行できます。クラスの複数のインスタンスを使用する必要がある場合は、そのようなグローバル変数を複数使用する必要があります。ただし、割り込みピンはほんの一部であるため、すべてのピンに対してグローバル変数と関数を作成できます。

MyClass theInstance_pin3 = NULL;
MyClass theInstance_pin7 = NULL;

// Somewhere, fill in an initialized copy of MyClass,
// and set theInstance_pin3 or theInstance_pin7 to it

void ISR_3()
{
   if (theInstance_pin3)
       theInstance_pin3->handleInterrupt();
}
void ISR_7()
{
   if (theInstance_pin7)
       theInstance_pin7->handleInterrupt();
}

参照として参照してください: http://forum.arduino.cc/index.php?topic=41713.0 またはhttp://forum.arduino.cc/index.php?topic=160101.0

于 2016-01-17T18:51:12.060 に答える