Skip to content

Transfer Filesystem data using PlatformIO Core

Mick Percy edited this page Aug 4, 2021 · 4 revisions

If you are developing on a platform like the ESP32. You will most likely have a requirement to be able to transfer files directly to the filesystem partition on the board. By default the Arduino editor does not do this, you need to install a third party tool. The Arduino-CLI is no different.

I decided to use PlatformIO to handle this for me. Platform IO can also handle more complex compile time / build tasks and so is a really good tool to augment Novas capabilities as it allows you to leverage the power of PlatformIO without having to use the PlatformIO IDE

PlatformIO Core installation

The command line version of Platform IO is PlatformIO Core. This is essentially a headless PlatformIO. Installation is pretty straightforwards but does have some caveats when it comes to Macs crappy Python management. You see by default Mac / OSX comes installed with Python 2.7. Not only is this outdated, but it's also the default Python version, so all Python apps will run under 2.7 even if you install a later version.

The best solution is to leave 2.7 installed but to use pyenv to manage your Python versions. This way you do not need to interfere with the core python version and can use the current version instead.

Install pyenv

The easiest safest way to install is using homebrew...

brew install pyenv

Install python

Now install the current python version through pyenv...

pyenv install 3.9.6

Once installed, you need to set the default global version. This can be done using the following command...

pyenv global 3.9.6

This is where the magick happens. We have essentially overridden the out-of-date 2.7 version without uninstalling it or replacing it. In fact we haven't touched it at all. pyenv takes care of everything automagickally. :)

In order for pyenv to work correctly you need to let it take control of the shells path engine, to do this you can issue the following command, which essentially adds a small bit of code to your .bash_profile or .zsh_profile files.

echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\n eval "$(pyenv init -)"\nfi' >> ~/.zshrc

You can confirm what version you have installed by using the following command

pyenv version

And that's essentially it. You should also consider updating the Python package manager pip3

pip install --upgrade pip

This process is covered in a lot more detail in Matthew Broberg's article The right and wrong way to set Python 3 as default on a Mac

Install PlatformIO Core

Now that the Python environment is sorted out we can continue with the installation of PlatformIO

There's a couple of different options here, including installation via the python package manager...

pip install -U platformio

or installation via homebrew...

brew install platformio

More in depth information on installation can be found on the PlatformIO installation page

Install Shell Commands

If you use Bash as your default shell, you can do it by editing either ~/.profile or ~/.bash_profile and adding the following line:

export PATH=$PATH:~/.platformio/penv/bin

If you use Zsh, you can either edit ~/.zprofile and add the code above, or for supporting both, Bash and Zsh, you can first edit ~/.profile and add the code above, then edit ~/.zprofile and add the following line:

emulate sh -c '. ~/.profile'

After everything’s done, just restart your session (log out and log back in) and you’re good to go.

More information on installing Shell Commands can be found on the PIO Installation Page

Setting up Nova

Now that you have PlatformIO installed there's a couple of things you need to do before you can use it within Nova.

The first thing is to create a platformio.ini file for your project. This is a file that resides within the Arduino project folder that the PlatformIO core uses to run its build tasks. It's essentially a build configuration file. The contents will vary depending on your project and what build tasks you need to undertake.

The platform.ini file sets up the environment and lists library dependencies and build conditions. I've included one of my files here for reference. For the most part it is pretty straight-forwards to understand but for some further reading you can always visit the platfromio.ini help page

; PlatformIO Project Configuration File
;
;   Build options: build flags, source filter
;   Upload options: custom upload port, speed and extra flags
;   Library options: dependencies, extra library storages
;   Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html

[platformio]
src_dir = DIY-Flow-Bench
lib_dir = libraries
data_dir = ESP32/diy-flow-bench/data
default_envs = release
;extra_configs=debug.ini

[common_env_data]
lib_deps_builtin = 
	ArduinoOTA
	BluetoothSerial
	DNSServer
	EEPROM
	ESPmDNS
	FS
	Preferences
	SD
	SPI
	SPIFFS
	Update
	WebServer
	WiFi
	WiFiClientSecure

[common]
build_flags = 
	;-DMACHINE_FILENAME=test_drive.h ;Remove ";" from the beginning of this line and specify the machine file
	-DCORE_DEBUG_LEVEL=0
	-Wno-unused-variable
	-Wno-unused-function

[env]
;lib_deps = 
;	TMCStepper@>=0.7.0,<1.0.0
platform = espressif32@3.0.0 ; temporary fix for lost uart rx characters
board = esp32dev
framework = arduino
upload_speed = 115200
board_build.partitions = no_ota.csv
monitor_speed = 115200
monitor_flags = 
	--eol=CRLF
	--echo
	--filter=esp32_exception_decoder
board_build.f_cpu = 240000000L
board_build.f_flash = 80000000L
board_build.flash_mode = qio
build_flags = ${common.build_flags}
src_filter = 
	+<*.h> +<*.s> +<*.S> +<*.cpp> +<*.c> +<*.ino> +<src/>
	-<.git/> -<data/> -<test/> -<tests/>

[env:release]
lib_deps = 


[env:debug]
build_type = debug
lib_deps = 

Adding a Nova Task.

As with the Arduino-CLI compile and upload tasks, create a new Run task in the Nova projects settings dialog. I named mine SPIFFS as that's the filesystem I'm using on my ESP32's.

cd /Users/Mick/Documents/Arduino/DIY-Flow_bench/ 
pio run -t uploadfs 

I always select 'open a report on run' so that I can see the verbose output from the running task. This helps a lot with debugging.

And that's essentially it.

The expression is pretty self explanatory