REMOTE OTA
Over The Air Device Updates
Last updated
Over The Air Device Updates
Last updated
Over-the-Air (OTA) Programming is a method that allows the remote sending of new firmware to IoT devices over the Internet, regardless of their location. This process works with the Thinger.io Cloud to deliver the new firmware binaries.
This feature enables us to keep devices updated with new security patches and code improvements quickly and on a large scale. It is an essential tool for the maintenance of IoT products, preventing the need to travel to the devices' locations.
The update process is performed using a Visual Studio Code extension that integrates with the Thinger.io cloud to upload new firmware binaries to the target device. This integration with the IDE streamlines the development process, allowing developers to compile and upload firmware as if the device were connected to the computer.
Before working with this tool it is necessary to install and configure Visual Studio Code and the PlatformIO extension as explained in the SDK SETUP section of the documentation. Then, you need to install the Thinger.io VSCode extension directly from the Extension manager. Search for "Thinger.io" or Checkout on Microsoft Marketplace.
This extension will manage the OTA processes with several interesting features such as:
OTA updates directly from the Internet over Thinger.io
Device and Product switcher to search and select the target device(s) for the update
Real-time device connection status and input/output indicators
Compatibility with multiple PlatformIO configuration environments within a project
Automatic build and upload over the Internet with a single click
OTA with compression support for ESP8266, ESP32, and Arduino Portenta devices
MD5 checksum verification for firmware binaries, both compressed and uncompressed
Before running the OTA, it is necessary to configure the extension by accessing the VS Code Extensions Manager and selecting the Extensions Settings option.
Thinger.io Host: Place here the URL of the Thinger.io Instance you are working with (if using a private instance, otherwise by default it will be backend.thinger.io
).
Thinger.io Port: Specifies the connection port (443 by default).
Thinger.io Secure: Verify SSL/TLS connection (enabled by default).
Thinger.io SSL: Use SSL/TLS encryption (enabled by default).
Thinger.io Token: Place here a Thinger.io Access Token with the following permissions:
ListDevices
AccessDeviceResources
ReadDeviceStatistics
ListProducts
The following image provides a token configuration example with the required permissions.
The OTA feature is implemented on the default Thinger.io Arduino IOTMP client libraries required for the connectivity with the Thinger.io cloud.
The boards that supports OTA updates over the Visual Studio Code extension are the following:
Espressif ESP8266
Espressif ESP32
Arduino Nano 33 IOT
Arduino MKR WiFi 1010
Arduino RPI2040 Connect
Arduino MKR NB 1500
Arduino Portenta
Arduino Opta
The general requirement to start working with OTA updates for a specific device are:
Have a PlatformIO project on Visual Studio Code for the target device. More details here.
Have a basic Thinger.io firmware for your device, and ensure you it can connect to the cloud.
Modify the sketch to include the OTA functionality. More details in each specific device section.
Flash the initial firmware over a serial communication port on the computer.
Use the Thinger.io Visual Studio Code toolbar buttons to select your device and flash new firmware.
If everything is configured correctly it will be possible to start working with the Thinger.io extension via the new elements added to the bottom toolbar. There are two buttons that allow to select the target device to be flashed, and then compile and upload new firmware binaries.
Select Target Device 🚀
This button is a device selector, when you click it, it will prompt to search and select a target device from your Thinger.io account.
When the target device is disconnected, the target device button background color will be red.
Compile and Update ▶️
This button compiles and uploads the code to the selected device. In the process it will show a window with the OTA progress.
To update your device over OTA, the first time it must be flashed from a serial com port.
Clean Target Device 🗑️
It is possible to clean the selected target device accessing the Visual Studio command Palette with Ctrl
+ Shift
+ P
, and searching for Thinger.io
To add OTA functionality for ESP32 it is only required to include the ThingerESP32OTA.h
header and create an instance of it. A complete example for a basic firmware with OTA support can be as the following:
To add OTA functionality for ESP8266 it is only required to include the ThingerESP8266OTA.h
header and create an instance of it. A complete example for a basic firmware with OTA support can be as the following:
To add OTA functionality for Arduino Portenta and Opta devices it is required to include the ThingerPortentaOTA.h
header and create an instance of it. A complete example for a basic firmware with OTA support can be as the following:
It may be required to update the bootloader of your Portenta/Opta device to enable OTA updates.
Update the Bootloader of your Arduino Portenta/Opta: Run the sketch 'STM32H747_System_manage_Bootloader'
Format the QSPI flash memory: Run the sketch 'QSPIFormat'.
Run WiFiFirmwareUpdater
To add OTA functionality for Arduino Nano 33 IOT it is required to include the ThingerWiFiNINAOTA.h
header and create an instance of it. A complete example for a basic firmware with OTA support can be as the following:
Note: it is required to include lib_archive = no
to platformio.ini
configuration file.
To add OTA functionality for Arduino MKR WiFi 1010 it is required to include the ThingerWiFiNINAOTA.h
header and create an instance of it. A complete example for a basic firmware with OTA support can be as the following:
Note: it is required to include lib_archive = no
to platformio.ini
configuration file.
To add OTA functionality for Arduino RPI2040 Connect it is only required to include the ThingerMbedOTA.h
header and create an instance of it. A complete example for a basic firmware with OTA support can be as the following:
To add OTA functionality for MKR NB 1500 it is only required to include the ThingerMKRNBOTA.h
header and create an instance of it. A complete example for a basic firmware with OTA support can be as the following:
Note: it is required to include lib_archive = no
to platformio.ini
configuration file.
At this moment, it seems that MKR NB 1500 requires pressing the reset button to apply the OTA update.
Firmware versioning is essential for managing updates and maintaining the security of IoT devices. As IoT deployments grow in complexity and scale, proper versioning ensures that devices operate reliably and securely.
Our recommended versioning system follows the Semantic Versioning (SemVer) approach, which uses a Major.Minor.Patch format:
Major: Incremented for incompatible API changes.
Minor: Incremented for added functionality in a backwards-compatible manner.
Patch: Incremented for backwards-compatible bug fixes.
To define your firmware version, it is required to define a preprocessor definition called THINGER_OTA_VERSION
. This is used inside the firmware and VS Code to decide when a device requires an update.
Each time an OTA update process is started, the system will display a confirmation dialog showing the details of the firmware to be uploaded. This dialog includes the device name, firmware version, and the environment. It ensures that the user is informed about the firmware update specifics before proceeding, providing an additional layer of verification.
Devices that are already running the current firmware version will not be updated, ensuring that only devices with outdated firmware receive the new update. This helps to optimize the update process, reducing unnecessary data transfer and minimizing downtime for devices that are already up-to-date.
For development purposes, it is possible to remove the THINGER_OTA_VERSION
definition, which will prevent version checking on the update process.
It is possible to define the firmware version in different places, such as:
In the source code
Through external build flags
Based on version control, like git tags
Below, we describe the different alternatives in detail.
Define THINGER_OTA_VERSION
in code before Thinger.io includes. This method involves hardcoding the firmware version directly in your source files. Each time you need to update the firmware version, you must manually change the version number in the code and redeploy the firmware.
Create a build flag in platformio.ini
with a static version definition. This approach sets the firmware version through build configuration. To update the firmware version, you need to modify the version number in the platformio.ini
file and rebuild the firmware.
This is the recommended approach and consists of dynamically setting the firmware version based on version control information, such as git tags. This method ensures the firmware version is automatically updated based on the latest git tag, reducing manual intervention. Each time you tag a new version in git, the build process will automatically use this tag as the firmware version.
To achieve this configuration, it is required to modify the platformio.ini
file and include a build flag that will be dynamically composed using the git describe
command. This command retrieves the latest git tag and uses it to set the THINGER_OTA_VERSION
preprocessor definition.