Asset OTA

Asset OTA (available in Device OS 5.5.0 and later), makes it easy to include bundled assets that can be delivered to other processors and components in your system, such as:

  • Coprocessors
  • Graphics and fonts for external displays
  • Sound samples for device with audio output capabilities

Including assets is as easy as including an directory in your project, specifying it in the and building and flashing using Particle Workbench, the Particle CLI, or fleet-wide OTA for a product. Bundled assets can be up to 1 MB to 1.5 MB in size, after compression, depending on the platform, and do not use additional data operations.

The compression algorithm is similar to gzip, so using a gzip program on the assets folder on your computer will yield the approximate size after compression.

  • Particle Workbench and the Particle CLI will automatically generated bundled assets when the file contains an assetOtaDir key and a value containing a valid directory.
  • When using Particle: Compile Application or particle compile projects with bundled assets are built into a .zip file. This file contains both the firmware binary (.bin) as well as the assets.
  • The asset bundle .zip can be uploaded to the console as product firmware binary.
  • When using Particle: Flash application or particle flash the same process is followed, except the device is flashed.
  • When flashing OTA, the asset bundle is transmitted using resumable OTA and compression for efficient data use.
  • You will need to include code in your application firmware to process the additional assets, such as sending them to a coprocessor or saving them to the file system.
  • Creating bundled assets will not be not possible in the Web IDE. Particle Workbench is recommended.

The application can register a callback using System.onAssetOta() that will be called by Device OS when the device has received all the bundled assets. For more information, see the Asset OTA Device OS API.

Maximum asset sizes

Platforms Total asset storage Maximum single asset size
tracker, b5som, esomx 2 MB 1.5 MB
boron, bsom, argon 1.125 MB 592 KB
p2 (and Photon 2) 1.125 MB 1.09 MB

Asset OTA Example

The rest of this document shows how to add OTA assets to your project. This example just saves the files to the flash file system so you can run it without any additional hardware beyond a compatible Particle cellular or Wi-Fi device. Additional examples of using Asset OTA can be found on the GitHub repository asset-ota-examples.

Instead of saving the assets to the flash file system, you could:

  • Directly flash an external coprocessor, such as by UART serial.
  • Directly write to an external display connected by SPI.

If you call System.assetsHandled(false) the assets will be presented on every boot, which is often more space-efficient than storing a separate copy in the file system. You still may want to store it in a file if you need random access to the asset, or need it later, after boot. For example, if you have multiple sound file assets and you want to be able to choose one to play, the file system would be a good choice.

Example firmware



This example stores assets in the user portion of flash file system, but this done for illustration only because it does not require external hardware and the example is easy to follow. Because assets are stored by the system even after you mark them as handled, you can always start reading the assets again using System.assetsAvailable() and reading the assets again. This is often more efficient.

onAssetOTA or assetsAvailable

There are two ways to handle assets. A common way is to use System.onAssetOta():


This example uses a call from setup() and System.assetsAvailable() instead, otherwise the debug log messages may occur so early at boot that you don't see them.


Processing Assets

In handleAssets() the code iterates through all of the assets. This is typical.

for (auto &asset : assets)
    // Put code here to handle asset

For each asset, the example creates a file on the flash file system with the same name. It then reads the data out of the asset and writes it to the file.

You must specify the assetOtaDir in your file for assets to be generated.


assets directory

You specify the name of the directory containing assets using assetOtaDir so it doesn't need to be called assets but that is what is used in the example.

There are two files in the example:

  • assets/logo.png: A small Particle logo png image file
  • assets/test1.json: A small JSON file to demonstrate using Asset OTA for distributing JSON configuration files

Creating a zip binary

One common option for creating a binary is to use the Particle CLI. The main difference is that you must specify a .zip file instead of a .bin file if you specify the filename using --saveTo.

% cd FileAssetExample
% particle compile p2 . --saveTo --target 5.5.0

Compiling code for p2
Targeting version: 5.5.0


attempting to compile firmware
downloading binary from: /v1/binaries/64e377e11067c0b8a0d11471
Memory use:
   text    data     bss     dec     hex filename
  17518     124    3254   20896    51a0 /workspace/target/workspace.elf

Compile succeeded and bundle created.
Saved bundle to: /Users/rick/Downloads/FileAssetExample/

You can see the files that are added to the bundle listed in the Including: section.

If you extract this zip file, you'll find that it contains firmware.bin, the compiled binary, and the assets directory containing your assets.

Flashing a device

You can then flash the zip file to the device using the Particle CLI or upload it to a product.

% particle flash test-photon2

From Workbench

You can also use the local and cloud compile options in Particle Workbench to create an asset binary, directly flash the device OTA, or flash the device over USB:

Observing the debug output

At boot, you'll see output similar to this. This shows the data being copied to the flash file system.

0000003378 [app] INFO: handleAssets called
0000003383 [app] INFO: asset path=/usr/assets/logo.png size=2466
0000003434 [app] INFO: wrote 512 bytes to file
0000003442 [app] INFO: wrote 512 bytes to file
0000003454 [app] INFO: wrote 512 bytes to file
0000003463 [app] INFO: wrote 512 bytes to file
0000003470 [app] INFO: wrote 418 bytes to file
0000003518 [app] INFO: asset path=/usr/assets/test1.json size=44
0000003566 [app] INFO: wrote 44 bytes to file
0000003783 [app] INFO: set assetsHandled to true

Every 10 seconds, the example prints out the asset files. The logo.png file is printed in hex, and the data should be as it is below.

The top level keys of the test1.json file are printed out. You can edit the file, compile, and flash it and see the values change.

0000010001 [app] INFO: found asset /usr/assets/logo.png size=2466
0000010126 [app] INFO: found asset /usr/assets/test1.json size=44
0000010132 [app] INFO: key=a value=JSON example
0000010135 [app] INFO: key=b value=12345

In the console

In the Particle console, if you view a device, you can see the assets that were flashed just below the functions and variables:

Console device view

Cleaning up

This will leave the files on the flash file system, which will be preserved even when you flash new firmware. To clean up these files, change the checkAssets() function to this and flash the firmware to your device to clean up the files in the assetsDir.

void checkAssets()
    // This is just for demonstration purposes for reading assets
    DIR *dirp = opendir(assetsDir);
    if (dirp)
        while (true)
            struct dirent *de = readdir(dirp);
            if (!de)
            if (de->d_type != DT_REG)
                // Not a file
            String path = String::format("%s/%s", assetsDir, de->d_name);

Community examples

Arduino Uno example

The Arduino Uno Asset OTA example shows how to interface to a 5V Arduino device, including necessary level shifting hardware, and flash the device firmware using Asset OTA.

Arduino Uno

Asset OTA sound example

The Asset OTA sound example shows how you can upgrade sound assets stored on an external SD card using Asset OTA.

Sound example

STM32 example

The STM32 Asset OTA example shows how to upgrade the firmware running on an external MCU using Asset OTA, in this case a STM32 MCU. This was shown during Spectra 2023.

LCD image

The LCD image Asset OTA example shows how you can include image assets that can be shown on a LCD display connected to the Particle device. This was shown during Spectra 2023.