ESP stand alone programming

Good morning everyone
I have a need to which I have not found an answer in simple terms. I have developed an application with Platform-Io on ESP32 platform. The application is tested and working and now I have to send the object code to the customer to update the FW.
In the past I used atp “pio remote” to update remotely but now the
customer asks me to be able to do it even in conditions where the internet connection is not available.
There is a utility to do this easily by sending the object file via email to the customer.
Maybe it’s written in the Platform-io documentation but I haven’t seen it
Thanks for your help

Does flashing happen wirelessly (OTA) or via USB-cable + usb-uart converter (using

I have to flash via usb-clable.
I don’t know “” but I document myself and see how to use it. At this point I just have to find the folder where to recover the executable file that generates PlatoformIO

People have already solved similiar type of problems before: See Upload littlefs.bin to ESP8266 boards.

The firmware files PlatformIO generates will be saved in .pio/build/<environment name>/firmware.bin.

With ESP32 you have to careful though, as not only your application image gets flashed technically, but also the bootloader, the partition table and other things. You can see exactly how PlatformIO flashes the binary for your project when you invoke the project task Advanced → Verbose Upload.

For example, with

platform = espressif32
board = esp32dev
framework = arduino

that is

CURRENT: upload_protocol = esptool
BeforeUpload(["upload"], [".pio/build/esp32dev/firmware.bin"])
Auto-detected: /dev/ttyACM0
"/home/max/.platformio/penv/bin/python" "/home/max/.platformio/packages/tool-esptoolpy/" --chip esp32 --port "/dev/ttyACM0" --baud 460800 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 40m --flash_size 4MB 0x1000 /home/max/temp/simple_esp32/.pio/build/esp32dev/bootloader.bin 0x8000 /home/max/temp/simple_esp32/.pio/build/esp32dev/partitions.bin 0xe000 /home/max/.platformio/packages/framework-arduinoespressif32/tools/partitions/boot_app0.bin 0x10000 .pio/build/esp32dev/firmware.bin v4.4
Serial port /dev/ttyACM0

So the critical command is basically --chip esp32 --port “/dev/ttyACM0” --baud 460800 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 40m --flash_size 4MB 0x1000 […]bootloader.bin 0x8000 […]partitions.bin 0xe000 […]boot_app0.bin 0x10000 […]firmware.bin

(on Windows, /dev/ttyACM0 will be a COM device, aka the serial port where the dev board is connected to, like COM9)

If you the hardware is non-changing, then details like flash mode, frequency and isze will always be same.

So what people usually do is:

  • Save every involved individual binary file
  • combine all binary files (with filler data in between the non-defined addresses) to one single flash image

Then they usually convert the tool to a native Windows Exe file to lose the dependency on having the customer install Python (and all esptool dependencies). They then write a batch (.bat) file tha invokes the flashing command (aka esptool.exe ) and bundle the new binaries in that folder.

The alternative to that is to use Espressif’s official GUI flashing tool avaiable from Tools | Espressif Systems.


which, as expected, wants you to give it all binary files it is supposed to flash along with the address where it’s supposed to go.

There’s also more GUI download tools like GitHub - Grovkillen/ESP_Easy_Flasher: A wrapper for ESPTOOL.exe + PowerShell to make flashing/programming ESP Easy units more streamline, these might expect the merged imaged though.

Note that the image merging can be facilitated through either the Espressif GUI after filling in the binaries and addresses

or, too.

max@XXXXX:~/temp/simple_esp32$ source ~/.platformio/penv/bin/activate
(penv) max@XXXXXX:~/temp/simple_esp32$ ~/.platformio/packages/tool-esptoolpy/ --help
usage: esptool [-h] [--chip {auto,esp8266,esp32,esp32s2,esp32s3beta2,esp32s3,esp32c3,esp32c6beta,esp32h2beta1,esp32h2beta2,esp32c2,esp32c6}] [--port PORT] [--baud BAUD]
               [--before {default_reset,usb_reset,no_reset,no_reset_no_sync}] [--after {hard_reset,soft_reset,no_reset,no_reset_stub}] [--no-stub] [--trace] [--override-vddsdio [{1.8V,1.9V,OFF}]]
               [--connect-attempts CONNECT_ATTEMPTS]
               ... v4.4 - Espressif chips ROM Bootloader Utility

positional arguments:
                        Run {command} -h for additional help
    load_ram            Download an image to RAM and execute
    dump_mem            Dump arbitrary memory to disk
    read_mem            Read arbitrary memory location
    write_mem           Read-modify-write to arbitrary memory location
    write_flash         Write a binary blob to flash
    run                 Run application code in flash
    image_info          Dump headers from an application image
    make_image          Create an application image from binary files
    elf2image           Create an application image from ELF file
    read_mac            Read MAC address from OTP ROM
    chip_id             Read Chip ID from OTP ROM
    flash_id            Read SPI flash manufacturer and device ID
    read_flash_status   Read SPI flash status register
    write_flash_status  Write SPI flash status register
    read_flash          Read SPI flash content
    verify_flash        Verify a binary blob against flash
    erase_flash         Perform Chip Erase on SPI flash
    erase_region        Erase a region of the flash
    merge_bin           Merge multiple raw binary files into a single file for later flashing
    get_security_info   Get some security-related data
    version             Print esptool version

I looked at the documentation received
and I think I will use the Espressiv tools
I think I found the file paths in the file
to load.
I’ll do some testing over the next few days to see
that everything works.
Thanks for the help

1 Like

If it helps, I am using this script for programming ESP32.

Thanks for this additional information .
I think it helps me to use the script

If you are using the Arduino framework then you can use the WifiManager library which allows for wifi setup and also now has the ability to upload and flash new firmware.