14

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?

6
  • 2
    If you're using the arduino IDE to build the firmware, there's no provision to pass a project-level #define to the compiler, aside from F_CPU ARDUINO and AVR_whatever. You may need to grauate to using a makefile to build, instead of arduinio IDE. Check the arduino.SE site, Nick and Ignatio have some good examples. – MarkU Feb 26 '16 at 23:01
  • I cannot find anything interesting on Arduino.SE. (Is that swedish?) – Elmue Feb 26 '16 at 23:39
  • @Elmue arduino.StackExchange.com is Arduino SE. – Avamander Feb 26 '16 at 23:42
  • Ahhhh. OK. But arduino.se exists! – Elmue Feb 26 '16 at 23:59
  • By “I want to display on the PC which board is currently connected” do you mean to display it when a compiled and uploaded sketch runs, or display it while a sketch is being compiled, or while the IDE is just sitting there with a particular board attached? (In the latter two cases, board selection shows up in lowest line of the 1.6.3 IDE, but if you have an older or different IDE maybe not.) (If first case applies, do you want it to appear in the serial monitor?) – James Waldby - jwpat7 Feb 27 '16 at 7:58
18

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"
    #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

6
  • another thing. instead of using "return "?";" when you don't know use #pragma warning board name is unknown – jantje Mar 1 '16 at 12:36
  • 1.) I have replaced the "?" with an #error. 2.) I don't think that the strings are really a problem. You did understand that only ONE string will be compiled at the end? See my update that explains this above. The longest string is 11 bytes. If you need to optimize your code so much that you care about 11 bytes, I recommend to define an enum and return that instead of a string. Then your function will return one byte instead of 11. – Elmue Mar 1 '16 at 22:00
  • 3.) And what concerns the maintainability: It is sad that I have to write such a function. This should be already part of the header files that are installed with the compiler and should be maintained by the developers and updated with every new version. – Elmue Mar 1 '16 at 22:00
  • 2)I made a mistake when writing the remark on the size. I made a remark on that 5 hours ago. Sorry for that. 3)The maintainability is a problem. I have written very similar code in the past. I'm sure many others have as well. It is the maintainability why I prefer the "better IDE solution". I'm pretty sure all "better IDE's" will have similar solution as the one I mentioned in my answer. See it as a complement: You are outgrowing the Arduino IDE. – jantje Mar 1 '16 at 23:08
  • If you wrote a wrong comment, the best would be to delete it. – Elmue Mar 2 '16 at 17:40
2

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.

6
  • Would the downvoter or anyone else please be so kind as to specify why this is answer needs downvoting? – jantje Feb 28 '16 at 12:24
  • 1.) Yes, StackExchange should force everybody who votes down to write an explanation. (It was not my downvote) 2.) There is no need to use Eclipse to solve this problem. 3.) See my answer here. – Elmue Mar 1 '16 at 5:35
  • Elmue, 1) thanks for agreeing :-). 2) I agree. The first part of the answer is how you can fix this modifying the platform txt so it works in the Arduino IDE. Your answer goes in more detail on how to fix this.No need to have eclipse or any better IDE for that. The better ide solution is mentioned because a Arduino ide needs to parse the boards.txt so it probably has this info somewhere and has the possibility to work without need for modifying the platform.txt. As I happen to know the arduino eclipse plugin very well I give an example on how to do this with this tool. 3)See my edit – jantje Mar 1 '16 at 12:25
  • Does Eclise also work with Teensy? What other advantages has Exclipse? – Elmue Mar 2 '16 at 17:39
  • Yes teensy is supported by the arduino eclipse plugin but you'll have to mod the platform.txt (should be fixed in teensyduino 1.28) – jantje Mar 2 '16 at 18:27
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.

1
  • Parse the file ?? And how do I know which one is selecetd in the menu? – Elmue Feb 27 '16 at 0:45
0

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.

2
  • Thanks for your answer. It helped me lot. (See my answer here) But there is an error in your code. Instead of AVR_UNO it must be ARDUINO_AVR_UNO. – Elmue Mar 1 '16 at 5:31
  • You might want to remove the semicolons at the end of your #defines; they are not C statements and do not need separators; in fact the separators will be inserted where the macros is used, link inside the parens of the println() function. (If the semicolons are removed, this comment won't make sense to later readers). – Zeph Mar 15 '16 at 8:44
0

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
  • This answer is just bla bla. Why don't you simply post a complete list of all new boards with all defines? – Elmue Oct 17 '18 at 17:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.