Changing ESP32 partition scheme in arduino-cli

So I was connecting PS3 controller to my “Jerry Annihilator” robot tank the other day, and faced the weirdest (of that day) issue: Arduino’s compilation process was reliably failing with “Sketch is too big” error. Can you imagine?

Sketch is too big

Apparently, Ps3Controller library and its underlying dependency – Bluetooth Low Energy lib – were so big, that they wouldn’t fit into my trusty ESP32 module. However, quick googling suggested that changing partition scheme could help.

Indeed, choosing “Minimal SPIFFS” partition scheme from the “Tools” menu increased program storage space from 1.2MB to 1.9 megs, which is more than enough for my 1.4MB sketch.

Minimal SPIFFS partitioning scheme

So we’re all good, right? No, not entirely. As I mentioned in my previous post, I’m using arduino-cli to compile the sketch on GitLab server. So naturally partition scheme should be specified there as well. But how? Is that even possible?

TL;DR yes, it’s possible, just add --build-properties build.partitions=min_spiffs,upload.maximum_size=1966080 parameter to arduino-cli compile call and magic will happen. But if you want to hear the whole story, stick around for a little bit longer

Long and beautiful story

How Arduino IDE applies partition scheme

First thing I wanted to know is how Arduino itself tells esp32 toolchain to use the partition scheme. Is that some sort of a parameter?

The build output window didn’t contain much, but as I suspected, there was a checkbox in Preferences window, which turned IDE into a chatter box.

Enable verbose output
“Show verbose output during:” compilation

Oh yeah, it started to talk alright. I copy-pasted the output to proper editor, and what do you know, very first two lines had PartitionScheme parameters with min_spiffs in them!


What’s more, down the output there was a line that connected min_spiffs  to actual CSV file:

Partition scheme file path

The contents of that file wasn’t that interesting, but at least I learned the keyword I need to search by and somehow pass to my arduino-cli compile call: min_spiffs.

Partition Schemes
Partition schemes

How arduino-cli applies partition scheme

Here I wanted to see if arduino-cli‘s output looks similar to IDE’s. arduino-cli compile --fqbn esp32:esp32:esp32  -v spit out a lot, and that ‘a lot’ looked awfully identical to what I saw in Arduino itself. Well, except for that partitioning thing – this time it was default.

This small experiment proved that arduino-cli at least knows about partitions. I just needed to find the way to tell it about a particular one.

arduino-cli compile --help didn’t say a lot, but it did mention that there’s a --build-properties parameter, and I’d bet my favourite horse that this is going to be the door to knock. But what values does it accept?

Having nothing left here I decided to look into that mysterious  ~/.arduino15/packages/esp32 folder, where CSV with partition schemes were living. It only took grep -ir min_spiffs to find the biggest clue possible.

look for mentions of min_spiffs

The long strings obviously corresponded to the GUI menu items, but the shorter ones – build.partitions and upload.maximum_size, could they be..?

arduino-cli compile --fqbn esp32:esp32:esp32 tank.ino --build-properties build.partitions=min_spiffs still failed. But this time the output did contain the correct partitioning scheme. Maybe adding the second parameter would finish the job.

And it did! arduino-cli compile --fqbn esp32:esp32:esp32 tank.ino --build-properties build.partitions=min_spiffs,upload.maximum_size=1966080 thought for about a minute, and then produced perfectly valid .bin file, which I was able to upload to the board. Both the ps3 controller logic and the firmware were fully functional.

Victory! Choosing between PS3 controller and my GitLab CI server I managed to keep them both.

8 thoughts on “Changing ESP32 partition scheme in arduino-cli

  1. Thanks for this information, it got me where I needed to be. Additionally, I just find out that if you type:

    “arduino-cli compile –fqbn esp32:esp32:esp32 –show-properties”

    It will show all the properties, so no need to go grepping for files!

  2. Ah that comment is very handy. Just to add my 2c, in 2022 using arduino-cli for esp32s3 (16f/8r) I’m using:

    arduino-cli --fqbn esp32:esp32:esp32s3 -p COM14 compile --board-options FlashMode=qio,FlashSize=16M,LoopCore=1,EventsCore=1,USBMode=hwcdc,CDCOnBoot=default,MSCOnBoot=default,DFUOnBoot=default,UploadMode=default,PartitionScheme=default_8MB,CPUFreq=240,UploadSpeed=921600,DebugLevel=none,EraseFlash=none

  3. Great write-up and it’s helping me figure out how to fix my Makefile to do much quicker compiles with the v2.x of the Arduino build system which includes creating spiffs and littlefs filesystems.

    But, it’s missing a piece of information for others who might want to use different memory configurations. That is, where the number 1966080 came from. I figured that out though.

    In the min_spiffs.cvs file on the app0 line:
    app0, app, ota_0, 0x10000, 0x1E0000,

    The last number of 0x1E0000 is the hex equivalent of 1966080 which means, if you use another partitioning configuration you should be able to find the number on the end of the app0 line and convert that from hex to decimal and the compiler should work with that partitioning too.

  4. Thanks for the great article, it was very helpful in getting Arduino OTA working on my ESP32-CAM.

    Just a note that in one place you have a typo with minspiffs without an underscore:
    Which should read as:

Leave a Reply

Your email address will not be published. Required fields are marked *