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?
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.
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.
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:
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
.
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.
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.
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!
That’s very good to know, thank you!
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
Thanks!!!!!!
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.
Thank you, that’s good to know!
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:
build.partitions=minspiffs,upload.maximum_size=1966080
Which should read as:
build.partitions=min_spiffs,upload.maximum_size=1966080
Thank you! I’ve fixed the typo.