Arduino: come ottenere il tipo di scheda nel codice


13

Voglio scrivere uno schizzo che può essere compilato su diverse schede Arduino. Voglio visualizzare sul PC quale scheda è attualmente connessa.

Ciò significa che l'utente collega il PC tramite cavo USB alla scheda Arduino / Teensy in cui viene eseguito il mio schizzo e il mio schizzo comunica al PC tramite seriale quale scheda è collegata. Sul PC esegue la mia applicazione C # che riceve questi dati e li visualizza.

Pertanto ho bisogno della scheda selezionata quando lo schizzo è stato compilato:

Selettore scheda Arduino

Ho trovato il codice su https://github.com/backupbrain/ArduinoBoardManager ma non fornisce risultati corretti (a parte il fatto che mancano diverse schede).

Ecco uno snippet dal codice:

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

Quindi questo codice dà lo stesso risultato (BOARD = 0x04 = Micro) per Yun 16MHz, Micro, Leonardo y Esplora.

C'è un modo per ottenere nel mio codice C esattamente la stringa che l'utente ha selezionato nel menu del compilatore Arduino?


2
Se stai usando l'IDE arduino per costruire il firmware, non è previsto il passaggio di un #define a livello di progetto al compilatore, a parte F_CPU ARDUINO e AVR_whatever . Potrebbe essere necessario ricorrere all'utilizzo di un makefile per creare, invece di arduinio IDE. Controlla il sito arduino.SE, Nick e Ignatio hanno alcuni buoni esempi.
MarkU,

Non riesco a trovare nulla di interessante su Arduino.SE. (È svedese?)
Elmue,

@Elmue arduino.StackExchange.com è Arduino SE.
Avamandro,

Ahhhh. OK. Ma arduino.se esiste!
Elmue,

Con "Voglio visualizzare sul PC quale scheda è attualmente connessa" intendi visualizzarlo quando viene eseguito uno schizzo compilato e caricato, oppure visualizzarlo mentre uno schizzo è in fase di compilazione o mentre l'IDE è semplicemente seduto lì con un particolare scheda allegata? (Negli ultimi due casi, la selezione della scheda viene visualizzata nella riga più bassa dell'IDE 1.6.3, ma se si dispone di un IDE più vecchio o diverso, forse no.) (Se si applica il primo caso, si desidera che appaia nel monitor seriale ?)
James Waldby - jwpat7,

Risposte:


17

Grazie all'aiuto di Charlie Hanson e jantje ho trovato la soluzione universale!

Poiché è un peccato che ogni programmatore Arduino debba affrontare lo stesso dolore per capire come ottenere il nome della scheda, offrirò il mio codice al pubblico in modo che tutti possano semplicemente copiarlo e incollarlo.

Ecco qui:

#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

Puoi persino inserire questo codice in un nuovo file di intestazione e #includerlo nel tuo progetto.

PD Se si desidera conoscere in aggiunta alla scheda anche il modello di CPU, cercare il file avr_cpunames.h


un'altra cosa. invece di utilizzare "return"? ";" quando non si conosce usare #pragma il nome della bacheca è sconosciuto
jantje

1.) Ho sostituito il "?" con un #error. 2.) Non penso che le stringhe siano davvero un problema. Hai capito che alla fine verrà compilata UNA SOLO stringa? Vedi il mio aggiornamento che spiega questo sopra. La stringa più lunga è di 11 byte. Se hai bisogno di ottimizzare il tuo codice così tanto da preoccuparti di circa 11 byte, ti consiglio di definire un enum e restituirlo al posto di una stringa. Quindi la tua funzione restituirà un byte anziché 11.
Elmue

3.) E ciò che riguarda la manutenibilità: è triste dover scrivere una tale funzione. Questo dovrebbe essere già parte dei file di intestazione installati con il compilatore e dovrebbe essere gestito dagli sviluppatori e aggiornato con ogni nuova versione.
Elmue

2) Ho fatto un errore durante la scrittura dell'osservazione sulla dimensione. Ho fatto un'osservazione su questo 5 ore fa. Scusa per quello. 3) La manutenibilità è un problema. Ho scritto un codice molto simile in passato. Sono sicuro che anche molti altri. È la manutenibilità perché preferisco la "migliore soluzione IDE". Sono abbastanza sicuro che tutti gli "IDE migliori" avranno una soluzione simile a quella che ho menzionato nella mia risposta. Vedilo come un complemento: stai superando l'IDE di Arduino.
jantje,

Se hai scritto un commento sbagliato, la cosa migliore sarebbe eliminarlo.
Elmue

2

nota che questa è una mod di Windows qualcosa di simile deve esistere su Linux.

Il primo è semplice e veloce. Modifica semplicemente i file platform.txt che stai utilizzando come descritto nel seguito. Lo svantaggio di questo è che dovrai cambiare i file platform.txt ad ogni versione.

aggiungi -DBOARD = \ "$ {build.board} \" alla ricetta. Ciò consentirà

   const char boardName[]=BOARD;

Che ti dà la stringa "ARDUINO_AVR_LEONARDO" (per il leonardo) in boardName.

Il secondo modo è passare a un IDE migliore (come già proposto da altri). Come creatore del plug-in eclissi arduino, consiglierei di usare il plug-in eclissi arduino. Nel plug-in eclipse di arduino lo fai come segue: fai clic destro sul progetto-> proprietà-> arduino-> scheda "compila opzioni"

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

nell'appendice ai campi C e C ++.

Questo renderà il codice sopra compilato

Adendum

Non sapevo che volessi il "bel nome". Non sono sicuro che questo possa essere risolto in platform.txt nell'IDE di Arduino. Nel plug-in eclissi di Arduino cambia la correzione sopra in

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

per ottenere il bel nome (per il leonardo "Arduino Leonardo") nel Consiglio di amministrazione.


Per favore, il downvoter o chiunque altro sarebbe così gentile da specificare perché questa risposta ha bisogno del downvoting?
jantje,

1.) Sì, StackExchange dovrebbe costringere tutti coloro che votano verso il basso a scrivere una spiegazione. (Non è stato il mio downvote) 2.) Non è necessario utilizzare Eclipse per risolvere questo problema. 3.) Vedi la mia risposta qui.
Elmue

Elmue, 1) grazie per essere d'accordo :-). 2) Sono d'accordo. La prima parte della risposta è come risolvere questo problema modificando la piattaforma txt in modo che funzioni nell'IDE di Arduino. La tua risposta è più dettagliata su come risolvere questo problema. Non è necessario avere eclissi o IDE migliore per questo. La migliore soluzione ide viene menzionata perché un ide Arduino deve analizzare il boards.txt, quindi probabilmente ha queste informazioni da qualche parte e ha la possibilità di lavorare senza la necessità di modificare platform.txt. Mentre conosco molto bene il plug-in eclipse di arduino, do un esempio su come farlo con questo strumento. 3) Vedi la mia modifica
jantje,

Eclise funziona anche con Teensy? Quali altri vantaggi ha Exclipse?
Elmue

Sì, teensy è supportato dal plug-in eclipse di arduino ma dovrai modificare platform.txt (dovrebbe essere riparato in teensyduino 1.28)
jantje

0

I nomi esatti nel menu provengono dal file boards.txt nell'IDE di Arduino (Arduino \ hardware \ arduino \ avr \ boards.txt). Penso che dovresti analizzare il file da solo e trovare lì la scheda rilevata.


Analizza il file ?? E come faccio a sapere quale è selezionato nel menu?
Elmue,

0

Ho fatto una domanda correlata qualche tempo fa.

Esiste un file * .h interno che viene creato dall'IDE e contiene il tipo di scheda selezionata. L'elenco delle possibili opzioni è riportato nella domanda collegata, ma solo per le schede AVR. Credo che l'elenco non AVR sia molto più breve.

Si tratta semplicemente di aggiungere alcune istruzioni condizionali per inviare al PC le informazioni corrette. Un semplice esempio:

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

Se è necessario fare riferimento al tipo di scheda più di una volta nello schizzo, utilizzare il seguente formato:

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

Quest'ultimo è molto più ordinato, anche se ne hai bisogno solo __BOARD_TYPEuna volta, poiché rimuove il #ifdefpezzo ingombrante dalle tue funzioni.

Dovrai, ovviamente, scriverne una per ogni scheda che prevedi possa avere il tuo utente finale e dovrai eventualmente aggiornare questo elenco man mano che compaiono nuovi modelli.


Grazie per la tua risposta. Mi ha aiutato molto. (Vedi la mia risposta qui) Ma c'è un errore nel tuo codice. Invece di AVR_UNO deve essere ARDUINO_AVR_UNO.
Elmue

Potresti voler rimuovere i punti e virgola alla fine di #define; non sono dichiarazioni C e non hanno bisogno di separatori; infatti i separatori verranno inseriti dove vengono utilizzate le macro, collegamento all'interno delle parentesi della funzione println (). (Se i punti e virgola vengono rimossi, questo commento non avrà senso per i lettori successivi).
Zeph,

0

La risposta originale non è aggiornata poiché sono state aggiunte nuove schede. Il test di base è corretto, ma non è chiaro da dove provenga l'elenco delle schede.

Se trovi il boards.txtfile e lo guardi (ad es. ~\Library\Arduino\hardware\arduino\avr\boards.txtSu un Mac), ogni scheda avrà una voce lungo le linee di <BOARD>.build.board=<NAME>, quindi per esempio, MKR1000 avrebbe una linea:

mkr1000.build.board=SAMD_MKR1000

Il #define corrispondente può essere generato anteponendo il <NAME>al ARDUINO_quindi in questo esempio, il seguente codice genererà un errore per una scheda MKR1000 ...

#if defined(ARDUINO_SAMD_MKR1000) #error


Questa risposta è solo bla bla. Perché non pubblichi semplicemente un elenco completo di tutte le nuove schede con tutte le definizioni?
Elmue,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.