Arduino Uno — First Upload
Setting up arduino-cli, writing a blinker sketch in neovim, compiling and uploading over USB serial.
The Setup
After the IC theory, time to put a microcontroller in front of me. Arduino Uno is the obvious starting point — AVR ATmega328P at its core, but all the hardware abstraction taken care of.
Skipped the IDE entirely. arduino-cli from the terminal is cleaner.
brew install arduino-cli
First Sketch
arduino-cli sketch new blinker
This creates a blinker/blinker.ino directory and file. Opened it in neovim:
void setup() {
pinMode(8, OUTPUT);
}
void loop() {
digitalWrite(8, HIGH);
delay(1000);
digitalWrite(8, LOW);
delay(1000);
}
The canonical first program. Pin 8 drives an LED on a breadboard through a current-limiting resistor — keeps the LED from pulling too much current and burning out.
Toolchain
Before compiling, need the AVR core:
arduino-cli core update-index
arduino-cli core install arduino:avr
arduino:avr installs avr-gcc, avrdude, and the board definitions. The FQBN (Fully Qualified Board Name) for the Uno is arduino:avr:uno.
Compile
arduino-cli compile --fqbn arduino:avr:uno .
Compiles to a .hex file in a temp build directory. The output shows memory usage — the blinker sketch takes ~924 bytes of the 32KB flash. Plenty of room.
Upload
First, find the board’s port:
arduino-cli board list
This lists all connected boards with their port, protocol, and FQBN. The Uno shows up as something like /dev/cu.usbserial-1120 with arduino:avr:uno detected automatically.
arduino-cli upload -p /dev/cu.usbserial-1120 --fqbn arduino:avr:uno .
The port /dev/cu.usbserial-1120 is the CH340 USB-serial chip on the board. avrdude handles the upload over the bootloader — no programmer needed.
The onboard LED blinked on first try.
What’s Actually Happening
The Arduino bootloader lives in the last 512 bytes of flash. When the board resets (triggered by DTR toggle on upload), the bootloader runs briefly and listens for an STK500 protocol handshake on the serial port. avrdude sends the compiled .hex over that protocol, the bootloader writes it to flash, then jumps to the user program at address 0.
The whole compile → upload loop takes about 3 seconds. Fast enough that the CLI doesn’t feel slower than the IDE.
Next
Try reading sensor data back over serial (Serial.begin(9600) + Serial.println()), then monitor with arduino-cli monitor.