我正在为arduino写一个库,该库必须在固定延迟后的某个时刻不使用延迟函数而调用该函数。
因为不包括标准的c ++库,所以我必须使用arduino库,我选择了FlexiTimer2,它对于每X个时间单位运行一个函数很有用(这只是一个介绍,问题与arduino不相关,而与c ++相关) )。
.h文件
#ifndef StepperDriverController_h
#define StepperDriverController_h
#include <stdlib.h>
#if ARDUINO >= 100
#include <Arduino.h>
#else
#include <WProgram.h>
#include <wiring.h>
#endif
class StepperDriverController
{
public:
StepperDriverController(unsigned char step, unsigned char direction);
void setPulseWidth(unsigned short width);
// other methods
protected:
void stepPinDown();
void step(bool blocking = true);
private:
unsigned char _pins[2];
// some attributes
};
#endif
.cpp文件
#include "StepperDriverController.h"
#include <Thread.h>
void StepperDriverController::stepPinDown()
{
digitalWrite(_pins[0], LOW);
FlexiTimer2::stop();
}
void StepperDriverController::setPulseWidth(unsigned short width)
{
_pulseWidth = width;
FlexiTimer2::set(width, 1/1000000, stepPinDown);
}
void StepperDriverController::step()
{
digitalWrite(_pins[1], _direction ? HIGH : LOW);
digitalWrite(_pins[0], HIGH);
FlexiTimer2::start();
}
我在代码 FlexiTimer2 :: set(width,1/1000000,stepPinDown); 和'_ pins'中无效使用了非静态成员函数在 digitalWrite(_pins [0],LOW);
上未在此范围内声明我已经阅读了许多与此错误有关的问题,但无论如何都找不到解决方法
编辑
FlexiTimer不应实例化,而应像我一样使用,如官方库example
所示答案 0 :(得分:1)
您要使用的FlexiTimer2::set()
重载声明如下:
namespace FlexiTimer2 {
// ...
void set(unsigned long units, double resolution, void (*f)());
}
第三个参数是void (*f)()
。这是指向 free函数的函数指针,该函数返回void并且不接受任何参数。但是,您正在传递成员函数。这行不通。
然后,您尝试将stepPinDown()
从成员函数更改为自由函数。这也不起作用,因为将其设为免费功能会阻止其访问StepperDriverController
的成员。
相反,您可以做的是传递一个lambda,使其强制与自由函数兼容(使用+
语法),如下所示:
FlexiTimer2::set(width, 1/1000000, +[]{ /* your code here */ });
现在的问题是如何访问StepperDriverController
实例并在其上调用stepPinDown()
。通常对于lambda,您只需对实例进行lambda捕获:
[&obj]{ obj.stepPinDown(); }
但是,这样的lambda无法传递给需要函数指针的函数。 +
中的+[]{ /* your code here */ }
表示法是为了明确表示lambda 一定不能捕获任何东西。如果不进行捕获,则可以省略+
;纯粹是为了拥有自我记录和更清晰的代码。
因此,由于不允许您进行lambda捕获,并且我也不知道代码的确切内部结构,因此尚不清楚如何在lambda中最好地调用stepPinDown()
。但是看来StepperDriverController
是一个单例对象,这意味着它只有一个实例。因此,您可以拥有一个指向该实例的全局指针,并在lambda中使用它:
FlexiTimer2::set(width, 1/1000000, +[]{ globalInstance->stepPinDown(); });
我无法告诉您您的情况下正确的解决方案是什么,但这就是要点。
还有一个与此无关的问题,但值得指出:
1/1000000
这没有做您认为做的事。这是整数除法,结果将为0。您需要:
1.0/1000000.0
为了得到0.000001作为结果。