Changing destination boards

I have an Arduino Uno that I use to irrigate my garden. I have a spare Arduino Micro that I use to develop and test my code before uploading to the Uno. Currently, I have to have two separate projects, one for developing on the Micro and one for uploading to the Uno. (The code I’m developing is compatible across the two platforms and is not very hardware-specific.) This has quickly become quite cumbersome and inefficient to switch between two projects in order to upload to two different platforms.

While remaining in the same project, can I simply change/specify the target board that I’m uploading to?

I have attempted to find an answer to this question. Perhaps it has been answered and I’m missing a few keywords here.

1 Like

You can just add both boards / environments in your platformio.ini. This is a built-in with PlatformIO. You then either set one or multiple default environments to produce / upload the firmware for one or multiple boards. See Redirecting....

Example platformio.ini:

; default environmen. Default to ProMicro 5V version.
[platformio]
env_default = promicro5v

[env:promicro5v]
platform = atmelavr
framework = arduino
board = sparkfun_promicro16

[env:promicro3v3]
platform = atmelavr
framework = arduino
board = sparkfun_promicro8

[env:uno]
platform = atmelavr
board = uno
framework = arduino

To compile for all boards at the same time, set env_default to promicro5v, promicro3v3, uno. Thus you will see that the firmware compiles on all platforms.

In the code itself, use #ifdef <board macro> to enable board-specific code for each target, e.g. #ifdef ARDUINO_AVR_PROMICRO16 et cetera.

If you want to upload to one specific board, either use the command line to select a specific environment, e.g. pio run -t upload -e uno or set the env_default to the one board environment you wish to upload for.

6 Likes

Wow, thank you! That is precisely what I’m looking for. Also, I never considered using macros for hardware-specific code; that definitely opens up some possibilities.

When you are checking to see if ARDUINO_AVR_PROMICRO16 is defined in your example, is ARDUINO_AVR_PROMICRO16 predefined by the env_default or are you including a #define ARDUINO_AVR_PROMICRO16 at compile time? (Having predefined values would be excellent because then it would be possible to upload for all boards simultaneously while the preprocessor divvies up the hardware specific code according to each compile environment.)

I just now read your link to the documentation. (It probably helps to read suggested links. My bad :flushed:)

Anyway, this seems very much related to my question: http://docs.platformio.org/en/latest/projectconf/section_env_build.html

If not predefined, would you define ARDUINO_AVR_PROMICRO16 using build flags? (Allowing you to set up environment-specific defines) If so, could you provide an example of a build flag for ARDUINO_AVR_PROMICRO16?

These flags are special because they are built in. Each board target (e.g. sparkfun_promicro16, uno etc) has its target JSON file here: platform-atmelavr/boards at develop · platformio/platform-atmelavr · GitHub

Each board file also defines at least one board-specific macro by which I can identify the board. E.g. sparkfun_promicro8.json:

{
  "build": {
    "core": "arduino",
    "extra_flags": "-DARDUINO_AVR_PROMICRO8",
    "f_cpu": "8000000L",
"hwids": [
..

So it has the ARDUINO_AVR_PROMICRO8 macro set. Similarly for the others.

But you are totally right, you can also put extra build flags into your platformio.ini and then use them in the firmware. E.g., in one environment

[env:uno]
platform = atmelavr
board = uno
framework = arduino
build_flags = -D BUILD_MY_FIRMWARE_FOR_UNO

Just put a different define in each environment and use it in the firmware, that also works.

@maxgerhardt, thank you for this information. This totally expands what I can do with the IDE and streamlines my workflow. :grin: :exploding_head:

1 Like