Arduino: Wie bekomme ich den Board-Typ in Code

13

Ich möchte eine Skizze schreiben, die auf verschiedenen Arduino-Boards kompiliert werden kann. Ich möchte auf dem PC anzeigen, welche Karte gerade angeschlossen ist.

Dies bedeutet, dass der Benutzer den PC über ein USB-Kabel mit dem Arduino / Teensy-Board verbindet, auf dem meine Skizze ausgeführt wird, und dem PC über Serial mitteilt, welches Board angeschlossen ist. Auf dem PC läuft meine C # -Anwendung, die diese Daten empfängt und anzeigt.

Deshalb brauche ich die Tafel, die beim Erstellen der Skizze ausgewählt wurde:

Arduino Board-Selektor

Ich habe den Code auf https://github.com/backupbrain/ArduinoBoardManager gefunden, aber er liefert keine korrekten Ergebnisse (abgesehen von der Tatsache, dass mehrere Boards fehlen).

Hier ein Ausschnitt aus dem 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(.....

Dieser Code liefert also dasselbe Ergebnis (BOARD = 0x04 = Micro) für Yun 16MHz, Micro, Leonardo und Esplora.

Gibt es eine Möglichkeit, in meinem C-Code genau die Zeichenfolge abzurufen, die der Benutzer im Menü des Arduino-Compilers ausgewählt hat?

Elmue
quelle
2
Wenn Sie die Firmware mit der Arduino-IDE erstellen, gibt es keine Möglichkeit, dem Compiler eine #Definition auf Projektebene zu übergeben , abgesehen von F_CPU ARDUINO und AVR_whatever . Möglicherweise müssen Sie anstelle von arduinio IDE ein Makefile zum Erstellen verwenden. Überprüfen Sie die arduino.SE-Site, Nick und Ignatio haben einige gute Beispiele.
MarkU
Ich kann auf Arduino.SE nichts Interessantes finden. (Ist das schwedisch?)
Elmue
@Elmue arduino.StackExchange.com ist Arduino SE.
Avamander
Ahhhh. IN ORDNUNG. Aber arduino.se existiert!
Elmue
Mit „Ich möchte auf dem PC anzeigen, welche Karte gerade angeschlossen ist“ meinen Sie, dass sie angezeigt wird, wenn eine kompilierte und hochgeladene Skizze ausgeführt wird, oder dass sie angezeigt wird, während eine Skizze kompiliert wird oder wenn die IDE nur mit einer bestimmten Karte zusammenarbeitet board angebracht? (In den letzten beiden Fällen wird die Kartenauswahl in der untersten Zeile der 1.6.3-IDE angezeigt, aber wenn Sie eine ältere oder eine andere IDE haben, ist dies möglicherweise nicht der Fall.) (Wenn der erste Fall zutrifft, soll sie auf dem seriellen Monitor angezeigt werden ?)
James Waldby - jwpat7

Antworten:

17

Dank der Hilfe von Charlie Hanson und jantje habe ich die universelle Lösung gefunden!

Da es schade ist, dass jeder Arduino-Programmierer denselben Schmerz durchmachen muss, um herauszufinden, wie er an den Board-Namen kommt, biete ich meinen Code der Öffentlichkeit an, damit jeder ihn einfach kopieren und einfügen kann.

Hier ist es:

#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

Sie können diesen Code sogar in eine neue Header-Datei einfügen und # in Ihr Projekt einbinden.

PD Wenn Sie zusätzlich zur Karte auch das CPU-Modell kennen wollen, suchen Sie die Datei avr_cpunames.h

Elmue
quelle
etwas anderes. anstelle von "return"? ";" Wenn Sie nicht wissen, verwenden Sie # Pragma Warning Board Name ist unbekannt
1.
1.) Ich habe das "?" mit einem # Fehler. 2.) Ich denke nicht, dass die Saiten wirklich ein Problem sind. Sie haben verstanden, dass am Ende nur EIN String kompiliert wird? Siehe mein Update, das dies oben erklärt. Die längste Zeichenfolge ist 11 Byte. Wenn Sie Ihren Code so optimieren müssen, dass Ihnen 11 Byte wichtig sind, empfehle ich, eine Enumeration zu definieren und diese anstelle einer Zeichenfolge zurückzugeben. Dann gibt Ihre Funktion ein Byte anstelle von 11 zurück.
Elmue
3.) Und was die Wartbarkeit betrifft: Es ist traurig, dass ich eine solche Funktion schreiben muss. Dies sollte bereits Teil der Header-Dateien sein, die mit dem Compiler installiert werden, und sollte von den Entwicklern gepflegt und mit jeder neuen Version aktualisiert werden.
Elmue
2) Beim Schreiben der Bemerkung zur Größe ist mir ein Fehler unterlaufen. Ich habe vor 5 Stunden eine Bemerkung dazu gemacht. Das tut mir leid. 3) Die Wartbarkeit ist ein Problem. Ich habe in der Vergangenheit sehr ähnlichen Code geschrieben. Ich bin sicher, viele andere haben das auch. Aus Gründen der Wartbarkeit bevorzuge ich die "bessere IDE-Lösung". Ich bin mir ziemlich sicher, dass alle "besseren IDEs" eine ähnliche Lösung haben werden wie die, die ich in meiner Antwort erwähnt habe. Sehen Sie es als Ergänzung: Sie wachsen aus der Arduino IDE heraus.
1.
Wenn Sie einen falschen Kommentar geschrieben haben, löschen Sie ihn am besten.
Elmue
2

Beachten Sie, dass dies ein Windows-Mod ist, der unter Linux ähnlich sein muss.

Der erste ist schnell und einfach. Ändern Sie einfach die von Ihnen verwendeten platform.txt-Dateien wie unten beschrieben. Dies hat den Nachteil, dass Sie die platform.txt-Dateien mit jeder Version ändern müssen.

Füge -DBOARD = \ "$ {build.board} \" zum Rezept hinzu. Dies ermöglicht

   const char boardName[]=BOARD;

Was gibt Ihnen die Zeichenfolge "ARDUINO_AVR_LEONARDO" (für den Leonardo) in Boardname.

Die zweite Möglichkeit besteht darin, auf eine bessere IDE zu wechseln (wie bereits von anderen vorgeschlagen). Als Entwickler des Arduino Eclipse Plugins würde ich empfehlen, das Arduino Eclipse Plugin zu verwenden. Im Arduino Eclipse Plugin machen Sie dies wie folgt: Klicken Sie mit der rechten Maustaste auf das Feld "Kompilieroptionen"

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

im Feld Anhängen an C und C ++.

Dadurch wird der obige Code kompiliert

Adendum

Mir war nicht bewusst, dass Sie den "schönen Namen" wollten. Ich bin nicht sicher, ob dies in der platform.txt in Arduino IDE behoben werden kann. Ändern Sie im Arduino Eclipse-Plugin das Fixe oben in

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

um den schönen Namen (für den Leonardo "Arduino Leonardo") im Define Board zu bekommen.

jantje
quelle
Wäre der Downvoter oder sonst jemand so freundlich, um anzugeben, warum diese Antwort downvoting benötigt?
28.
1.) Ja, StackExchange sollte jeden, der abstimmt, dazu zwingen, eine Erklärung zu verfassen. (Es war nicht meine Ablehnung) 2.) Es besteht keine Notwendigkeit, Eclipse zu verwenden, um dieses Problem zu lösen. 3.) Siehe meine Antwort hier.
Elmue
Elmue, 1) danke fürs zustimmen :-). 2) Ich stimme zu. Der erste Teil der Antwort ist, wie Sie dieses Problem beheben können, indem Sie die Plattform txt so ändern, dass sie in der Arduino IDE funktioniert. In Ihrer Antwort erfahren Sie mehr darüber, wie Sie dieses Problem beheben können. Dafür benötigen Sie weder Eclipse noch eine bessere IDE. Die bessere Ide-Lösung wird erwähnt, weil ein Arduino-Ide die Datei boards.txt analysieren muss, damit er diese Informationen wahrscheinlich irgendwo hat und die Möglichkeit hat, zu arbeiten, ohne die Datei platform.txt ändern zu müssen. Da ich das Arduino Eclipse Plugin sehr gut kenne, gebe ich ein Beispiel, wie dies mit diesem Tool gemacht wird. 3) Siehe mein edit
jantje
Funktioniert Eclise auch mit Teensy? Welche weiteren Vorteile hat Exclipse?
Elmue
Ja, teensy wird vom arduino Eclipse-Plugin unterstützt, aber Sie müssen die platform.txt modifizieren (sollte in teensyduino 1.28 behoben sein)
2.
0

Die genauen Namen im Menü stammen aus der Datei boards.txt in Ihrer Arduino IDE (Arduino \ hardware \ arduino \ avr \ boards.txt). Ich denke, Sie müssten die Datei selbst analysieren und die erkannte Karte dort finden.

PW
quelle
Datei analysieren? Und woher weiß ich, welche im Menü ausgewählt ist?
Elmue
0

Ich habe vor einiger Zeit eine verwandte Frage gestellt .

Es ist eine interne * .h-Datei vorhanden, die von der IDE erstellt wird und den ausgewählten Kartentyp enthält. Die Liste der möglichen Optionen ist in der verknüpften Frage angegeben, jedoch nur für AVR-Karten. Ich glaube, die Nicht-AVR-Liste ist viel kürzer.

Es müssen lediglich einige bedingte Anweisungen hinzugefügt werden, um die richtigen Informationen an den PC zu senden. Ein einfaches Beispiel:

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

Wenn Sie sich in der Skizze mehrmals auf den Kartentyp beziehen müssen, verwenden Sie das folgende Format:

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

Letzteres ist viel aufgeräumter, auch wenn Sie es nur __BOARD_TYPEeinmal benötigen , da es den umständlichen #ifdefTeil Ihrer Funktionen entfernt.

Sie müssen natürlich eine für jedes Board schreiben, von dem Sie erwarten, dass es Ihrem Endbenutzer zur Verfügung steht, und Sie müssen diese Liste möglicherweise aktualisieren, sobald neue Modelle erscheinen.

CharlieHanson
quelle
Danke für deine Antwort. Es hat mir sehr geholfen. (Siehe meine Antwort hier) Aber es gibt einen Fehler in Ihrem Code. Anstelle von AVR_UNO muss es ARDUINO_AVR_UNO sein.
Elmue
Möglicherweise möchten Sie die Semikolons am Ende Ihrer #Definitionen entfernen. Sie sind keine C-Anweisungen und benötigen keine Trennzeichen. Tatsächlich werden die Trennzeichen dort eingefügt, wo die Makros verwendet werden. Verknüpfen Sie diese innerhalb der Parens der Funktion println (). (Wenn die Semikolons entfernt werden, ist dieser Kommentar für spätere Leser nicht sinnvoll.)
Zeph
0

Die ursprüngliche Antwort ist veraltet, da neue Boards hinzugefügt wurden. Der Basistest ist korrekt, aber es ist nicht klar, woher die Liste der Boards stammt.

Wenn Sie die boards.txtDatei suchen und sie durchsehen (z. B. ~\Library\Arduino\hardware\arduino\avr\boards.txtauf einem Mac), hat jedes Board einen Eintrag in der Art von <BOARD>.build.board=<NAME>, sodass der MKR1000 beispielsweise eine Zeile hat:

mkr1000.build.board=SAMD_MKR1000

Das entsprechende #define kann durch das Präfix <NAME>mit erzeugt werden, ARDUINO_so dass in diesem Beispiel der folgende Code für eine MKR1000-Karte fehlerhaft ist ...

#if defined(ARDUINO_SAMD_MKR1000) #error

Jason Crocker
quelle
Diese Antwort ist nur bla bla. Warum postest du nicht einfach eine vollständige Liste aller neuen Boards mit allen Definitionen?
Elmue