嵌入式设备中传感器应用的程序设计架构

时间:2017-11-03 12:24:42

标签: c++ architecture arduino

我不是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()':

您认为这是实施问题解决方案的好方法吗?如果是这样,我怎么能修复我的错误?

1 个答案:

答案 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文件夹合并。

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