Ардуїно: Як отримати тип дошки в коді


13

Я хочу написати ескіз, який можна скласти на різних дошках Arduino. Я хочу показати на ПК, до якої плати зараз підключено.

Це означає, що користувач підключає ПК через USB-кабель до плати Arduino / Teensy, на якій працює мій ескіз, а мій ескіз повідомляє ПК через послідовну програму, до якої плати підключено. На ПК працює мій додаток C #, який отримує ці дані та відображає їх.

Тому мені потрібна рада, яка була обрана після складання ескізу:

Селектор Arduino Board

Я знайшов код на 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(.....

Отже, цей код дає такий же результат (BOARD = 0x04 = Micro) для Yun 16 МГц, Micro, Leonardo y Esplora.

Чи є спосіб отримати в моєму коді C саме ту строку, яку користувач вибрав у меню компілятора Arduino?


2
Якщо ви використовуєте ID Arduino IDE для створення мікропрограмного забезпечення, немає можливості передавати #define проектного рівня компілятору, окрім F_CPU ARDUINO та AVR_ незалежно від цього . Можливо, вам знадобиться застосувати графічний файл замість arduinio IDE. Перевірте сайт arduino.SE, Нік та Ігнатіо мають кілька хороших прикладів.
MarkU

Я не можу знайти нічого цікавого на Arduino.SE. (Це
шведка

@Elmue arduino.StackExchange.com - це Arduino SE.
Avamander

А-а-а. ГАРАЗД. Але arduino.se існує!
Елму

Під "Я хочу відобразити на ПК, до якої плати зараз підключено", ви маєте на увазі відобразити її під час запуску складеного та завантаженого ескізу, або відобразити його під час компіляції ескізу або тоді, коли IDE просто сидить там із певним дошка додається? (У двох останніх випадках вибір дошки відображається в нижньому рядку ID ID 1.6.3, але якщо у вас є старший або інший IDE, можливо, ні.) (Якщо застосовується перший випадок, ви хочете, щоб він відображався на послідовному моніторі ?)
Джеймс Уолдбі - jwpat7

Відповіді:


17

Завдяки допомозі Чарлі Хансона та jantje я знайшов універсальне рішення!

Оскільки шкода, що кожен програміст 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 Якщо ви хочете додатково знати на платі також модель процесора, знайдіть файл avr_cpunames.h


Ще одна річ. замість використання "return"? ";" коли ви не знаєте використовувати #pragma попереджувальну дошку невідомо
jantje

1.) Я замінив "?" з #error. 2.) Я не думаю, що струни насправді є проблемою. Ви розуміли, що в кінці буде складено лише ОДИН рядок? Дивіться моє оновлення, яке пояснює це вище. Найдовший рядок - 11 байт. Якщо вам потрібно настільки оптимізувати свій код, що вам важливо 11 байтів, рекомендую визначити enum і повернути це замість рядка. Тоді ваша функція поверне один байт замість 11.
Elmue

3.) А що стосується ремонтопридатності: Сумно, що я повинен написати таку функцію. Це повинні бути вже частиною файлів заголовків, які встановлені разом із компілятором і повинні підтримуватися розробниками та оновлюватися кожною новою версією.
Елмуе

2) Я помилився, написавши зауваження про розмір. Я зробив зауваження з цього приводу 5 годин тому. Вибачте за це. 3) Обслуговування є проблемою. Я раніше писав дуже подібний код. Я впевнений, що також багато інших. Саме для ремонту я віддаю перевагу «кращому рішенню IDE». Я впевнений, що всі «кращі ІДЕ» матимуть подібне рішення, як те, про яке я згадував у своїй відповіді. Розгляньте це як доповнення: Ви переростаєте IDE Arduino.
jantje

Якщо ви написали неправильний коментар, найкраще було б його видалити.
Елмуе

2

Зауважте, це мод Windows, щось подібне повинно існувати на Linux.

Перший - швидко і легко. Просто змініть файли platform.txt, які ви використовуєте, як описано нижче. Недолік цього полягає в тому, що вам потрібно буде змінювати файли platform.txt з кожним випуском.

додати в рецепт -DBOARD = \ "$ {build.board} \". Це дозволить зробити

   const char boardName[]=BOARD;

Що дає вам рядок "ARDUINO_AVR_LEONARDO" (для леонардо) у boardName.

Другий спосіб - перейти на кращу IDE (як це вже запропоновано іншими). Як творець плагіна arduino eclipse, я б радив використовувати плагін arduino eclipse. У плагін arduino eclipse ви робите це так: Клацніть правою кнопкою миші на проект-> властивості-> arduino-> вкладку "параметри компіляції"

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

у додатку до полів C і C ++.

Це зробить код вище для компіляції

Додаток

Я не знав, що ти хочеш "приємного імені". Я не впевнений, що це можна виправити в платформі.txt в IDE arduino. У плагін Arduino eclipse змініть виправлене вище в

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

щоб отримати приємне ім'я (для Леонардо "Ардуїно Леонардо") у визначній раді.


Чи хотіли б користувачі, які звернулися до них, чи хтось інший, будь ласка, щоб уточнити, чому саме ця відповідь потребує зворотного схилення?
jantje

1.) Так, StackExchange повинен змусити всіх, хто голосує, написати пояснення. (Це був не мій відгук) 2.) Не потрібно використовувати Eclipse для вирішення цієї проблеми. 3.) Дивіться мою відповідь тут.
Елмуе

Elmue, 1) дякую за згоду :-). 2) Я згоден. Перша частина відповіді полягає в тому, як ви можете виправити цю зміну txt платформи, щоб вона працювала в ID Arduino. Ваша відповідь детальніше розповідає про те, як це виправити. Не потрібно мати затемнення чи кращого IDE для цього. Краще рішення ідеї згадується тому, що ідея Arduino повинна проаналізувати boards.txt, щоб він, мабуть, десь мав цю інформацію та мав можливість працювати без зміни платформи.txt. Оскільки я випадково дуже добре знаю плагін arduino eclipse, я наводжу приклад того, як це зробити за допомогою цього інструменту. 3) Дивіться мою
редакцію

Чи Eclise також працює з Teensy? Які ще переваги має Exclipse?
Елмуе

Так, teensy підтримується плагіном Arduino eclipse, але вам доведеться модифікувати платформу.txt (має бути зафіксовано в teensyduino 1.28)
jantje

0

Точні назви в меню походять з файлу Board.txt у вашому ID-файлі Arduino (Arduino \ hardware \ arduino \ avr \ boards.txt). Я думаю, вам доведеться самостійно розібрати файл і знайти там виявлену дошку.


Розбір файлу ?? І як я можу дізнатись, який з них є selecetd у меню?
Елму

0

Я задав споріднене питання деякий час тому.

Існує внутрішній * .h файл, який створюється IDE, і містить у ньому тип обраної плати. Перелік можливих варіантів наведено у пов'язаному питанні, але лише для дощок AVR. Я вважаю, що не-AVR список набагато коротший.

Просто додати деякі умовні заяви, щоб надіслати ПК правильну інформацію. Простий приклад:

//...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шматок від ваших функцій.

Звичайно, вам доведеться написати по одній платі для кожної дошки, яку, на вашу думку, міг би мати ваш кінцевий користувач, і вам, можливо, потрібно буде оновити цей список, коли з’являться нові моделі.


Дякую за вашу відповідь. Це мені дуже допомогло. (Дивіться мою відповідь тут) Але у вашому коді є помилка. Замість AVR_UNO це повинно бути ARDUINO_AVR_UNO.
Елмуе

Ви можете видалити крапки з комою в кінці #defines; вони не є твердженнями C і не потребують роздільників; насправді роздільники будуть вставлені там, де використовуються макроси, посилання всередині паролів функції println (). (Якщо крапки з комою вилучено, цей коментар не матиме сенсу для наступних читачів).
Зеф

0

Оригінальна відповідь застаріла, оскільки були додані нові дошки. Основний тест є правильним, але незрозуміло, звідки береться список дощок.

Якщо ви boards.txtзнайдете файл і переглянете його (наприклад, ~\Library\Arduino\hardware\arduino\avr\boards.txtна Mac), кожна плата матиме запис у рядках рядків <BOARD>.build.board=<NAME>, наприклад, у MKR1000 буде рядок:

mkr1000.build.board=SAMD_MKR1000

Відповідний #define може бути породжена Приставка <NAME>з ARDUINO_так що в цьому прикладі, наступний код помилки для MKR1000 дошки ...

#if defined(ARDUINO_SAMD_MKR1000) #error


Ця відповідь - просто бла-бла. Чому ви просто не опублікуєте повний список всіх нових дощок з усіма визначеними?
Елму
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.