Arduino: Cara mendapatkan jenis papan dalam kode

13

Saya ingin menulis sketsa yang dapat dikompilasi di papan Arduino yang berbeda. Saya ingin menampilkan pada PC papan mana yang saat ini terhubung.

Ini berarti bahwa pengguna menghubungkan PC melalui kabel USB ke papan Arduino / Teensy di mana menjalankan sketsa saya dan sketsa saya memberitahu PC melalui Serial papan mana yang terhubung. Di PC saya menjalankan aplikasi C # yang menerima data ini dan menampilkannya.

Karena itu saya membutuhkan papan yang telah dipilih ketika sketsa telah dikompilasi:

Pemilih Dewan Arduino

Saya menemukan kode di https://github.com/backupbrain/ArduinoBoardManager tetapi tidak memberikan hasil yang benar (terlepas dari kenyataan bahwa beberapa papan hilang).

Berikut cuplikan dari kode:

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(.....

Jadi kode ini memberikan hasil yang sama (BOARD = 0x04 = Mikro) untuk Yun 16MHz, Micro, Leonardo y Esplora.

Apakah ada cara untuk mendapatkan kode C saya persis string yang telah dipilih pengguna dalam menu dari kompiler Arduino?

Elmue
sumber
2
Jika Anda menggunakan arduino IDE untuk membuat firmware, tidak ada ketentuan untuk meneruskan #define tingkat proyek ke kompiler, selain dari F_CPU ARDUINO dan AVR_apapun . Anda mungkin perlu untuk menggunakan makefile untuk membangun, alih-alih arduinio IDE. Lihat situs arduino.SE, Nick dan Ignatio memiliki beberapa contoh bagus.
MarkU
Saya tidak dapat menemukan sesuatu yang menarik di Arduino.SE. (Apakah itu swedia?)
Elmue
@Elmue arduino.StackExchange.com adalah Arduino SE.
Avamander
Ahhhh. BAIK. Tapi arduino.se ada!
Elmue
Dengan "Saya ingin menampilkan pada PC papan mana yang saat ini terhubung" maksud Anda untuk menampilkannya ketika sketsa yang dikompilasi dan diunggah berjalan, atau menampilkannya saat sketsa sedang dikompilasi, atau ketika IDE hanya duduk di sana dengan sebuah tertentu papan terpasang? (Dalam dua kasus terakhir, pemilihan board muncul di baris terendah dari IDE 1.6.3, tetapi jika Anda memiliki IDE yang lebih tua atau berbeda mungkin tidak.) (Jika case pertama berlaku, apakah Anda ingin itu muncul di monitor serial ?)
James Waldby - jwpat7

Jawaban:

17

Berkat bantuan Charlie Hanson dan jantje, saya menemukan solusi universal!

Sangat disayangkan bahwa setiap programmer Arduino harus melalui rasa sakit yang sama untuk mengetahui cara mendapatkan nama papan, saya akan menawarkan kode saya kepada publik sehingga semua orang bisa menyalin dan menempelkannya.

Ini dia:

#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

Anda bahkan dapat memasukkan kode ini ke file header baru dan # memasukkannya ke dalam proyek Anda.

PD Jika Anda ingin tahu lebih lanjut juga tentang model CPU, cari file avr_cpunames.h

Elmue
sumber
hal lain. alih-alih menggunakan "kembali"? ";" ketika Anda tidak tahu, gunakan nama #pragma warning board tidak diketahui
jantje
1.) Saya telah mengganti "?" dengan #error. 2.) Saya tidak berpikir bahwa senar benar-benar masalah. Anda mengerti bahwa hanya SATU string yang akan dikompilasi di akhir? Lihat pembaruan saya yang menjelaskan ini di atas. String terpanjang adalah 11 byte. Jika Anda perlu mengoptimalkan kode sehingga Anda peduli dengan 11 byte, saya sarankan untuk mendefinisikan enum dan mengembalikannya sebagai ganti string. Maka fungsi Anda akan mengembalikan satu byte, bukan 11.
Elmue
3.) Dan apa yang menyangkut kelestarian: Sangat menyedihkan bahwa saya harus menulis fungsi seperti itu. Ini seharusnya sudah menjadi bagian dari file header yang diinstal dengan kompiler dan harus dikelola oleh pengembang dan diperbarui dengan setiap versi baru.
Elmue
2) Saya membuat kesalahan ketika menulis komentar pada ukuran. Saya berkomentar 5 jam yang lalu. Maaf untuk itu. 3) Pemeliharaan adalah masalah. Saya telah menulis kode yang sangat mirip di masa lalu. Saya yakin banyak orang lain juga. Ini adalah rawatan mengapa saya lebih suka "solusi IDE yang lebih baik". Saya yakin semua "IDE yang lebih baik" akan memiliki solusi yang sama dengan yang saya sebutkan dalam jawaban saya. Lihat itu sebagai pelengkap: Anda melebihi IDE Arduino.
jantje
Jika Anda menulis komentar yang salah, yang terbaik adalah menghapusnya.
Elmue
2

perhatikan ini adalah mod windows sesuatu yang serupa harus ada di linux.

Yang pertama cepat dan mudah. Cukup modifikasi file platform.txt yang Anda gunakan seperti dijelaskan di bawah. Yang menarik dari ini adalah Anda perlu mengubah file platform.txt dengan setiap rilis.

tambahkan -DBOARD = \ "$ {build.board} \" ke resep. Ini akan memungkinkan

   const char boardName[]=BOARD;

Yang memberi Anda string "ARDUINO_AVR_LEONARDO" (untuk leonardo) di boardName.

Cara kedua adalah beralih ke IDE yang lebih baik (seperti yang sudah diusulkan oleh orang lain). Sebagai pencipta plugin arduino eclipse, saya akan menyarankan untuk menggunakan plugin arduino eclipse. Dalam plugin arduino eclipse Anda melakukan ini sebagai berikut: Klik kanan pada project-> properties-> arduino-> tab "compile options" put

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

di bidang tambahkan ke C dan C ++.

Ini akan membuat kode di atas untuk dikompilasi

Adendum

Saya tidak sadar Anda menginginkan "nama yang bagus". Saya tidak yakin ini bisa diperbaiki di platform.txt di arduino IDE. Di plugin arduino eclipse ubah fixe di atas di

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

untuk mendapatkan nama yang bagus (untuk leonardo "Arduino Leonardo") di Papan define.

jantje
sumber
Apakah downvoter atau orang lain harap berbaik hati untuk menentukan mengapa ini jawaban perlu downvoting?
jantje
1.) Ya, StackExchange harus memaksa semua orang yang memberikan suara untuk menulis penjelasan. (Itu bukan downvote saya) 2.) Tidak perlu menggunakan Eclipse untuk menyelesaikan masalah ini. 3.) Lihat jawaban saya di sini.
Elmue
Elmue, 1) terima kasih telah menyetujui :-). 2) Saya setuju. Bagian pertama dari jawabannya adalah bagaimana Anda dapat memperbaikinya dengan memodifikasi platform txt sehingga berfungsi di Arduino IDE. Jawaban Anda lebih rinci tentang cara memperbaikinya. Tidak perlu gerhana atau IDE yang lebih baik untuk itu. Solusi ide yang lebih baik disebutkan karena ide Arduino perlu mem-parsing boards.txt sehingga mungkin ada info ini di suatu tempat dan memiliki kemungkinan untuk bekerja tanpa perlu memodifikasi platform.txt. Kebetulan saya tahu plugin arduino eclipse dengan sangat baik saya berikan contoh bagaimana melakukan ini dengan alat ini. 3) Lihat hasil edit saya
jantje
Apakah Eclise juga bekerja dengan Teensy? Apa kelebihan lain yang dimiliki Exclipse?
Elmue
Ya amat, didukung oleh plugin arduino eclipse tetapi Anda harus memod platform.txt (harus diperbaiki di teensyduino 1.28)
jantje
0

Nama-nama persis di menu berasal dari file boards.txt di IDE Arduino Anda (Arduino \ hardware \ arduino \ avr \ boards.txt). Saya pikir Anda harus mengurai file sendiri dan menemukan papan yang terdeteksi di sana.

PW
sumber
Parsing file ?? Dan bagaimana saya tahu yang mana yang dipilih dalam menu?
Elmue
0

Saya mengajukan pertanyaan terkait beberapa waktu lalu.

Ada file * .h internal yang dibuat oleh IDE, dan menyimpan di dalamnya jenis papan yang telah dipilih. Daftar opsi yang memungkinkan diberikan dalam pertanyaan yang ditautkan, tetapi hanya untuk papan AVR. Saya percaya daftar non-AVR jauh lebih pendek.

Ini hanyalah masalah menambahkan beberapa pernyataan kondisional untuk mengirim PC informasi yang benar. Contoh sederhana:

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

Jika Anda perlu merujuk pada jenis papan lebih dari satu kali dalam sketsa, gunakan format berikut:

//...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);

Yang terakhir jauh lebih rapi, bahkan jika Anda hanya perlu __BOARD_TYPEsekali, karena menghapus #ifdefpotongan rumit dari fungsi Anda.

Anda tentu saja harus menulis satu untuk setiap papan yang Anda harapkan dapat dimiliki oleh pengguna akhir Anda, dan Anda mungkin perlu memperbarui daftar ini ketika model baru muncul.

CharlieHanson
sumber
Terima kasih atas jawaban anda. Itu banyak membantu saya. (Lihat jawaban saya di sini) Tetapi ada kesalahan dalam kode Anda. Alih-alih AVR_UNO itu harus ARDUINO_AVR_UNO.
Elmue
Anda mungkin ingin menghapus titik koma di akhir #define Anda; mereka bukan pernyataan C dan tidak perlu pemisah; sebenarnya pemisah akan dimasukkan di mana makro digunakan, tautan di dalam parens fungsi println (). (Jika titik koma dihapus, komentar ini tidak masuk akal untuk pembaca nanti).
Zeph
0

Jawaban asli sudah usang karena papan baru telah ditambahkan. Tes dasar sudah benar, tetapi tidak jelas dari mana daftar papan berasal.

Jika Anda menemukan boards.txtfile dan melihatnya (mis. ~\Library\Arduino\hardware\arduino\avr\boards.txtPada Mac), setiap papan akan memiliki entri di sepanjang baris <BOARD>.build.board=<NAME>, jadi misalnya, MKR1000 akan memiliki baris:

mkr1000.build.board=SAMD_MKR1000

#Define yang sesuai dapat dihasilkan dengan mengawali <NAME>dengan ARDUINO_sehingga dalam contoh ini, kode berikut akan kesalahan untuk papan MKR1000 ...

#if defined(ARDUINO_SAMD_MKR1000) #error

Jason Crocker
sumber
Jawaban ini hanya bla bla. Mengapa Anda tidak memposting daftar lengkap semua papan baru dengan semua definisi?
Elmue