无法在库中使用attachInterrupt

Mac*_*wic 5 arduino interrupt static-libraries

我正在为超声波距离传感器编写一个简单的库,并且我想尝试使用中断.

但是我无法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 (*)()'
Run Code Online (Sandbox Code Playgroud)

这是我的标题:

#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
Run Code Online (Sandbox Code Playgroud)

我的实现(由于我无法通过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)();
}
Run Code Online (Sandbox Code Playgroud)

小智 5

所以编译器(不是IDE)会告诉你到底出了什么问题:

argument of type 'void (HCSR04Interrupt::)()' does not match 'void (*)()
Run Code Online (Sandbox Code Playgroud)

因此,虽然attachInterrupt()采用了类型的函数指针void (*)(),但是你试图将它传递给非静态成员函数,你不能这样做.您可以尝试制作成员函数static和强制转换:

static void echoHigh();

// ...

attachInterrupt(_echo_pin - 2, reinterpret_cast<void (*)()>(&echoHigh), RISING);
Run Code Online (Sandbox Code Playgroud)


ang*_*rge 2

Arduino 中断处理程序只能是函数。您正在尝试使对象的方法成为中断处理程序。因此编译器会抱怨。

更准确地说,对象方法就像函数,但就好像它们采用“隐藏”参数,该参数指定对象实例。因此,它们实际上具有与普通函数不同的类型签名。当函数正在寻找的是普通函数指针时,这不允许传递方法指针。

解决方案是将您的echoHigh()echoLow()移出类HCSR04Interrupt,并使它们成为简单的函数。