web-dev-qa-db-ja.com

Arduinoスケッチに.cppおよび.hファイルを含める正しい方法

まず、問題:

メインスケッチファイル:

char foo;            // required to clean up some other problems
#include <Arduino.h> // tried it in desperation, no help
#include "a.h"

void setup(){
  Serial.begin(9600);
  Serial.println("\nTest begins");
  for (int num = -1; num < 1; num++){
    Serial.print(num);
    if (isNegative(num)){
      Serial.println(" is negative");
    } else {
      Serial.println(" is NOT negative");
    }
  }
}

void loop(){}

// a.h

#ifndef H_A
#define H_A

boolean isNegative(int x);                  // Err#1
int anotherOdity();

#endif // H_A

// a.cpp

#include "a.h"

int isNegative(int x){
  Serial.println("I can't print this from inside my INCLUDE FILE"); //Err#2
  if (x<0) return true;
  return false;
}

int anotherOdity(){
  char ch[5];
  memcpy(ch,"1",1);  //doesn't work, memcpy not declared      // Err#3
}

上記はそのままではコンパイルされず、これらは私が得るエラーです:

In file included from a.cpp:1:
a.h:4: error: 'boolean' does not name a type
a.cpp: In function 'int isNegative(int)':
a.cpp:4: error: 'Serial' was not declared in this scope
a.cpp: In function 'int anotherOdity()':
a.cpp:11: error: 'memcpy' was not declared in this scope

最初の問題はブール型で、Arduino環境で行われる名前のマングリングに苦しんでいるようですが、通常はメインファイルのchar foo;によって修正されます。そして、特定の状況ではそうです。ただし、.cppファイルでそのタイプを使用すると、このエラーが生成されます。

エラー2とエラー3は関連していることがわかりますが、これらをスコープ内で取得するにはどうすればよいですか? Serialmemcpyがまだ定義/宣言されていないため、問題の一部はおそらく#include自体(おそらく)であることを認識していますか? Arduino.hライブラリを含めてみましたが、それは役に立ちませんでした。実際には、ブール値の問題は解決しましたが、.hファイルにすべてを入れる場合にのみ(以下でさらに説明します)、上記の例は役に立ちません。

3つのファイルをまとめて、すべてをメインスケッチ(.ino)ファイルに含めると、正常に機能します。しかし、ここでの考え方は、コードを分割してスケッチを読みやすくしたいということです。

ソリューションに最も近いものはここにありました: http://liudr.wordpress.com/2011/02/16/using-tabs-in-arduino-ide/ ここで、自分で実行した後テストにより、すべてを.hファイルに入れると機能することを確認しました。

たとえば、a.cppを削除してa.hだけを作成すると(次のように)、メインスケッチファイルを変更せずにそのまま使用できます。

#ifndef H_A
#define H_A

boolean isNegative(int x){
  Serial.println("I can't print this from inside my INCLUDE FILE");
  if (x<0) return true;
  return false;
}

int anotherOdity(){
  char ch[5];
  memcpy(ch,"1",1);  //doesn't work, memcpy not declared
}

#endif // H_A

これにより、ブール値の問題が解決されます(...まだArduino.hまたはchar foo;が必要です)、およびスコープの問題が修正されています。

しかし、それはただ間違っているように感じます。

これは、さまざまなスケッチで使用できる標準関数のライブラリを作成することではなく、コードを小さな(読み取り可能な)チャンクに分割し、プロジェクトフォルダーにまとめて保持することです。これを可能な限り最も正しい方法で実行したいのですが、IDEによって制限されているようです。ヘッダーと関連する.cppファイルをまとめる方法について適切に理解しているはずです(その部分が間違っていないことを願っています)。

私はC/C++のすべてを完全に独学で教えており、ごく最近になってマイクロプログラミングを始めたばかりです。

私はグーグルの奥深くでこれを研究してきましたが、継続的に不足しています。

hacksに頼らず、私のような人々のためにシンプルに保つことなく、Arduino IDE/gccがコンパイルできるように上記の例をまとめるにはどうすればよいでしょうか?

編集:ここで開いたタブの一部だけを含めて、これに関する調査を本当に行ったことを示すと思いました!

http://arduino.cc/en/Reference/Include

http://arduino.cc/en/Hacking/LibraryTutorial

http://forum.arduino.cc/index.php/topic,124904.msg938861.html#msg938861

http://forum.arduino.cc/index.php?topic=84412. (これは私がchar foo;ソリューションを見つけた場所です)

http://liudr.wordpress.com/2011/02/16/using-tabs-in-arduino-ide/

。cppファイルを含む

Arduinoスケッチディレクトリにすべてのライブラリを保持する

C++ヘッダーとCPPを含む

12
Madivad

動作しない理由は、a.hまたはa.cppファイルに何かを含める必要があるためです。

これをa.hファイルで試してみると、すべてが機能するはずです。

#ifndef H_A
#define H_A

#include <Arduino.h> //needed for Serial.println
#include <string.h> //needed for memcpy

...

これは、コンパイラが各cppファイルを個別にコンパイルすると考えることができるためです。 #includeは、実際には単なる自動コピーペーストです。コンパイラがa.cppをコンパイルしようとするとき、Serial.println()がa.hで定義されていなかったため、Serial.println()が存在することがわかりません。これは、a.cppに表示される他の唯一のテキストです。ヘッダーにすべてを入れると動作する理由は、メインのcppファイルでah includeの前にArduino.hをインクルードしているためです。そのため、それらの#includesをコピーして、あたかもそこにコードを書いたかのように貼り付けます。最初の場所。

すべてのコードをヘッダーに書き込むだけでかまいませんが、コンパイル時の効率など、さまざまな理由からお勧めできません(ただし、arduinoプログラムは32kしか使用できないため、コンパイル時間が長くなりすぎるとは思いません!)

20
user2711915