Arduino: comment obtenir le type de carte dans le code


13

Je veux écrire un croquis qui peut être compilé sur différentes cartes Arduino. Je veux afficher sur le PC quelle carte est actuellement connectée.

Cela signifie que l'utilisateur connecte le PC via un câble USB à la carte Arduino / Teensy dans laquelle exécute mon croquis et mon croquis indique au PC via Serial quelle carte est connectée. Sur le PC exécute mon application C # qui reçoit ces données et les affiche.

J'ai donc besoin du tableau qui a été sélectionné lors de la compilation du croquis:

Sélecteur de carte Arduino

J'ai trouvé le code sur https://github.com/backupbrain/ArduinoBoardManager mais il ne donne pas de résultats corrects (à part le fait que plusieurs cartes manquent).

Voici un extrait du code:

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

Donc, ce code donne le même résultat (BOARD = 0x04 = Micro) pour Yun 16MHz, Micro, Leonardo y Esplora.

Existe-t-il un moyen d'obtenir dans mon code C exactement la chaîne que l'utilisateur a sélectionnée dans le menu du compilateur Arduino?


2
Si vous utilisez l'IDE Arduino pour construire le firmware, il n'y a aucune disposition pour passer un #define au niveau du projet au compilateur, à part F_CPU ARDUINO et AVR_wwhat . Vous devrez peut-être passer à l'utilisation d'un makefile pour construire, au lieu de l'arduinio IDE. Consultez le site arduino.SE, Nick et Ignatio ont de bons exemples.
MarkU

Je ne trouve rien d'intéressant sur Arduino.SE. (Est-ce suédois?)
Elmue

@Elmue arduino.StackExchange.com est Arduino SE.
Avamander

Ahhhh. D'ACCORD. Mais arduino.se existe!
Elmue

Par «Je veux afficher sur le PC quelle carte est actuellement connectée», voulez-vous l'afficher lorsqu'une esquisse compilée et téléchargée s'exécute, ou l'afficher pendant qu'une esquisse est en cours de compilation, ou alors que l'IDE est juste assis là avec un particulier conseil attaché? (Dans les deux derniers cas, la sélection de la carte apparaît dans la ligne la plus basse de l'IDE 1.6.3, mais si vous avez un IDE plus ancien ou différent peut-être pas.) (Si le premier cas s'applique, voulez-vous qu'il apparaisse dans le moniteur série ?)
James Waldby - jwpat7

Réponses:


17

Grâce à l'aide de Charlie Hanson et jantje, j'ai trouvé la solution universelle!

Parce que c'est dommage que chaque programmeur Arduino doive passer par la même peine pour comprendre comment obtenir le nom de la carte, je vais offrir mon code au public afin que tout le monde puisse simplement le copier et le coller.

C'est ici:

#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

Vous pouvez même mettre ce code dans un nouveau fichier d'en-tête et # l'inclure dans votre projet.

PD Si vous souhaitez connaître en plus de la carte également le modèle de CPU, recherchez le fichier avr_cpunames.h


autre chose. au lieu d'utiliser "retour"? ";" quand vous ne savez pas utiliser le nom du tableau d'avertissement #pragma est inconnu
jantje

1.) J'ai remplacé le "?" avec une #error. 2.) Je ne pense pas que les cordes soient vraiment un problème. Vous avez compris qu'une seule chaîne sera compilée à la fin? Voir ma mise à jour qui explique cela ci-dessus. La chaîne la plus longue est de 11 octets. Si vous avez tellement besoin d'optimiser votre code que vous vous souciez de 11 octets, je vous recommande de définir une énumération et de la renvoyer au lieu d'une chaîne. Ensuite, votre fonction renverra un octet au lieu de 11.
Elmue

3.) Et ce qui concerne la maintenabilité: c'est triste que je doive écrire une telle fonction. Cela devrait déjà faire partie des fichiers d'en-tête installés avec le compilateur et devrait être maintenu par les développeurs et mis à jour avec chaque nouvelle version.
Elmue

2) J'ai fait une erreur en écrivant la remarque sur la taille. J'ai fait une remarque à ce sujet il y a 5 heures. Désolé. 3) La maintenabilité est un problème. J'ai écrit du code très similaire dans le passé. Je suis sûr que beaucoup d'autres l'ont également fait. C'est la maintenabilité pour laquelle je préfère la "meilleure solution IDE". Je suis presque sûr que tous les "meilleurs IDE" auront une solution similaire à celle que j'ai mentionnée dans ma réponse. Voyez-le comme un complément: vous devenez trop grand pour l'IDE Arduino.
jantje

Si vous avez écrit un mauvais commentaire, le mieux serait de le supprimer.
Elmue

2

notez que c'est un mod Windows quelque chose de similaire doit exister sur linux.

Le premier est simple et rapide. Modifiez simplement les fichiers platform.txt que vous utilisez comme décrit ci-dessous. L'inconvénient est que vous devrez modifier les fichiers platform.txt avec chaque version.

ajoutez -DBOARD = \ "$ {build.board} \" à la recette. Cela permettra

   const char boardName[]=BOARD;

Ce qui vous donne la chaîne "ARDUINO_AVR_LEONARDO" (pour le leonardo) dans boardName.

La deuxième façon est de passer à un meilleur IDE (comme déjà proposé par d'autres). En tant que créateur du plugin eclipse arduino, je conseillerais d'utiliser le plugin eclipse arduino. Dans le plugin eclipse arduino, vous procédez comme suit: Faites un clic droit sur le projet-> propriétés-> arduino-> onglet "options de compilation"

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

dans le champ ajouter à C et C ++.

Cela rendra le code ci-dessus pour compiler

Adendum

Je ne savais pas que tu voulais le "joli nom". Je ne suis pas sûr que cela puisse être corrigé dans le platform.txt dans l'arduino IDE. Dans le plugin eclipse arduino, changez le fixe ci-dessus dans

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

pour obtenir le joli nom (pour leonardo "Arduino Leonardo") dans le tableau de définition.


Est-ce que l'électeur ou quelqu'un d'autre pourrait avoir la gentillesse de préciser pourquoi cette réponse doit être diminuée?
jantje

1.) Oui, StackExchange devrait obliger tous ceux qui votent pour écrire une explication. (Ce n'était pas mon downvote) 2.) Il n'est pas nécessaire d'utiliser Eclipse pour résoudre ce problème. 3.) Voir ma réponse ici.
Elmue

Elmue, 1) merci d'avoir accepté :-). 2) Je suis d'accord. La première partie de la réponse est de savoir comment résoudre ce problème en modifiant le txt de la plate-forme afin qu'il fonctionne dans l'IDE Arduino. Votre réponse va plus en détail sur la façon de résoudre ce problème.Pas besoin d'avoir Eclipse ou un meilleur IDE pour cela. La meilleure solution d'idée est mentionnée car une idée Arduino doit analyser le boards.txt donc elle a probablement ces informations quelque part et a la possibilité de fonctionner sans avoir besoin de modifier le platform.txt. Comme je connais très bien le plugin eclipse arduino, je donne un exemple sur la façon de le faire avec cet outil. 3) Voir mon montage
jantje

Eclise fonctionne-t-il également avec Teensy? Quels autres avantages Exclipse?
Elmue

Oui, teensy est pris en charge par le plugin eclipse arduino mais vous devrez modifier le platform.txt (devrait être corrigé dans teensyduino 1.28)
jantje

0

Les noms exacts dans le menu proviennent du fichier boards.txt de votre IDE Arduino (Arduino \ hardware \ arduino \ avr \ boards.txt). Je pense que vous devrez analyser le fichier par vous-même et y trouver la carte détectée.


Analyser le fichier ?? Et comment savoir lequel est sélectionné dans le menu?
Elmue

0

J'ai posé une question connexe il y a quelque temps.

Il existe un fichier interne * .h qui est créé par l'IDE et contient le type de carte qui a été sélectionné. La liste des options possibles est donnée dans la question liée, mais uniquement pour les cartes AVR. Je pense que la liste non AVR est beaucoup plus courte.

Il s'agit simplement d'ajouter des instructions conditionnelles pour envoyer au PC les informations correctes. Un exemple simple:

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

Si vous devez faire référence au type de carte plusieurs fois dans l'esquisse, utilisez le format suivant:

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

Ce dernier est beaucoup plus ordonné, même si vous n'en avez besoin __BOARD_TYPEqu'une seule fois, car il supprime le #ifdefgros morceau de vos fonctions.

Vous devrez bien sûr en écrire un pour chaque carte que vous attendez de votre utilisateur final, et vous devrez peut-être mettre à jour cette liste à mesure que de nouveaux modèles apparaissent.


Merci pour votre réponse. Cela m'a beaucoup aidé. (Voir ma réponse ici) Mais il y a une erreur dans votre code. Au lieu de AVR_UNO, il doit être ARDUINO_AVR_UNO.
Elmue

Vous voudrez peut-être supprimer les points-virgules à la fin de vos #defines; ce ne sont pas des instructions C et n'ont pas besoin de séparateurs; en fait, les séparateurs seront insérés là où les macros sont utilisées, lien à l'intérieur des parens de la fonction println (). (Si les points-virgules sont supprimés, ce commentaire n'aura aucun sens pour les lecteurs ultérieurs).
Zeph

0

La réponse originale est obsolète car de nouveaux tableaux ont été ajoutés. Le test de base est correct, mais on ne sait pas d'où vient la liste des cartes.

Si vous localisez le boards.txtfichier et le parcourez (par exemple ~\Library\Arduino\hardware\arduino\avr\boards.txtsur un Mac), chaque carte aura une entrée dans le sens de <BOARD>.build.board=<NAME>, par exemple, le MKR1000 aurait une ligne:

mkr1000.build.board=SAMD_MKR1000

Le #define correspondant peut être généré en préfixant le <NAME>avec ARDUINO_ainsi dans cet exemple, le code suivant générera une erreur pour une carte MKR1000 ...

#if defined(ARDUINO_SAMD_MKR1000) #error


Cette réponse est juste bla bla. Pourquoi ne postez-vous pas simplement une liste complète de tous les nouveaux tableaux avec toutes les définitions?
Elmue
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.