嵌入式设备中传感器应用程序设计体系结构



我不是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

传感器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()':

你认为这是解决我问题的好方法吗?如果是,我该如何修复我的错误?

如果我理解这个问题,这里有两个问题(一个是阻塞,另一个不是)。

对于最简单的问题,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);
}

那么在您退出CCD_ 6之后,传感器对象将被破坏。为了避免这种情况,写入

Sensor_2 sensorHall;
void setup() {
sensorManager->addSensor(&sensorHall);
}

至于主要问题,我认为arduino不会编译主草图文件夹之外的源文件(而且它不会递归,所以不会扫描子文件夹)。

然而,您试图做的事情通常是通过实现库来完成的。你可以找到不同的库和资源来了解库是如何工作的(例如,arduino网站上有一个库教程)。你必须在库文件夹中创建一个文件夹,然后放在源文件中(在这种情况下,你可以使用子文件夹);汇编将会成功。这样,您就不需要在未来的项目中复制这些文件:它们已经存在了。

如果你不想让它们共享,但仍然想把它们放在一个单独的文件夹中,IIRC你可以制作一个名为src的特殊文件夹,并把源文件放在那里(同样,不是放在子文件夹中)。编译时,src文件夹将与草图文件夹合并。

我的建议是:把它变成一个图书馆。完全可重复使用,易于维护,甚至有点突出显示。。。

最新更新