我不是C ++专家,因为我来自电子背景。
我正在尝试制作一个Arduino程序,允许任何人使用标准格式轻松地将传感器添加到Arduino设备。
我想为每个传感器制作一个HAL,因为我创建了一个名为Sensor
的类,它是每个传感器的基类。用户必须创建一个继承自Sensor
类的子类。例如,这个子类称为Sensor_2
(2是ID),它实现了如下函数:
uint16_t getID( void );
uint8_t getAvailableChannels( void );
void sampleChannel( uint8_t aChannel, uint8_t *aDataSize, uint8_t aDataBuffer[] );
这个类调用自己的传感器库,它依赖于传感器。
这样做我可以用标准方式对每个传感器进行采样,而无需重写每个传感器库。
我不知道这是否可以做到,但我想不出更好的事情。
我尝试使用以下代码实现它:
Sensor.h
#ifndef SENSOR_H
#define SENSOR_H
#include "Arduino.h"
class Sensor
{
public:
Sensor();
virtual uint16_t getID( void );
virtual uint8_t getAvailableChannels( void );
virtual void sampleChannel( uint8_t channel, uint8_t dataSize, uint8_t dataBuffer[]);
};
#endif
Sensor_2.h
#ifndef Sensor_2_H
#define Sensor_2_H
#include "Arduino.h"
#include "../../Sensor.h"
#define ID 2
#define CHANNELS 1
class Sensor_2: public Sensor
{
public:
Sensor_2 ( void );
virtual uint16_t getID( void );
virtual uint8_t getAvailableChannels( void );
virtual void sampleChannel( uint8_t aChannel, uint8_t *aDataSize, uint8_t aDataBuffer[] );
};
#endif
Sensor_2.cpp
#include "Sensor_2.h"
Sensor_2::Sensor_2( void )
{
}
uint16_t Sensor_2::getID( void )
{
return (ID);
}
uint8_t Sensor_2::getAvailableChannels( void )
{
return (CHANNELS);
}
void sampleChannel( uint8_t aChannel, uint8_t *aDataSize, uint8_t aDataBuffer[] )
{
aDataSize = 1;
aDataBuffer[0] = hallRead();
}
的main.cpp
#include <Logger.h>
#include "ComHandler.h"
#include "./Sensors/Sensor_2/Sensor_2.h"
ComHandler comHandler;
SensorManager* sensorManager = SensorManager::getInstance();
void setup()
{
Serial.begin(115200);
Logger::setLogLevel(Logger::WARNING);
Sensor_2 sensorHall = new Sensor_2;
sensorManager->addSensor(sensorHall);
}
void loop()
{
uint8_t* datasize;
uint16_t buffer[4];
comHandler.checkForData();
sensorManager.getAvailableSensors()[0].sampleChannel(0,dataSize, buffer);
}
问题是,在尝试编译时,我收到此错误:
conversion from 'Sensor_2*' to non-scalar type 'Sensor_2' requested
Sensor_2 sensorHall = new Sensor_2;
^
如果不是:
Sensor_2 sensorHall = new Sensor_2;
我用:
Sensor_2 sensorHall;
我明白了:
sketch/Sensor.cpp.o:(.literal._ZN6SensorC2Ev+0x0): undefined reference to `vtable for Sensor'
sketch/Winja.ino.cpp.o:(.literal._Z5setupv+0x10): undefined reference to `Sensor_2::Sensor_2()'
sketch/Winja.ino.cpp.o: In function `setup()':
您认为这是实施问题解决方案的好方法吗?如果是这样,我怎么能修复我的错误?
答案 0 :(得分:0)
如果我理解了这个问题,那么你有两个问题(一个是阻塞,另一个不是)。
至于最简单的问题,Sensor_2 sensorHall = new Sensor_2;
无效,因为new
关键字生成指向对象的指针。您有两种方法来生成对象并将其传递给传感器管理器(我假设传感器管理器接受指向传感器的指针):
// Solution 1
Sensor_2 *sensorHall = new Sensor_2;
sensorManager->addSensor(sensorHall);
// Solution 2
Sensor_2 sensorHall;
sensorManager->addSensor(&sensorHall);
但请注意,如果使用解决方案2,则必须将传感器定义放在功能之外。例如,如果你写了
void setup() {
Sensor_2 sensorHall;
sensorManager->addSensor(&sensorHall);
}
然后退出setup
后传感器对象将被销毁。为了避免这种情况,请写
Sensor_2 sensorHall;
void setup() {
sensorManager->addSensor(&sensorHall);
}
至于主要问题,我认为arduino不会在主草图文件夹之外编译源文件(并且它不会递归,因此不扫描子文件夹)。
但是,您尝试执行的操作通常是通过实现库来完成的。您可以找到不同的库和资源来了解库的工作方式(例如,arduino网站上有library tutorial)。您必须在库文件夹中创建一个文件夹,然后放入源文件(在这种情况下,您可以使用子文件夹);编译将成功。这样你就不需要在未来的项目中复制这些文件:它们已经存在了。
如果您不想让它们共享,并且仍然希望将它们放在单独的文件夹中,IIRC可以创建一个名为src的特殊文件夹并将源文件放在那里(同样,不在子文件夹中)。编译时,src文件夹将与sketch文件夹合并。
我的建议:把它变成一个图书馆。完全可重复使用,易于维护,甚至有点突出......