A great way to compile for and flash an Arduino device from the command line and integrate with Vim is to use PlatformIO Core (CLI).
Since it's written in Python it's easy to install even when it's not packaged for your Linux distribution. PlatformIO supports many microcontroller devices, not just Arduino ones. Thus, you don't have to switch your development environment when you target another platform. PlatformIO takes care of downloading the right toolchain (compiler etc.) for your target.
Example
Getting started with PlatformIO and an Arduino Pro Mini 3.3v clone on Fedora 35:
mkdir -p ~/local
cd ~/local
python -m venv platformio
source platformio/bin/activate
pip install platformio
This installs PlatformIO (CLI) in a virtual environment, i.e. its main command is then available from ~/local/platformio/bin/pio
and pio
is found in your PATH
when the virtual environment is activated.
Next, we need to find the right board ID for setting up a new project:
pio boards arduino | less
That means search for Pro.*Mini
in the listing. There are several versions of the Pro Mini, in our example the pro8MHzatmega328
(3.3 V, 8 MHz, ATmega328, 30 kb flash, 2 kB RAM) is the right one as can be validated by looking at the board markings as well as its voltage regulator, and CPU markings.
To set up a new project
mkdir ~/project/some_new_project
cd ~/project/some_new_project
pio project init --board pro8MHzatmega328 --ide vim
Which prints:
The current working directory /home/juser/project/arduino/pro-mini will be used for the project.
The next files/directories have been created in /home/juser/arduino/pro-mini
include - Put project header files here
lib - Put here project specific (private) libraries
src - Put project source files here
platformio.ini - Project Configuration File
Platform Manager: Installing atmelavr
Downloading [####################################] 100%
Unpacking [####################################] 100%
Platform Manager: atmelavr @ 3.4.0 has been installed!
Tool Manager: Installing platformio/toolchain-atmelavr @ ~1.70300.0
Downloading [####################################] 100%
Unpacking [####################################] 100%
Tool Manager: toolchain-atmelavr @ 1.70300.191015 has been installed!
The platform 'atmelavr' has been successfully installed!
The rest of the packages will be installed later depending on your build environment.
Project has been successfully initialized including configuration files for `vim` IDE.
For a first test one can copy a simple blink-led example using the usual setup()
/loop()
functions. It's possible to re-use an existing 'sketch' from the Arduino IDE, one just has to add #include <Arduino.h>
at the top and place it under src/some-name.cc
or src/some-name.cpp
.
To compile everything:
pio run
Which prints:
Processing pro8MHzatmega328 (platform: atmelavr; board: pro8MHzatmega328; framework: arduino)
--------------------------------------------------------------------------------
Verbose mode can be enabled via `-v, --verbose` option
CONFIGURATION: https://docs.platformio.org/page/boards/atmelavr/pro8MHzatmega328.html
PLATFORM: Atmel AVR (3.4.0) > Arduino Pro or Pro Mini ATmega328 (3.3V, 8 MHz)
HARDWARE: ATMEGA328P 8MHz, 2KB RAM, 30KB Flash
DEBUG: Current (avr-stub) On-board (avr-stub, simavr)
PACKAGES:
- framework-arduino-avr 5.1.0
- toolchain-atmelavr 1.70300.191015 (7.3.0)
LDF: Library Dependency Finder -> https://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 5 compatible libraries
Scanning dependencies...
No dependencies
Building in release mode
Compiling .pio/build/pro8MHzatmega328/src/sos-switch.cc.o
Linking .pio/build/pro8MHzatmega328/firmware.elf
Checking size .pio/build/pro8MHzatmega328/firmware.elf
Advanced Memory Usage is available via "PlatformIO Home > Project Inspect"
RAM: [ ] 0.4% (used 9 bytes from 2048 bytes)
Flash: [ ] 3.8% (used 1170 bytes from 30720 bytes)
========================= [SUCCESS] Took 0.51 seconds =========================
So for this example I created src/sos-switch.cc
which is compiled to .pio/build/.../sos-switch.cc.o
.
To upload (flash) the device:
pio run --target upload
As always, a common pitfall are the permissions of the USB device. For example, on Fedora, my USB2TTL serial device registers as /dev/ttyUSB0
with read-write permissions for just root:dialout
. Thus, you have to add your user to the dialout
group or adjust the permissions by other means.
Vim Quickfix Mode
For integrating with Vim's quickfix mode a simple makefile is sufficient, e.g.:
.PHONY: all
all: build
.PHONY: build
build:
pio run
.PHONY: upload
upload:
pio run --target upload
Thus, everything is built when :make
is invoked in Vim, and there one can navigate the quickfix mode as usual.
Serial Monitoring
An easy way to monitor the serial interface is to use picocom, e.g.:
picocom --baud 9600 --echo --imap lfcrlf --noreset /dev/ttyUSB0
where:
--imap lfcrlf
maps newline to carriage return + newline such that we can just write Serial.print("multi\nlines\n')
instead of Serial.print("multi\r\nlines\r\n")
in our program
--noreset
tells picocom to not clear DTR - without it, when DTR is connected, the Anrdoid device is reset
Of course, one has to terminate picocom when uploading.
Alternatively, one can use the PlatformIO monitor command:
pio device monitor
In contrast to picocom, it doesn't require explicit mapping or DTR handling. However, as with picocom, it must be terminated when uploading/flashing. That means PlatformIO doesn't automatically suspends monitoring when pio run --target upload
is invoked.
Closing Remarks
- PlatformIO is currently packaged for Fedora and thus might be directly available in Fedora 36 or so
- the classic Arduino IDE was packaged for Fedora, but isn't available anymore in Fedora 35 because of the big Java package exodus
- there is also a PlatoformIO plugin for VSCode which seems to be quite popular
arduino-cli
tool is extremely good. You can make a very simple 2 lineMakefile
in no time.