Arduino: Cómo obtener el código del tipo de placa

13

Quiero escribir un boceto que se pueda compilar en diferentes tableros Arduino. Quiero mostrar en la PC qué placa está conectada actualmente.

Esto significa que el usuario conecta la PC a través del cable USB a la placa Arduino / Teensy en la que se ejecuta mi boceto y mi boceto le dice a la PC a través de la serie qué placa está conectada. En la PC ejecuta mi aplicación C # que recibe estos datos y los muestra.

Por lo tanto, necesito el tablero que se seleccionó cuando se compiló el boceto:

Selector de placa Arduino

Encontré el código en https://github.com/backupbrain/ArduinoBoardManager pero no da resultados correctos (aparte del hecho de que faltan varias placas).

Aquí un fragmento del código:

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

Entonces, este código da el mismo resultado (BOARD = 0x04 = Micro) para Yun 16MHz, Micro, Leonardo y Esplora.

¿Hay alguna forma de obtener en mi código C exactamente la cadena que el usuario ha seleccionado en el menú del compilador Arduino?

Elmue
fuente
2
Si está utilizando el IDE de Arduino para construir el firmware, no hay ninguna disposición para pasar un #define de nivel de proyecto al compilador, aparte de F_CPU ARDUINO y AVR_whatever . Es posible que deba graduarse para usar un archivo MAKE para compilar, en lugar de arduinio IDE. Visite el sitio arduino.SE, Nick e Ignatio tienen algunos buenos ejemplos.
MarkU
No puedo encontrar nada interesante en Arduino.SE. (¿Es sueco?)
Elmue
@Elmue arduino.StackExchange.com es Arduino SE.
Avamander
Ahhhh OKAY. ¡Pero arduino.se existe!
Elmue
Por "Quiero mostrar en la PC qué placa está conectada actualmente", quiere decir que se muestra cuando se ejecuta un boceto compilado y cargado, o se muestra mientras se está compilando un boceto, o mientras el IDE está sentado allí con un determinado junta adjunta? (En los últimos dos casos, la selección de la placa aparece en la línea más baja del IDE 1.6.3, pero si tiene un IDE anterior o diferente, tal vez no.) (Si se aplica el primer caso, ¿desea que aparezca en el monitor en serie? ?)
James Waldby - jwpat7

Respuestas:

17

¡Gracias a la ayuda de Charlie Hanson y Jantje encontré la solución universal!

Debido a que es una pena que cada programador de Arduino tenga que pasar por el mismo problema para descubrir cómo obtener el nombre de la placa, ofreceré mi código al público para que todos puedan copiarlo y pegarlo.

Aquí está:

#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

Incluso puede poner este código en un nuevo archivo de encabezado e incluirlo en su proyecto.

PD Si desea conocer adicionalmente a la placa también el modelo de CPU, busque el archivo avr_cpunames.h

Elmue
fuente
otra cosa. en lugar de usar "return"? ";" cuando no sabes usar el nombre del tablero de advertencia #pragma es desconocido
jantje
1.) He reemplazado el "?" con un #error. 2.) No creo que las cuerdas sean realmente un problema. ¿Entendiste que solo UNA cadena se compilará al final? Vea mi actualización que explica esto arriba. La cadena más larga es de 11 bytes. Si necesita optimizar su código tanto que le interesan unos 11 bytes, le recomiendo definir una enumeración y devolverla en lugar de una cadena. Entonces su función devolverá un byte en lugar de 11.
Elmue
3.) Y lo que concierne a la mantenibilidad: Es triste que tenga que escribir tal función. Esto ya debería ser parte de los archivos de encabezado que se instalan con el compilador y los desarrolladores deberían mantenerlo y actualizarlo con cada nueva versión.
Elmue
2) Cometí un error al escribir el comentario sobre el tamaño. Hice un comentario sobre eso hace 5 horas. Lo siento por eso. 3) La mantenibilidad es un problema. He escrito un código muy similar en el pasado. Estoy seguro de que muchos otros también. Es la mantenibilidad por la que prefiero la "mejor solución IDE". Estoy bastante seguro de que todos los "mejores IDE" tendrán una solución similar a la que mencioné en mi respuesta. Véalo como un complemento: está superando el IDE de Arduino.
jantje
Si escribió un comentario incorrecto, lo mejor sería eliminarlo.
Elmue
2

Tenga en cuenta que este es un mod de Windows, algo similar debe existir en Linux.

El primero es rápido y fácil. Simplemente modifique los archivos platform.txt que está utilizando como se describe a continuación. El inconveniente de esto es que necesitará cambiar los archivos de platform.txt con cada versión.

agregue -DBOARD = \ "$ {build.board} \" a la receta. Esto permitirá

   const char boardName[]=BOARD;

Lo que te da la cadena "ARDUINO_AVR_LEONARDO" (para el leonardo) en boardName.

La segunda forma es cambiar a un IDE mejor (como ya lo propusieron otros). Como creador del complemento arduino eclipse, recomendaría usar el complemento arduino eclipse. En el complemento arduino eclipse, haga lo siguiente: Haga clic derecho en el proyecto-> propiedades-> arduino-> pestaña "opciones de compilación" poner

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

en el campo anexar a C y C ++.

Esto hará que el código anterior compile

Adendum

No sabía que querías el "buen nombre". No estoy seguro de que esto se pueda solucionar en platform.txt en arduino IDE. En el plugin Arduino Eclipse, cambie la corrección anterior en

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

para obtener el bonito nombre (para el leonardo "Arduino Leonardo") en la tabla de definición.

jantje
fuente
¿El votante o cualquier otra persona sería tan amable de especificar por qué esta respuesta necesita voto negativo?
jantje
1.) Sí, StackExchange debería obligar a todos los que voten a favor a escribir una explicación. (No fue mi voto negativo) 2.) No hay necesidad de usar Eclipse para resolver este problema. 3.) Vea mi respuesta aquí.
Elmue
Elmue, 1) gracias por aceptar :-). 2) Estoy de acuerdo. La primera parte de la respuesta es cómo puede solucionar esto modificando la plataforma txt para que funcione en el IDE de Arduino. Su respuesta va en más detalle sobre cómo solucionar esto. No es necesario tener eclipse o cualquier IDE mejor para eso. Se menciona la mejor solución ide porque un ide Arduino necesita analizar los tables.txt, por lo que probablemente tenga esta información en algún lugar y tenga la posibilidad de funcionar sin necesidad de modificar la plataforma.txt. Como conozco muy bien el plugin de eclipse de arduino, doy un ejemplo de cómo hacer esto con esta herramienta. 3) Ver mi edición
jantje
¿Eclise también trabaja con Teensy? ¿Qué otras ventajas tiene Exclipse?
Elmue
Sí, los adolescentes son compatibles con el plugin Arduino Eclipse, pero tendrás que modificar la plataforma.txt (debe corregirse en teensyduino 1.28)
jantje
0

Los nombres exactos en el menú provienen del archivo boards.txt en su IDE Arduino (Arduino \ hardware \ arduino \ avr \ boards.txt). Creo que tendría que analizar el archivo usted mismo y encontrar la placa detectada allí.

PW
fuente
Analizar el archivo? ¿Y cómo sé cuál es selecetd en el menú?
Elmue
0

Hice una pregunta relacionada hace un tiempo.

Existe un archivo * .h interno creado por el IDE y que contiene el tipo de placa que se ha seleccionado. La lista de opciones posibles se proporciona en la pregunta vinculada, pero solo para placas AVR. Creo que la lista no AVR es mucho más corta.

Es simplemente una cuestión de agregar algunas declaraciones condicionales para enviar a la PC la información correcta. Un simple ejemplo:

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

Si necesita referirse al tipo de tablero más de una vez en el boceto, use el siguiente 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);

Este último es mucho más ordenado, incluso si solo lo necesita __BOARD_TYPEuna vez, ya que elimina la #ifdefparte engorrosa de sus funciones.

Por supuesto, tendrá que escribir uno para cada tablero que espera que su usuario final pueda tener, y posiblemente necesite actualizar esta lista a medida que aparezcan nuevos modelos.

CharlieHanson
fuente
Gracias por tu respuesta. Me ayudó mucho. (Vea mi respuesta aquí) Pero hay un error en su código. En lugar de AVR_UNO, debe ser ARDUINO_AVR_UNO.
Elmue
Es posible que desee eliminar los puntos y comas al final de sus #defines; no son declaraciones C y no necesitan separadores; de hecho, los separadores se insertarán donde se usan las macros, enlace dentro de los parentes de la función println (). (Si se eliminan los puntos y comas, este comentario no tendrá sentido para los lectores posteriores).
Zeph
0

La respuesta original está desactualizada ya que se han agregado nuevos tableros. La prueba básica es correcta, pero no está claro de dónde proviene la lista de tablas.

Si localiza el boards.txtarchivo y lo revisa (por ejemplo, ~\Library\Arduino\hardware\arduino\avr\boards.txten una Mac), cada placa tendrá una entrada en la misma línea que <BOARD>.build.board=<NAME>, por ejemplo, el MKR1000 tendría una línea:

mkr1000.build.board=SAMD_MKR1000

El #define correspondiente se puede generar con el prefijo <NAME>con ARDUINO_lo que en este ejemplo, el siguiente código de error para una junta MKR1000 ...

#if defined(ARDUINO_SAMD_MKR1000) #error

Jason Crocker
fuente
Esta respuesta es solo bla bla. ¿Por qué no simplemente publicas una lista completa de todos los nuevos tableros con todas las definiciones?
Elmue