Open-source firmware for the ErgoDox keyboard, modernized and optimized for the Adafruit ItsyBitsy 32u4 (5V 16 MHz).
The v3 update combines Asymmetric Eager Per-Key debouncing with a custom Baremetal I2C Library, pushing the hardware to its absolute limits:
| Metric | Legacy (Defer) | v3 (Asym Eager + I2C) | Improvement |
|---|---|---|---|
| Loop Time | 6.5 ms | ~1.5 ms (Real) | 77% faster processing |
| Scan Rate | 154 Hz | ~660 Hz (Real) | 4.2x increase |
| I2C Efficiency | Standard TWI | Baremetal + R/W | 50% less overhead |
| Flash Usage | ~24 KB | ~16 KB | 33% reduction (LTO) |
| Layout Storage | 3 matrices | 1 unified matrix | 66% reduction |
| Input Latency | 6.5 ms | < 2 ms | 4.5 ms reduction |
- Asymmetric Eager Debouncing: Reports key presses immediately (0ms delay) while deferring release to filter noise. This is the new system default.
- Optimized I2C Transactions: Uses Repeated Starts and Sequential Reads to minimize the overhead when scanning the MCP23018 I/O expander.
- High-Speed TWI: Native support for 400 kHz and 800 kHz I2C clock speeds, further reducing matrix update time.
- Simulation Benchmarking: Continuous performance tracking via
avr8jssimulation, ensuring stable loop timing and zero matrix errors. (Note: Simulation scan rates of ~146 Hz reflect conservative I2C modeling; real hardware typically reaches 600+ Hz).
- Tap-Hold / Dual-Role Keys: Use
LT(layer, kc)andMT(mod, kc)to act as a modifier/layer when held and a regular key when tapped. - Mouse Keys: Integrated support for controlling mouse cursor and buttons directly from keyboard layers.
- I2C/TWI Error Recovery: Robust bus recovery and MCP23018 reset logic, allowing the keyboard to remain partially functional (left hand) during bus failures.
- N-Key Rollover (NKRO): Simultaneous keypress tracking with full BIOS compatibility.
- Baremetal I2C Implementation: Custom, lightweight TWI library replacing standard AVR TWI for reduced code size and improved reliability.
- Streamlined USB HID Stack: Optimized specifically for the ATmega32U4, reducing overhead and improving latency.
- Flexible Customization: Firmware-level layers and macros with modern AVR toolchain support (C17, LTO, atomic operations).
- Macros: Support for sending complex keycode sequences with a single press, using an indexed macro table.
- 16-bit Keycode Architecture: Expanded keycode range to support macro identifiers and future feature extensions.
- Low-Level Simulation (avr8js): Comprehensive hardware-level simulation verifying matrix scanning (Direct & I2C), debouncing, and EEPROM persistence without physical hardware.
To build, test, and flash this firmware, you will need the AVR toolchain, Node.js, and avrdude.
- macOS (Homebrew):
brew tap osx-cross/avr brew install avr-gcc avrdude make node
- Windows (winget):
winget install ZakKemble.avr-gcc ezwinports.make OpenJS.NodeJS.LTS AVRDudes.AVRDUDE
- Linux (Fedora):
sudo dnf install avr-gcc avr-binutils avr-libc make nodejs avrdude
- Linux (Ubuntu/Debian):
sudo apt install gcc-avr avr-libc make nodejs avrdude
All build commands should be executed within the src directory.
- Standard Firmware: Build the production
.hexfile for the ItsyBitsy 32u4.cd src make - Simulation Firmware: Build a specialized version for the
avr8jssimulation.cd src make simulation - Clean: Remove all build artifacts.
cd src make clean
The firmware includes a dual-layered testing suite:
Verifies core algorithms (debouncing, layer switching, keycode processing) without needing an AVR environment.
# From project root
make -C tests run_testsFull ATmega32u4 + MCP23018 simulation verifying matrix scanning, I2C logic, and HID behavior.
# From project root
cd src && make simulation
cd ../tests/simulation && npm install # Only needed the first time
npm testTo flash the firmware to your Adafruit ItsyBitsy 32u4:
- Connect your ItsyBitsy 32u4 to your computer via USB.
- Enter Bootloader Mode: Quickly double-press the Reset button on the ItsyBitsy. The red LED should start pulsing.
- Identify the Serial Port:
- Windows:
COM3,COM4, etc. Check Device Manager under "Ports (COM & LPT)". - macOS:
/dev/cu.usbmodem* - Linux:
/dev/ttyACM*
- Windows:
- Flash: Use
avrdudeto upload thefirmware.hexfile.# Replace [PORT] with your actual device path avrdude -v -p atmega32u4 -c avr109 -P [PORT] -b 57600 -U flash:w:src/firmware.hex:i
The documentation has been reorganized into clear sections for easier navigation.
- Keymap Customization — How to define your own layout.
- Architecture Overview — How layers, matrix scanning, and USB handling work.
- NKRO Implementation — The technical details behind our N-Key Rollover.
- Scan Rate & Debouncing — Detailed calculations and the Eager Debounce algorithm.
- Hardware Reference — Detailed specs and pinout for the controller.
- Testing Strategy — Detailed breakdown of our testing methods.
- Simulation vs. Hardware — Understanding the role of
avr8js. - Wokwi & Velxio Integration — How to use visual simulation for debugging.
- Issues & Features: Tracked on GitHub Issues.
- Official Project: ergodox.io