Friday, August 28, 2020

The Aardvark

V-USB, ATmega328P, APA106 experiment

The aardvark is a 3x12 keyboard powered by an ATmega328P. The ATmega328P does not have a built in USB controller. Instead it uses the V-USB software USB library for AVR processors. 


To interface the controller to a USB bus you have to adjust the data lines to communicate at 3.3v levels. There are several methods of accomplishing this listed here. Another method is to use LEDs instead of zener diodes, I used this method on the tiny USB stick I made. The SparkFun AVR stick also uses this method.

On the aardvark I used the 3.6v zener diode method. I also use the same data pin selection as the Metaboard, since I have one and can use it for testing. D+ is connected to PD2 and D- is connected to PD4. The switch to boot into USBASP is connected to PD7. The parts needed are the same as on the Metaboard. The only omission is the 1Mohm resistor, it works fine without that. 

The Metaboard next to another V-USB project I made several years ago.

The V-USB circuit requires:

1    1.5Kohm resistor
2    3.6v 500mw zener diodes
2    68ohm resistors

The PCB has markings with values for each part.

The rest of the board: 

1    500mA or less polyfuse
1    LED for power indication
1    1.5Kohm resistor for LED
1    10Kohm resistor for RESET pullup
2    6mm tactile switches for RESET and USBASP
1    ATmega328P
1    16MHz 3 pin ceramic resonator
1    28pin socket for ATmega328P
36   1n4148 diodes
1    Full size USB or Mini USB socket
1    47mF capacitor
2    100nF bypass capacitors
1    2x3 header for ICSP
3    APA106 5mm RGB LEDs

Full size USB connector. I have lots of these left over from old projects.

Mini USB connector sits inside the footprint the the full size USB connector. That blue thing next to the ATmega328P is the 16MHz ceramic resonator. It has built in capacitors. Ceramic resonators are not as accurate as crystals but are fine for most uses that don't demand extreme precision.


For the bootloader I used the USBaspLoader, same as the Metaboard. This allows flashing firmware while connected through USB. I used the fork available on github

Only two changes need to be made to bootloadercfg.h. Change D- to 4, and jumper to 7.

In the change the DEVICE to atmega328p.

You will need to update the FUSE bits, working settings can be found in the If you use those settings avrdude will probably complain that it is missing bits, that is fine since one of the registers ignores some bits and different programs deal with the missing bits in different ways.

Using a USBTINY programmer the avrdude command to flash the bootloader and set the FUSEs at the same time is:

avrdude -p m328p -c usbtiny -U lfuse:w:0xD7:m -U hfuse:w:0xD0:m -U efuse:w:0xFC:m -U flash:w:bootloader.hex

This firmware will also run on the older ATmega328 (no P). Just remove the 'p'. I have several of these from old Arduino projects. They function identically to 328P but consume more power having been built using a larger die process. They do have a different chip ID so have to be specified when flashing. Otherwise they run code identically.

avrdude -p m328 -c usbtiny -U lfuse:w:0xD7:m -U hfuse:w:0xD0:m -U efuse:w:0xFC:m -U flash:w:bootloader.hex 

With the bootloader installed, if you hold PD7 to ground while you RESET the ATmega328P it will go into USBasp mode for flashing. When PD7 is not held to ground during a RESET it will run the normal firmware instead.

You may need to install a driver for USBasp to be detected. More information can be found on the USBasp site

When in bootloader mode you can flash the keyboard firmware with:

avrdude -p atmega328p -c usbasp -U flash:w:firmware.hex


I used the same ring diode arrangement as on the Germanium. Instead of using the square WS2812B surface mount RGB LEDs, I used 5mm through hole APA106 LEDs. There are several types of these through hole WS2812B compatible LEDs. 5mm, 8mm, with different pinouts.

The APA106 LEDs I use have the pinout shown above.

The LEDs have thick notches on the leads. These get stuck in the tiny holes in the PCB.

I installed a set with the notches. With the donut hole in the diode top it works fine, but looks odd sticking out so high.

I used Peel-A-Way sockets for the diodes. The diodes are soldered with all the cathodes connected to the top donut PCB. The anodes connect to the board. Sockets are optional.

A second PCB is used as the bottom. There are holes for M2 spacers and screws.

If you trim the leads off just above the notches the LEDs will fit flush against the PCB.


TMK supports the ATmega328P via V-USB. It only requires editing the usbconfig.h to set the correct pins and making some changes to the Makefile to define the MCU type and the bootloader size.

You may also need to disable the serial port if it enabled by default.

I also had to modify rgblight.c to use timer 1 instead of timer 3 (the ATmega328P does not have a timer 3). The timer is used to drive the RGB animations.


I made some 3x4 plates for plate mount switches.

Gerber files on git.

Get PCB pricing on PCB Shopper.