16

I want to write a sketch that can be compiled on different Arduino boards. I want to display on the PC which board is currently connected.

This means that the user connects the PC via USB cable to the Arduino/Teensy board in which runs my sketch and my sketch tells the PC via Serial which board is connected. On the PC runs my C# application which receives this data and displays it.

Therefore I need the board that has been selected when the sketch has been compiled:

Arduino Board selector

I found the code on https://github.com/backupbrain/ArduinoBoardManager but it does not give correct results (apart from the fact that several boards are missing).

Here a snippet from the 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(.....

So this code gives the same result (BOARD = 0x04 = Micro) for Yun 16MHz, Micro, Leonardo y Esplora.

Is there any way to get in my C code exactly the string that the user has selecetd in the menu of the Arduino compiler?

Elmue
  • 481
  • 1
  • 3
  • 10

6 Answers6

21

Thanks to the help of Charlie Hanson and jantje I found the universal solution!

Because it is a pity that every Arduino programmer has to go through the same pain to figure out how to get the board name, I will offer my code to the public so everybody can just copy and paste it.

Here it is:

#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"
#elif defined(__IMXRT1062__) && defined(ARDUINO_TEENSY40)
    #define BOARD "Teensy 4.0"
#elif defined(__IMXRT1062__) && defined(ARDUINO_TEENSY41)
    #define BOARD "Teensy 4.1"
#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

You can even put this code into a new header file and #include it into your project.

P.D. If you want to know additionaly to the board also the CPU model, search for the file avr_cpunames.h

Elmue
  • 481
  • 1
  • 3
  • 10
4

note this is a windows mod something similar must exist on linux.

The first is quick and easy. Simply modify the platform.txt files you are using as described nelow. The draw back of this is that you will need to change platform.txt files with each release.

add -DBOARD=\"${build.board}\" to the recipe. This will allow for

   const char boardName[]=BOARD;

Which gives you the string "ARDUINO_AVR_LEONARDO" (for the leonardo) in boardName.

The second way is to switch to a better IDE (like already proposed by others). As the creator of the arduino eclipse plugin I would advice to use the arduino eclipse plugin. In the arduino eclipse plugin you do this as follows: Right click on the project->properties->arduino->tab "compile options" put

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

in the append to C and C++ field.

This will make the code above to compile

Adendum

I wasn't aware you wanted the "nice name". I'm not sure this can be fixed in the platform.txt in arduino IDE. In the arduino eclipse plugin change the fixe above in

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

to get the nice name (for the leonardo "Arduino Leonardo") in the define Board.

jantje
  • 1,392
  • 1
  • 8
  • 16
2

The original answer is out of date as new boards have been added. The basic test is correct, but it's not clear where the list of boards come from.

If you locate the boards.txt file and look through it (eg. ~\Library\Arduino\hardware\arduino\avr\boards.txt on a Mac), each board will have an entry along the lines of <BOARD>.build.board=<NAME>, so for example, the MKR1000 would have a line:

mkr1000.build.board=SAMD_MKR1000

The corresponding #define can be generated by prefixing the <NAME> with ARDUINO_ so in this example, the following code will error for an MKR1000 board...

#if defined(ARDUINO_SAMD_MKR1000) #error

1

I asked a related question a while ago.

An internal *.h file exists which is created by the IDE, and holds in it the type of board that has been selected. The list of possible options is given in the linked question, but only for AVR boards. I believe the non-AVR list is much shorter.

It is simply a matter of adding some conditional statements to send the PC the correct information. A simple example:

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

If you need to refer to the board type more than once in the sketch, use the following 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);

The latter is much tidier, even if you only need __BOARD_TYPE once, as it removes the cumbersome #ifdef chunk from your functions.

You will, of course, have to write one for each board that you expect your end-user could have, and you will possibly need to update this list as new models appear.

CharlieHanson
  • 1,430
  • 1
  • 11
  • 25
1

For Adafruit boards, specifically a Feather M4, the following worked for me.

#ifdef _VARIANT_FEATHER_M4_
serial.println("Feather M4");
#endif
Rodrigo
  • 11
  • 2
0

The exact names in the menu come from boards.txt file in your Arduino IDE (Arduino\hardware\arduino\avr\boards.txt). I think you would have to parse the file by yourself and find the detected board there.

P.W.
  • 317
  • 6
  • 15