Arduino:コードでボードタイプを取得する方法


13

異なるArduinoボードでコンパイルできるスケッチを書きたいです。現在接続されているボードをPCに表示したい。

これは、ユーザーがUSBケーブルを介してPCをArduino / Teensyボードに接続し、そこでArduino / Teensyボードが私のスケッチを実行し、私のスケッチがどのボードが接続されているかをシリアルでPCに伝えることを意味します。PC上でこのデータを受信して​​表示するC#アプリケーションを実行します。

したがって、スケッチのコンパイル時に選択されたボードが必要です。

Arduinoボードセレクター

https://github.com/backupbrain/ArduinoBoardManagerでコードを見つけましたが、 正しい結果が得られません(いくつかのボードが欠落しているという事実は別として)。

ここにコードからの抜粋:

static const uint8_t BOARD_MICRO= 0x04;

....
#elif defined(__AVR_Atmega32U4__) // Yun 16Mhz, Micro, Leonardo, Esplora
  static const uint8_t BOARD = 0x04;
  static const uint8_t NUM_BITS = 8;
  static const uint16_t CPU = __AVR_Atmega32U4__;
  static const unsigned long SRAM_SIZE = 2500;
  static const unsigned long EEPROM_SIZE = 1000;
  static const unsigned long FLASH_SIZE = 32000;
#elif defined(.....

したがって、このコードは、Yun 16MHz、Micro、Leonardo y Esploraに対して同じ結果(BOARD = 0x04 = Micro)を返します。

Arduinoコンパイラのメニューでユーザーが選択した文字列をCコードに正確に取得する方法はありますか?


2
arduino IDEを使用してファームウェアをビルドしている場合、F_CPU ARDUINOおよびAVR_whateverを除き、プロジェクトレベルの#defineをコンパイラーに渡すことはできません。arduinio IDEの代わりに、makefileを使用してビルドする必要がある場合があります。arduino.SEサイトをチェックしてください。NickとIgnatioには良い例があります。
MarkU

Arduino.SEで面白いものを見つけることができません。(それはスウェーデン人ですか?)
エルム

@Elmue arduino.StackExchange.comはArduino SEです。
アバンマンダー

ああ。OK。しかし、arduino.seは存在します!
エルム

「現在接続されているボードをPCに表示したい」とは、コンパイルおよびアップロードされたスケッチの実行時に表示するのか、スケッチのコンパイル中またはIDEが特定の場所に座っているときに表示するのかボードが取り付けられていますか?(後者の2つの場合、ボードの選択は1.6.3 IDEの最下行に表示されますが、古いまたは異なるIDEがある場合はそうではありません。)(最初の場合が該当する場合、シリアルモニターに表示しますか? ?)
ジェームズウォルドビー-jwpat7 16年

回答:


17

チャーリー・ハンソンとジャンチェの助けのおかげで、私は普遍的な解決策を見つけました!

すべてのArduinoプログラマーが同じ苦痛を乗り越えてボード名を取得する方法を見つけなければならないのは残念なので、誰でもコピーして貼り付けられるようにコードを公開します。

ここにあります:

#if defined(TEENSYDUINO) 

    //  --------------- Teensy -----------------

    #if defined(__AVR_ATmega32U4__)
        #define BOARD "Teensy 2.0"
    #elif defined(__AVR_AT90USB1286__)       
        #define BOARD "Teensy++ 2.0"
    #elif defined(__MK20DX128__)       
        #define BOARD "Teensy 3.0"
    #elif defined(__MK20DX256__)       
        #define BOARD "Teensy 3.2" // and Teensy 3.1 (obsolete)
    #elif defined(__MKL26Z64__)       
        #define BOARD "Teensy LC"
    #elif defined(__MK64FX512__)
        #define BOARD "Teensy 3.5"
    #elif defined(__MK66FX1M0__)
        #define BOARD "Teensy 3.6"
    #else
       #error "Unknown board"
    #endif

#else // --------------- Arduino ------------------

    #if   defined(ARDUINO_AVR_ADK)       
        #define BOARD "Mega Adk"
    #elif defined(ARDUINO_AVR_BT)    // Bluetooth
        #define BOARD "Bt"
    #elif defined(ARDUINO_AVR_DUEMILANOVE)       
        #define BOARD "Duemilanove"
    #elif defined(ARDUINO_AVR_ESPLORA)       
        #define BOARD "Esplora"
    #elif defined(ARDUINO_AVR_ETHERNET)       
        #define BOARD "Ethernet"
    #elif defined(ARDUINO_AVR_FIO)       
        #define BOARD "Fio"
    #elif defined(ARDUINO_AVR_GEMMA)
        #define BOARD "Gemma"
    #elif defined(ARDUINO_AVR_LEONARDO)       
        #define BOARD "Leonardo"
    #elif defined(ARDUINO_AVR_LILYPAD)
        #define BOARD "Lilypad"
    #elif defined(ARDUINO_AVR_LILYPAD_USB)
        #define BOARD "Lilypad Usb"
    #elif defined(ARDUINO_AVR_MEGA)       
        #define BOARD "Mega"
    #elif defined(ARDUINO_AVR_MEGA2560)       
        #define BOARD "Mega 2560"
    #elif defined(ARDUINO_AVR_MICRO)       
        #define BOARD "Micro"
    #elif defined(ARDUINO_AVR_MINI)       
        #define BOARD "Mini"
    #elif defined(ARDUINO_AVR_NANO)       
        #define BOARD "Nano"
    #elif defined(ARDUINO_AVR_NG)       
        #define BOARD "NG"
    #elif defined(ARDUINO_AVR_PRO)       
        #define BOARD "Pro"
    #elif defined(ARDUINO_AVR_ROBOT_CONTROL)       
        #define BOARD "Robot Ctrl"
    #elif defined(ARDUINO_AVR_ROBOT_MOTOR)       
        #define BOARD "Robot Motor"
    #elif defined(ARDUINO_AVR_UNO)       
        #define BOARD "Uno"
    #elif defined(ARDUINO_AVR_YUN)       
        #define BOARD "Yun"

    // These boards must be installed separately:
    #elif defined(ARDUINO_SAM_DUE)       
        #define BOARD "Due"
    #elif defined(ARDUINO_SAMD_ZERO)       
        #define BOARD "Zero"
    #elif defined(ARDUINO_ARC32_TOOLS)       
        #define BOARD "101"
    #else
       #error "Unknown board"
    #endif

#endif

このコードを新しいヘッダーファイルに入れて、プロジェクトに#includeすることもできます。

PDボードの追加情報とCPUモデルを知りたい場合は、avr_cpunames.hファイルを検索してください。


別物。「return "?";」を使用する代わりに #pragma警告ボードの名前がわからない場合は知らない
-jantje

1.)「?」を置き換えました #エラーで。2.)文字列が本当に問題だとは思わない。最後に1つの文字列のみがコンパイルされることを理解しましたか?上記を説明する私の更新を参照してください。最長の文字列は11バイトです。コードを最適化して、11バイトを必要とする場合は、enumを定義して、文字列ではなくそれを返すことをお勧めします。次に、関数は11ではなく1バイトを返します
。-エルムエ

3.)そして保守性に関係すること:そのような関数を書かなければならないのは悲しいことです。これは、コンパイラとともにインストールされるヘッダーファイルの一部であり、開発者が保守し、新しいバージョンごとに更新する必要があります。
エルム

2)サイズに関する備考を書くときに間違えました。5時間前にそのことについて発言しました。そのために残念。3)保守性が問題です。過去にも非常によく似たコードを書いてきました。他にも多くの人がいると思います。私が「より良いIDEソリューション」を好むのは、保守性です。すべての「より良いIDE」には、私の答えで述べたものと同様の解決策があると確信しています。補足として参照してください:あなたはArduino IDEを成長しています。
jantje

間違ったコメントを書いた場合、それを削除するのが最善です。
エルム

2

これは、Windows MODであり、Linuxにも同様のものが存在する必要があることに注意してください。

最初の方法は迅速かつ簡単です。次の説明に従って、使用しているplatform.txtファイルを変更します。これの欠点は、各リリースでplatform.txtファイルを変更する必要があることです。

-DBOARD = \ "$ {build.board} \"をレシピに追加します。これにより、

   const char boardName[]=BOARD;

boardNameに文字列「ARDUINO_AVR_LEONARDO」(レオナルド用)が表示されます。

2番目の方法は、より良いIDEに切り替えることです(他の人がすでに提案しているように)。arduino eclipseプラグインの作成者として、arduino eclipseプラグインを使用することをお勧めします。arduino eclipseプラグインでは、次のようにこれを実行します。プロジェクト->プロパティ-> arduino-> tab "compile options" putを右クリックします。

-DBOARD=\"${A.BUILD.BOARD}\" 

CおよびC ++フィールドに追加します。

これにより、上記のコードがコンパイルされます

補遺

あなたが「素敵な名前」を望んでいるとは知らなかった。これがarduino IDEのplatform.txtで修正できるかどうかはわかりません。arduino eclipseプラグインで上記の修正を変更します

-DBOARD=\"${A.NAME}\"

定義ボードで素敵な名前(レオナルド「Arduino Leonardo」)を取得します。


ダウンボーターまたは他の誰かは、これが答えである理由をダウンボーティングが必要な理由を指定するように親切にしてください。
jantje

1.)はい、StackExchangeは投票したすべての人に説明を書かせる必要があります。(私の投票ではありませんでした)2.)この問題を解決するためにEclipseを使用する必要はありません。3.)ここで私の答えを参照してください。
エルム

Elmue、1)同意してくれてありがとう:-)。2)同意します。答えの最初の部分は、Arduino IDEで動作するようにプラットフォームのtxtを変更してこれを修正する方法です。あなたの答えは、これを修正する方法についてより詳しく説明しています。日食やそれのためのより良いIDEを持つ必要はありません。Arduino ideはboards.txtを解析する必要があるため、おそらくこの情報がどこかにあり、platform.txtを変更することなく動作する可能性があるため、より良いideソリューションが言及されています。私はたまたまarduino eclipseプラグインを非常によく知っているので、このツールでこれを行う方法の例を示します。3)私の編集を参照してください
-jantje

EcliseはTeensyでも動作しますか?Exclipseには他にどのような利点がありますか?
エルム

はい、teensyはarduino eclipseプラグインでサポートされていますが、platform.txtを変更する必要があります(teensyduino 1.28で修正される必要があります)
jantje

0

メニューの正確な名前は、Arduino IDEのboards.txtファイル(Arduino \ hardware \ arduino \ avr \ boards.txt)から取得されます。自分でファイルを解析し、そこで検出されたボードを見つける必要があると思います。


ファイルを解析しますか?? そして、どのメニューが選択されているかをどのようにして知ることができますか?
エルム

0

私は尋ねた、関連する質問をしばらく前に。

IDEによって作成され、選択されたボードのタイプを保持する内部* .hファイルが存在します。可能なオプションのリストはリンクされた質問にありますが、AVRボードのみです。非AVRリストはずっと短いと思います。

PCに正しい情報を送信するために、いくつかの条件ステートメントを追加するだけです。簡単な例:

//...within your code, perhaps during setup()...
#ifdef ARDUINO_AVR_UNO
    serial.println("UNO");
#endif
#ifdef ARDUINO_AVR_LEONARDO
    serial.println("LEONARDO");
#endif
// etc...

スケッチでボードタイプを複数回参照する必要がある場合は、次の形式を使用します。

//...BEFORE setup(), or otherwise in the global namespace...
#ifdef ARDUINO_AVR_UNO
    #define __BOARD_TYPE "UNO"
#endif
#ifdef ARDUINO_AVR_LEONARDO
    #define __BOARD_TYPE "LEONARDO"
#endif
// etc...

// within your code, wherever necessary:
serial.println(__BOARD_TYPE);

後者は、関数から__BOARD_TYPE面倒な#ifdefチャンクを削除するため、一度だけ必要な場合でも、はるかに整頓されています。

もちろん、エンドユーザーが持つことができるボードごとに1つを作成する必要があります。新しいモデルが表示されたら、このリストを更新する必要があります。


ご回答有難うございます。とても助かりました。(ここで私の答えをご覧ください)しかし、あなたのコードにエラーがあります。AVR_UNOの代わりに、ARDUINO_AVR_UNOでなければなりません。
エルム

#definesの最後にあるセミコロンを削除することもできます。これらはCステートメントではなく、セパレーターを必要としません。実際、セパレーターはマクロが使用される場所に挿入され、println()関数の括弧内にリンクされます。(セミコロンが削除された場合、このコメントは後の読者には意味がありません)。
ゼフ

0

新しいボードが追加されたため、元の答えは古くなっています。基本的なテストは正しいですが、ボードのリストがどこから来たのかは明確ではありません。

boards.txtファイルを見つけてそれを調べると(~\Library\Arduino\hardware\arduino\avr\boards.txtMacなど)、各ボードにはの行に沿ってエントリがあります。<BOARD>.build.board=<NAME>たとえば、MKR1000には次の行があります。

mkr1000.build.board=SAMD_MKR1000

対応する#defineは、この例では<NAME>withを前に付けることで生成できますARDUINO_。MKR1000ボードの場合、次のコードはエラーになります...

#if defined(ARDUINO_SAMD_MKR1000) #error


この答えはただのbla blaです。すべての定義を含むすべての新しいボードの完全なリストを投稿してみませんか?
エルム
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.