2017-11-03 9 views
0

私はエレクトロニクスのバックグラウンドから来ているので、私はC++の専門家ではありません。組み込み機器のセンサアプリケーションのプログラム設計アーキテクチャ

私は誰もがArduinoデバイスにセンサーを標準フォーマットで簡単に追加できるArduinoプログラムを作ろうとしています。

各センサーの基本クラスであるSensorという名前のクラスを作成したので、各センサーのHALを作成することを考えました。ユーザーは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();  
} 

メイン:

私は次のコードでそれを実現しようとしました.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; 

私が手:

これは私の問題の解決方法を実装する良い方法だと思いますか?もしそうなら、どうすればエラーを修正できますか?

答えて

0

私が問題を理解していれば、ここでは2つの問題があります(1つはブロックされ、もう1つは問題ありません)。

newキーワードはオブジェクトへのポインタを生成するため、最も簡単な問題は、Sensor_2 sensorHall = new Sensor_2;は無効です。

// 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のWebサイトにはlibrary tutorialがあります)。ライブラリフォルダ内にフォルダを作成してから、ソースファイルの中に入れなければなりません(この場合、サブフォルダを使用できます)。コンパイルは成功します。この方法で、将来のプロジェクトでこれらのファイルをコピーする必要はありません。すでに存在します。

これらを共有したくない場合でも、別のフォルダに配置したい場合は、IIRCで特別なフォルダsrcを作成し、ソースファイルをそこに置くことができます(サブフォルダではありません)。コンパイル時にsrcフォルダがスケッチフォルダとマージされます。

私の提案:ライブラリにしてください。完全に再利用可能で、メンテナンスが容易で、ハイライト表示さえ...

+0

ありがとうございます。私はそれを試みます。私はこれが私の問題に非常に特化しているので、これを図書館にしたいとは思わない。私はこれを実装したいと思いますか?あなたは他の方法でそれをやりますか? – Twistx77

+0

@ Twistx77もしあなたがそれを「普遍的な」ものにするために努力していれば、多くの異なるセンサーが使用できるようになります。それがまさに図書館が発明された理由です。現在のところ、それを使用するのは単なるプロジェクトです。実装に関しては、いいえ、あなたは正しい方法で仕事をしたと思います(共通のインターフェースと異なるメンバーを識別する方法を定義します)。私のプロジェクトでは、数字のIDの代わりに私は通常、子供を識別するためにenumを使用するので、それはより "ユーザーフレンドリー"です – frarugi87

+0

さらにあなたの具体的な仕事はわかりませんが、 。たとえば、私はバイト配列を返す汎用の 'sampleChannel'が必要ですが、私はまた、超音波センサーのためのより特定の' getDistance'、温度のための 'getTemperature'またはADCの' setSampleRate'を望んでいます。 SensorManagerの3番目の要素が温度センサーであることを知っています。それをキャストして物理量を直接得ることができます(変換はメインではなくクラスで行われます) – frarugi87

関連する問題