Hi Arduino community,
I have a question that I'm hoping someone can help me out with. You see I have two different sketches, each of which work fine... but are geared specifically for different types of boards. The first is for the Uno or all other clones (basically any board that has the same number of pins, ie. Lillypad, Duemilanove, etc.) The second is a sketch for the Mega (since this has a completely different pin setup. What I would like to do is to combine these two sketches into a single sketch and have some sort of function that checks which board type is being used during the upload process... an only load portions of the combined sketch that are appropriate for that type of board. Does that make sense? I could imagine some sort of #ifdef function that could be used if the board that was being used was an Uno, or Mega, and only upload those portions of the sketch. So, my question is... is there a way to determine which board is being used upon upload? I know the IDE reports the last selected board at the bottom of the window... so, is this being stored somewhere that I could access? Or am I going about this the wrong way. Any help would be greatly appreciated.
Cheers,
Andy
Does that make sense?
Yes, it does.
I could imagine some sort of #ifdef function that could be used if the board that was being used was an Uno, or Mega, and only upload those portions of the sketch.
Exactly. Look at pins_arduino.h for an example.
So, my question is... is there a way to determine which board is being used upon upload? I know the IDE reports the last selected board at the bottom of the window... so, is this being stored somewhere that I could access?
The IDE knows what board is selected. The compile process passes the board type to the compiler by using #define. You can test whether the #define for the Mega (both 1280 and 2560) exists, or not.
Hi Paul,
I'm sorry for getting back to this late. I found the pins_arduino.h header file, but I'm having a little trouble figuring out how to actually determine if the #define has been set for the Mega or not. Would it be possible to setup a really basic example (just a bare minimum sketch) with the proper code in the setup() function that determines which board type is being used. Actually, I also have a follow-up. I'm also trying to add support for the Leonardo, and I see it also has it's own pins_arduino.h file. Is there an easy way to determine between standard, Mega, and Leonardo boards? Thanks for the help.
-Andy
I think this is what you are looking for
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
//Code in here will only be compiled if an Arduino Mega is used.
#endif
Similarly, you can do this
#if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__)
//Code in here will only be compiled if an Arduino Uno (or older) is used.
#endif
And this:
#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega16U4__)
//Code in here will only be compiled if an Arduino Leonardo is used.
#endif
Thanks so much!
This is awesome! But this is gonna work if the board is another one that uses the same micro controller?
How could I determine if the board is actually an Arduino?
How could I determine if the board is actually an Arduino?
Versus what? There isn't a way to determine if the code is being compiled for use on an AtMega328 that is being used on an official Arduino board vs being compiled for an AtMega328 being used on another kind of board.
Also, functionally it makes no difference at all what dev board you have if they have the same microcontroller, the code will compile the same. The only potential difference is the pin mappings, but that is why Arduino Pin Numbers tend to be used, which are defined in the pins_arduino.h file for an associated dev board.
Can someone tell me where these #defines are actually set ?
Looking in boards.txt I can see things like this
mega.build.board=AVR_MEGA2560
does this get converted to
#define AVR_MEGA2560 by the IDE
I need to know because I'm trying to get the LeafLabs Maple stuff working a bit better on Arduino 1.5.x (most of the work for this has been done by @bobc) - however I can't see any definitions in the boards.txt for the maple devices that allow the sketches to know what platform they are running on
i.e perhaps boards.txt
DEVICE.build.board = xxxx
has been added since Leaflabs did their original work back in 2012 or before ?
Thanks
http://www.nongnu.org/avr-libc/user-manual/using_tools.html
From what I can make out from that, your board type select sets an option on the command line of the compile:
-mmcu=atmega328p
That gets converted by avr-g++ to an appropriate define, eg.
#define __AVR_ATmega328P__ 1
That is what you can test for in your code.
The "mcu" option is defined in the boards.txt file, eg.
uno.build.mcu=atmega328p
So, you select Uno from the Boards menu, it sends "-mmcu=atmega368p" to the compiler, the compiler does a table lookup, and defines "AVR_ATmega328P" to be 1 for you.
See http://www.gammon.com.au/forum/?id=12153#info6 for how to find what your current defines are.
Thanks Nick,
I have
maple_STM32.build.mcu=cortex-m3
I also see it passes in -D from the build.board setting
I think I may post to the Due thread, because my general issue is attempting to use libraries which use things that are only applicable to the AVR series (not SAM or my STM32), specificly progmem stuff and the progmem library
BTW.
I did try to use the compiler switch you posted, but I didnt see any #define statements, it just seemed to be the output after the preprocessor
I'm not using the AVR compiler I'm using the ARM one, so perhaps things are different with that version (though I don't see why they would be)
Really? It worked for me using IDE 1.5.8 set up for a Due:
/home/nick/Development/arduino-1.5.8/hardware/tools/gcc-arm-none-eabi-4.8.3-2014q1/bin/arm-none-eabi-g++ -c -g -Os -w -ffunction-sections -fdata-sections -nostdlib -fno-threadsafe-statics --param max-inline-insns-single=500 -fno-rtti -fno-exceptions -Dprintf=iprintf -mcpu=cortex-m3 -DF_CPU=84000000L -DARDUINO=158 -DARDUINO_SAM_DUE -DARDUINO_ARCH_SAM -D__SAM3X8E__ -mthumb -DUSB_VID=0x2341 -DUSB_PID=0x003e -DUSBCON -DUSB_MANUFACTURER="Unknown" -DUSB_PRODUCT="Arduino Due" -I/home/nick/Development/arduino-1.5.8/hardware/arduino/sam/system/libsam -I/home/nick/Development/arduino-1.5.8/hardware/arduino/sam/system/CMSIS/CMSIS/Include/ -I/home/nick/Development/arduino-1.5.8/hardware/arduino/sam/system/CMSIS/Device/ATMEL/ -I/home/nick/Development/arduino-1.5.8/hardware/arduino/sam/cores/arduino -I/home/nick/Development/arduino-1.5.8/hardware/arduino/sam/variants/arduino_due_x /tmp/build3865434089207142493.tmp/sketch_oct29a.cpp -dM -E > nick.txt
I attach my results as the -mcpu is the same as what you had (cortex-m3).
I'm surprised you didn't see any defines. I see about 11000+ of them.
nick.txt (476 KB)
I'll give it another go, perhaps I typed something wrong
OK. Managed to get it to work,
I'd used lowercase m on -dM
(doh)
But I cant really see anything in it like the mpu which is defined as cortex-m3 and nothing about the board either really
op.txt (90.2 KB)
I'm not sure exactly what you should look for. I found this in your file:
#define _BOARD_MAPLE_MINI_H_
...
#define BOARD_maple_mini 1
...
#define ARDUINO_ARCH_MAPLE 1
...
#define ARDUINO_MAPLE_MAPLE_STM32 1
Thanks Nick,
I'll take a look though my boards.txt and see what correlation there is
Cheers
Roger
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 GitHub - backupbrain/ArduinoBoardManager: Arduino library to determine the Arduino models and features as well as the SDK version.
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.
Seems neat. I think you should pick a different class name than "Arduino", though... Some of the variable names make me nervous about collisions as well.
westfw:
Seems neat. I think you should pick a different class name than "Arduino", though... Some of the variable names make me nervous about collisions as well.
I change the name to ArduinoBoardManager, updated in GitHub. Thank you for the suggestion.