A tiny Zig workspace that builds both a host-side CLI and an AVR firmware using MicroZig. The firmware targets common Arduino Uno/Nano clones based on the ATmega328P and toggles the on-board LED (D13 / PB5).
- Host app:
zig-out/bin/zig_duino(a simple CLI built for your machine). - Firmware:
zig-out/firmware/blink_avr.hex(for ATmega328P boards; LED on PB5/D13). - Toolchain: Zig 0.15.x + MicroZig for AVR.
- Zig 0.15.1 (check with
zig version). - avrdude (for flashing). On Arch Linux:
sudo pacman -S avrdude. - Serial access to
/dev/ttyUSB0:- Quick path: prefix commands with
sudo. - Recommended: add your user to the
uucpgroup and re-login:sudo usermod -aG uucp "$USER" # log out/in or reboot for group to take effect
- Alternatively, grant a temporary ACL:
sudo setfacl -m u:$USER:rw /dev/ttyUSB0
- Quick path: prefix commands with
Optional:
- PlatformIO CLI (handy for listing ports):
pipx install platformio pio device list
Fetch dependencies (MicroZig) and build everything:
zig build --fetch
zig buildFor AVR firmware, ensure ReleaseSmall optimizations when building:
zig build -Doptimize=ReleaseSmallArtifacts:
- Host CLI:
zig-out/bin/zig_duino - Firmware HEX:
zig-out/firmware/blink_avr.hex
-
Identify the serial port. Typical on Linux with CH340:
/dev/ttyUSB0. -
Probe the MCU signature and bootloader baud with avrdude (Uno/Nano clones use 57600 or 115200):
# Try 115200 first avrdude -c arduino -p m328p -P /dev/ttyUSB0 -b 115200 -v # If that fails, try 57600 avrdude -c arduino -p m328p -P /dev/ttyUSB0 -b 57600 -v
Expected signature for ATmega328P:
0x1E 0x95 0x0F. -
Flash the firmware (two options):
- Using avrdude directly:
avrdude -c arduino -p m328p -P /dev/ttyUSB0 -b 115200 -D \ -U flash:w:zig-out/firmware/blink_avr.hex:i
- Using the build-integrated flash step:
zig build -Doptimize=ReleaseSmall flash \ -Dflash-port=/dev/ttyUSB0 \ -Dflash-baud=115200 \ -Dflash-programmer=arduino \ -Davrdude-bin=avrdude \ -Dflash-mcu=m328p
If you lack permissions on the serial device, prefix direct avrdude with
sudoor fix permissions per Prerequisites. - Using avrdude directly:
build.zig: Builds the host app and configures MicroZig AVR firmware target.build.zig.zon: Zig dependency manifest (pulls MicroZig).src/main.zig: Host executable entry point.src/root.zig: Library for host app.src/firmware.zig: AVR blink firmware using MicroZig HAL (PB5/D13 toggle).zig-out/: Build outputs. Firmware HEX inzig-out/firmware/.
- Board detected as an Arduino-compatible with CH340 USB-serial.
- AVR target assumed ATmega328P (Arduino Nano/Uno clone) @ 16 MHz.
- Firmware builds and flashes successfully using avrdude at 115200 baud.
- Output file present:
zig-out/firmware/blink_avr.hex.
- Permission denied on
/dev/ttyUSB0:- Add user to
uucpgroup or usesudo/ACL as shown above.
- Add user to
- avrdude sync errors:
- Toggle baud between 115200 and 57600.
- Press/reset the board at the start of the upload.
- Ensure you’re using
-c arduino -p m328pfor ATmega328P bootloaders.
- Build errors on AVR regarding
compiler_rtor odd integer sizes:- Use
-Doptimize=ReleaseSmalland avoid pulling in heavy helpers. - This project disables bundling
compiler_rtfor the AVR firmware via build.zig.
- Use
- Adjust the LED pin or board target in
src/firmware.zig/build.zigif using a different AVR. - Add a serial "hello" example using
USARTvia MicroZig HAL. - Create a
flashbuild step that invokes avrdude automatically.
Maintained with Zig + MicroZig. Have fun hacking your Arduino-compatible in Zig!