Skip to content


Maxim Prokhorov edited this page Dec 8, 2022 · 37 revisions

Change log

Getting started

Supported hardware and options





More around ESPurna

Clone this wiki locally

Build & Flash the Firmware with PlatformIO


  • 🔴 Python 3.7 is the minimum supported version!
  • 🔴 PlatformIO installer might not always use the system Python!

Installing git

git is used to manage our library dependencies

Installing PlatformIO

Refer to the latest platformio-core documentation and follow the instructions for your platform

By default, PlatformIO does not add pio / platformio command to the system PATH variable (but, it is a recommended option for Windows installations)

Otherwise, it is possible to use Python's venv 'activate' / 'activate.bat' / 'activate.ps1' scripts (depends on the platform) to allow the use of python and pio commands in the shell

Common location of the platformio installation is ~/.platformio/penv/Scripts/


For example, to build a binary for Sonoff Basic:

$ pio run -e sonoff-basic

The resulting .bin file can be found at .pio/build/sonoff-basic/firmware.bin

Or, using special generic environment:

$ env ESPURNA_FLAGS="-DITEAD_SONOFF_BASIC" pio run -e esp8266-1m-base

(including any other flags / environment variables, depending on the board you are working with)

For Window's cmd.exe, syntax is a bit different:

> cmd /V /C "set ESPURNA_FLAGS=-DITEAD_SONOFF_BASIC && pio run -e esp8266-1m-base"

Flash your board

Notice This describes serial upload, see OTA page for information about wireless upload and PlatformIO documentation

Wire your board (check the Hardware page) and flash the firmware (with upload):

$ env ESPURNA_FLAGS="-DITEAD_SONOFF_BASIC" pio run -e esp8266-1m-base -t upload

macOS Big Sur

PlatformIO's compatibility issues are fixed since espressif8266 version 2.6.3:

platform =
    platformio/espressif8266 @ >=2.6.3

As an alternative, it is possible to override an older version of the tool-esptoolpy:

platform_packages =
    platformio/tool-esptoolpy @ ~1.30000.0

Or, install esptool>=3.0 via pip and manually call the updated version.

For more information, see


PlatformIO will take care of the library dependencies. The first time you run the build process it will fetch and install all the libraries required by ESPurna in the specified versions.

For the most up-to-date list, please see code/platformio.ini lib_deps = ... in the [common] section.

Core libraries:

Optional libraries, depending on specific ..._SUPPORT flags:

Button management, WiFi control and settings storage inspired by:

At last, legacy libraries for Core 2.3.0 (deprecated, only matters when building using platform = espressif8266@1.5.0):

Customize build settings

platformio.ini format

Please refer to the official PlatformIO documentation for platformio.ini:

ESPurna's platformio.ini has the following structure:

  • code/espurna/ is set as source code root directory
  • code/platformio_override.ini can be used to override existing or create new sections.
  • [common] sections is used to set some variables that later will be used as ${common.variable}
  • [env] section implicitly provides keys for every environment, so we don't have to repeat ourselves
  • [env:...-base] specifies framework (arduino, only available option), board (upload settings, variant build flags), ldscript (memory regions, flash constants and flash size), platform (PlatformIO build system version) and platform_packages (in case we need to change build tools versions)
  • [env:named] extends from the -base environment and sets build_src_flags with our project-specific flags. Common way to specify hardware is to have #if defined(HARDWARE_FLAG) (see code/espurna/config/hardware.h') and add -DHARDWARE_FLAGwhen you need to enable multiple#define` options.

It is important to note that in case of repeating keys:

extends = esp8266-1m-base

extends = env:example
build_src_flags = -DANOTHER_HARDWARE

When building env:override, -DUSE_CUSTOM_H will not be added to the compiler build flags. To append to the existing variable you would need to explicitly specify the key that you want it to use. For example:

extends = esp8266-1m-base

extends = esp8266-1m-base
build_src_flags = ${env:example.build_src_flags} -DSOME_OTHER_FLAG=1

build_flags and build_src_flags

  • build_src_flags is used only by our project's files
  • build_flags sets command line options for project's files, Core and libraries

For example, our [env] sections contains the following flags:



Any environment that wants to modify build flags needs to explicitly specify the existing build_flags variable as build_flags = ${common.build_flags} -DLIBRARY_CUSTOM_FLAG=12345 -DPIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK221.

Custom environment

If you want to modify the stock configuration but you don't want to touch the repo files you can create a brand new environment in the code/platformio_override.ini:

extends = esp8266-1m-base


Add -DUSE_CUSTOM_H to build_src_flags and create code/espurna/config/custom.h. For example:

#define WEB_EMBEDDED 0
#define NTP_SERVER              ""
#define MQTT_TOPIC              "my/topic"

(see code/espurna/config/general.h and code/espurna/config/sensor.h for available flags)

It is also possible to add flag through command line by setting OS environment variables PLATFORMIO_BUILD_SRC_FLAGS and PLATFORMIO_BUILD_FLAGS, for build_src_flags and build_flags respectively:


We also provide a ESPURNA_FLAGS OS environment variable that is used by the OTA:


ESPURNA_FLAGS is interchangeable with the PLATFORMIO_BUILD_SRC_FLAGS and both will append flags into the existing build_src_flags contents.

Advanced options

-DDISABLE_POSTMORTEM_STACKDUMP (build_flags / build_src_flags option)

Used to disable serial print of postmortem stack dump after a board crashes. This functionality is part of the Arduino Core, so we build a dummy file with an empty printf function and replace the reference to printf in the resulting .o file. Kind of a hack, this should probably be configured in the Core itself. But, we need to write a patch for that.

ESPURNA_BUILD_SINGLE_SOURCE (OS environment variable)

Combine every .cpp into a single file to significantly speed up compilation process when parallel build cannot be used. This will also result in a reduced .bin size (~7KB smaller). ATM this option is only used in CI to build release and test .bin files


Specify where to store files copied with pio run -e $env -t build-and-copy and how to name them


Configures version string, both for the resulting .bin name and string inside of the app. Ver

By default, version string looks like this: 1.15.0-dev.git73e3bdac. It can be completely changed, or just some parts of it

  • ESPURNA_BUILD_FULL_VERSION replaces the full string; {FULL_VERSION}
  • ESPURNA_BUILD_VERSION replaces the leftmost part; {VERSION}-git73e3bdac
  • ESPURNA_BUILD_REVISION replaces the hash string at the end; 1.15.0-dev.git{REVISION} (since we use git by default)
  • ESPURNA_BUILD_VERSION_SUFFIX adds an extra (semantic version compatible) string at the end; 1.15.0-dev.git73e3bdac+{SUFFIX}


  • ESPURNA_IP flags upload type as OTA (when using -t upload) and adds --ip=$ESPURNA_IP to the arguments list
  • ESPURNA_AUTH adds --auth=$ESPURNA_AUTH to the arguments list (depends on ESPURNA_IP)
  • ESPURNA_FLAGS supports adding -D... to the project build flags (or, modify build_src_flags for the same result. however, ESPURNA_FLAGS could be used to short-circuit PlatformIO configuration change detection which will prevent rebuilding everything when flags change)
  • (legacy) ESPURNA_BOARD updates build flags with -D$ESPURNA_BOARD. This was used previously as a platformio.ini substitution, but is no longer used and will be removed in the future.

1 See MQTT configuration
2 See I2C configuration
3 See Sensors configuration
4 See Lights configuration
5 See RPN Rules configuration
6 See RFBridge configuration