OTA: PlatformIO and ESP8266

As my IoT odyssey continues to unfold I blogged about building the ESP8266 tool chain and creating NodeMCU firmware manually, etc. A colleague of mine asked me about an open source ecosystem which does all this for you with only a few key strokes: PlatformIO. A small team from the Ukraine is creating quite a splash in the world of IoT and micro controllers (read: embedded platforms) by centralizing and automating the required libraries and tool chains. Needless to say I want to try this out for myself and see what this hype is all about!

PlatformIO is an open source ecosystem for IoT development, a cross-platform builder and the missing library manager for micro controllers all at the same time. Continuous and IDE integration. Arduino and ARM mbed compatible. -- PlatformIO

Lets put this perceived awesomeness to the test. As a new prototype this blog rebuilds the HCP integrated temperature sensor using this platform. In addition I want to extend the prototype with Over-the-Air ("OTA") capabilities to eliminate the dependency on the serial cable.

Install PlatformIO

PlatformIO is written in Python and a subsequent runtime environment must be available on our system. Validate whether your system has a version of Python 2.7 installed by issuing the following command: python --status. Result should look something like Python 2.7.xy. If this is not the case Python must be installed on the system, the steps to do so differ based upon operating system.

For Windows OS download Python and install. Once installed add the values C:\Python27 and C:\Python27\Scripts to the PATH system variable. Please follow these instructions to do so.

Linux OS requires the python package manager, validate its installation by entering pip in the terminal. For those not familiar, the pip command is a tool for installing and managing Python packages. If the tool is not available execute the following: sudo apt-get install python-pip. Once installed is completed, enter pip -V to validate successful installation. If a later pip version is available, upgrade using the following command pip install --upgrade pip.

Also ensure to have permission to access the serial port to access the ESP8266. In a terminal enter the command: sudo adduser xyz-user dialout. Replace xyz-user with your username.

Once all mandatory requirements are met its time to install the PlatformIO Core with CLI. Initiate the installation by executing the following command: pip install -U platformio. Validating if all went well by executing the command platformio --version or its alias pio --version. The result should return the latest version of the PlatformIO environment.

Setting up an IoT device

Now we have installed the PlatformIO Core with CLI its time to setup the first IOT device. Before we start I have created a dedicated location for my PlatformIO project in my user directory: ~/pio/test/. All commands in this upcoming section are executed from withing or referencing this directory location.

Initializing a new project

First step to setup and configure an IoT device is the generation of a firmware skeleton based on the board used. PlatformIO supports an ever expanding variety of boards, the command pio boards provides an overview of the boards currently supported. Alternatively PlatformIO's boards explorer can be leveraged to determine the correct board. This blog utilizes the Espressif 8266 (MCU: ESP8266) as IoT platform leveraging the Arduino/Simba board with board identifier (ID) nodemcuv2. Ensure to select the correct board before continuing.

The value PlatformIO brings to the IoT table is that it claims to provide pre-configured settings for the most IoT devices. It is intended as a one-stop shop for installing toolchains, writing build scripts or configuring uploading process. Lets put this to the test, issue the command: pio init --board nodemcuv2. The firmware skeleton should look like the screenshot below.

Building a project

With the project skeleton setup we need to build the firmware. For purposes of this blog - enabling OTA capabilities. OTA (Over the Air) updating is the process of loading the firmware to the ESP device using Wi-Fi connection rather that a serial port; truly 'cutting the cord'. I've leveraged an existing sketch which can be found on github: Arduino OTA. Simplest way is to download the 3 needed files into the PlatformIO skeleton:

curl -o ~/pio/test/src/main.cpp https://raw.githubusercontent.com/platformio/platformio-examples/develop/espressif/esp8266-arduino-ota/src/main.cpp  
curl -o ~/pio/test/lib/ArduinoOTA/ArduinoOTA.cpp https://raw.githubusercontent.com/platformio/platformio-examples/develop/espressif/esp8266-arduino-ota/lib/ArduinoOTA/ArduinoOTA.cpp  
curl -o ~/pio/test/lib/ArduinoOTA/ArduinoOTA.h https://raw.githubusercontent.com/platformio/platformio-examples/develop/espressif/esp8266-arduino-ota/lib/ArduinoOTA/ArduinoOTA.h  

Make sure the ArduinoOTA.cpp and ArduinoOTA.h files are copied into the directory /lib/ArduinoOTA/ otherwise the firmware will not correctly compile. Alternatively you can leverage the .ino file located here: BasicOTA and curl in src directory as main.ino.

Lets take a closer look at the main.cpp file to better understand what is being uploaded. First the Arduino setup function; here the wifi connection is established and several OTA specific functions are declared. Key routines defined are progress update onProgress, error handling onError and ready message Begin.

The OTA capability is enabled by the looping nature of the Arduino loop function itself. The OTA handle function checks whether a serial command to update the firmware is received and kicks off the OTA process accordingly. Custom code is added here as we would normally do for any Arduino sketch.

An few updates must be made in the main.cpp file's declarations to ensure the device can connect to the wireless network. Open the file in your favorite editor and find/update the following two lines:

const char* ssid = "YOUR NETWORK";  
const char* password = "YOUR PASSWORD";  

Also modify the line Serial.println("Ready"); by issuing a more descriptive message, i.e. Serial.println("Ready, no OTA!");

Next, run command: pio run initiating the process which builds all environments specified in the platformio.ini file - in this example only a NodeMCU environment will be build. Connect the ESP device using serial cable and execute pio run --target upload. At this point magic happens; PlatformIO detects the mandatory ESP8266 toolchain is not yet installed - assuming this is the first run. Better yet... it proposes and commences to do so.

Once the tool chain in installed it: 1) automatically builds the firmware, 2) detects the correct USB port, 3) connects to the ESP8266 device and 4) uploads firmware. Wow! This process made the value from PlatformIO clear in terms of standardization and simplification. Especially when you consider the number different environments and boards it supports. Good stuff.

Assuming the process ended successfully we can validate whether the OTA firmware was uploaded by issuing the command: pio device monitor -b 115200. After selecting the correct serial port; reset the ESP device and a message should appear that reads:

Updating firmware using OTA

With PLatformIO and the ArduinoOTA code in place its time to test this wireless firmware updating goodness. First, lets update the firmware by including a blinky example in the main.cpp file which turns the internal LED on/off. Include the following code snippets in the setup and loop routines subsequently:

setup

  // Duration of delay of led output
  #define DELAY 2500
  // initialize NodeMCU LED as an output.
  pinMode(LED_BUILTIN, OUTPUT);

loop

  // Set voltage level to HIGH - turn LED on
  digitalWrite(LED_BUILTIN, HIGH);
  delay(DELAY);
  // Set voltage level to LOW - turn LED off
  digitalWrite(LED_BUILTIN, LOW);
  delay(DELAY);

After having saved these updates its time to put OTA into action. Disconnect the ESP device from the computer and plug it into a wall socket using an USB charger of sorts. PlatformIO gives us a simple command that allows for directly targeting the device: pio run -e nodemcuv2 -t upload --upload-port YOUR IP. Replace YOUR IP with the value received by pio device monitor.

Alternatively you can add the ip address to the platformio.ini file by adding the following line to the respective device: upload_port = YOUR IP ADDRESS.

If all went well the internal led on your device has started blinking and a success message was received. Congrats you've just issued your first OTA firmware update and cut the wire once and for all!!

As I reflect back on this exiting part of my technology odyssey I can only say that Platform.IO is a great open source ecosystem for IOT development and providing much needed process standardization. Its library of boards available in combination with its simplicity makes it a great time saver. The combination of Platform.IO with the ArduinoOTA capabilities for the ESP8266 creates even more value. In summary, an impressive toolset and in my next blog I plan to use its capabilities in combination with the SAP HANA Cloud Platform. Stay tuned.

One last thing. I do want to highlight: the PlatformIO community and in particular its seems-to-be-always-available: Ivan Kravets. A great community that provides timely support and keeps you updated.

Tiest van Gool

Boulder, CO

comments powered by Disqus