Pregunta

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.

¿Fue útil?

Solución

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.

Otros consejos

I don't think that there is such a thing built into the arduino IDE, but you can always write your own makefile and define such a thing yourself.

http://pragprog.com/magazines/2011-04/advanced-arduino-hacking

If you scroll down to the hello world example, you will see an example makefile, with a BOARD make variable defined and with just a little extra makefile smarts you could invoke make like this:

make BOARD=UNO

or

make BOARD=NANO

to build the sketch for the different boards.

An easy way to do board sniffing is to use a library such as ArduinoManager. With this you can very easily get the board name and features https://github.com/backupbrain/ArduinoBoardManager

It uses the technique described above to reveal lots of information about almost every Arduino board, so it's great for making projects that might get deployed on a lot different environments.

Just download and include in your Arduino project.

#include "ArduinoBoardManager.h"

ArduinoBoardManager arduino = ArduinoBoardManager(); // required if you want to know the board name and specific features

void setup() {
  Serial.begin(9600);

  Serial.print("Board is compatible with Arduino ");
  Serial.println(arduino.BOARD_NAME);

  Serial.println("Speed/SRAM/Flash: ");
  Serial.print(ArduinoBoardManager::MAX_MHZ);
  Serial.println(ArduinoBoardManager::SRAM_SIZE);
  Serial.println(ArduinoBoardManager::FLASH_SIZE);

  // Board features (multiple serial ports on Mega, for example)
  if (arduino.featureExists(ArduinoBoardManager::FEATURE_MULTIPLE_SERIAL)) {
    Serial.println("Your board supports multiple serial connections");
  }

}

void loop() {
}

The resulting output on Arduino Uno is:

Board is compatible with Arduino UNO

Speed/SRAM/Flash: 
16000000
2048
33554432

The process for making this library (including example code) to determine an Arduino board model and version is described in detail on my blog.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top