determine board type of Arduino

mpflaga picture mpflaga · Dec 13, 2012 · Viewed 10.9k times · Source

How can one determine the board type (e.g. Uno vs Nano) of an Arduino at time of compile? Not to be confused with determining the processor type. As I see examples of this e.g. #if defined(__AVR_ATmega32U4__) ...

I would like a way, similarly, to determine between flavors of Arduino's all using the same processor of ATmega328.

The IDE knows board. So is it possible to access it from some pre-compiler #IF

The Nano has different interrupts vs. the Uno. Hence knowing board type at compile can automate the pin assignments for public libraries.

Answer

jdr5ca picture jdr5ca · Dec 29, 2012

As you noted, you check off a board target in the development environment so the compiler might know the board. Unfortunately, the IDE does not tell the compiler this information directly. Only the processor type and frequency are passed down.

You can see what the IDE does to compile programs. In the preferences menu, turn on verbose output for compilation. Compile a sketch and you will see something like this:

C:\Apps\arduino-1.0-windows\arduino-1.0\hardware\tools\avr\bin\avr-g++ -c -g -Os -Wall -fno-exceptions -ffunction-sections -fdata-sections -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=100 -IC:\Apps\arduino-1.0-windows\arduino-1.0\hardware\arduino\cores\arduino -IC:\Apps\arduino-1.0-windows\arduino-1.0\hardware\arduino\variants\standard C:\Users\Jim\AppData\Local\Temp\build4664216036291565363.tmp\Blink.cpp -oC:\Users\Jim\AppData\Local\Temp\build4664216036291565363.tmp\Blink.cpp.o

The -D 's are how the Arduino environment passes defines to the preprocessor. You see that only the CPU speed and arduino version are passed in this way.

The IO pins are defined a different manner: The IDE includes one folder that contains a board specific header file.

This -I argument includes a folder onto the compiler's search path:

-IC:\Apps\arduino-1.0-windows\arduino-1.0\hardware\arduino\variants\standard

In that folder is a pins_arduino.h file that is appropriate for the board you selected. If you choose a different board, you will see this parameter change.

If you are willing to modify your IDE configuration, you can get what you ask for.

So to get what you want, you just need to get one #define directive. So here is how to

Step 1. Make your own board type. To make a new board type, see the boards.txt file located in this folder:

...\arduino-1.0\hardware\arduino

The line like this define the include folder (standard in this case):

uno.build.variant=standard

Copy an entire block, changing the name and the folder

myuno.name=My Arduino Uno
...
myuno.build.variant=myunoboard

With this change, when you select this board target, the myunoboard folder will be placed on the compiler path.

Step 2. Make you header that includes your define.

In the folder

...\arduino-1.0\hardware\arduino\variants\myunoboard

make a file pins_arduino.h. In that file

#include "..\standard\pins_arduino.h"
#define BOARD MY_UNO
// and/or this form
#define __BOARD_MY_UNO

Step 3. Repeat for more boards.

This will provide the ability to build your code for different board targets.

Having said this, I wouldn't really recommend this approach. If you are starting to think about creating code that runs across multiple targets, it may be time to move on from the Arduino IDE. If you were using an environment such as Eclipse, you have one project with any number of build configurations. Each build configuration can specify different preprocessor defines for the board target.