Pi AVR Programmer HAT Hookup Guide

Contributors: QCPete
Favorited Favorite 4

Closer Look at Repository Files

There are a lot of files in the GitHub repository for this project.

However, you don't actually need all of them to get up and running. There are quite a few that are extra examples and will show you some more of the advanced features of this programmer. Let's take a closer look at the most important ones.


The test.py is the Python module that handles all of the operations of the Pi AVR Programmer HAT. It is launched at bootup from inside rc.local. Once it is up and running, it blinks the "STAT" LED to show that it is alive. It then listens to the capsense pad, finds your firmware hex file, engages programming, parses output from avrdude, and ultimately blinks status LEDs.

It also has some functionality to watch for media drives and pull in any new hex files that live on them. This is an easy way to update your programming hex file on your Pi, but beware, it will overwrite your existing hex file, so be careful. It's usually a good idea to stop test.py before plugging in any thumbdrives (until you're absolutely sure you want test.py to pull in the hex file). To stop test.py (and any other background Python modules), simply use this command:

sudo killall python

It's also not a bad idea to back up your hex files elsewhere (outside of /home/pi).


The pi_program.sh shell file contains the actual programming calls to avrdude. Test.py launches this shell to engage programming. It is very similar to the types of programming we do in SparkFun production. It allows you to adjust some variables at the top for device and fuse bits. Fuse bits can be a little tricky. If you need to adjust these and want some help, please check out our fuse bits tutorial.

# Here are some commonly used "part no"s in avrdude at SFE
# UN-comment the one you wish to use, or plug in something different
# Use "avrdude -p?" for a list of supported devices

EXT_FUSE=0xFD # due to masking, 0x05 = 0xFD, 0x07 = 0xFF, ***Note on an ATMEGA2560, ext fuse writes and verifies as 0xFD
LOCK=0x0F # due to masking, 0x0F = 0xCF

Note that it also has a nice little trick at the top to search for a hex file within /home/pi and use that for programming.

# get firmware file name
firmware=$(find /home/pi/*.hex)
$firmware .= "/home/pi/$firmware"

Beware, that if you have two hex files in this directory, it will use the first one it finds. You can modify pi_program.sh to call a specific hex file by changing the $firmware variable.

The last thing to note about this file is the manual GPIO control in the middle of calls. In between fuse bits programming and flashing of the hex, there is a manual flip of the GPIO controlling the reset line. After using this programmer for thousands of programming cycles, we found that in order to truly reset the target in between calls to avrdude, a more reliable approach is to quickly toggle that GPIO from the shell file. Without this, the second call to avrdude can occasionally fail to reset the target. But with this toggle, we've had 100% success!

sudo gpio -g mode 26 output
sudo gpio -g write 26 0
sleep 0.1
sudo gpio -g write 26 1
sleep 0.1


The provided avrdude_gpio.conf configuration file is very similar to the default configuration file. The only modification necessary is adding in the linuxspi programmer definition (Note that this also defines your RESET pin). On the Pi AVR Programmer HAT, we have this hard wired to GPIO PIN 26. If you are working from a different .conf file, then this little block of text below needs to be added to the very bottom of the avrdude.conf file.

  id = "linuxspi";
  desc = "Use the Linux SPI device in /dev/spidev*";
  type = "linuxspi";
  reset = 26;


The provided rc.local file is very similar to the default rc.local file you get with most raspberry Pis. This file runs at bootup, so it is handy if you'd like to have some commands run every time you power up your Pi (very useful if you plan to run it headless). The only addtional command added to the default rc.local is as follows. It simply calls Python to launch our test.py module.

python /home/pi/test.py &

Note the "&" is very important here. It allows your Pi to continue on and run the GUI. If it wasn't there, then your Pi would just wake up and run the Python module, and then do nothing else, this is dangerous, because you wouldn't be able to modify your Pi from here on out. It's kind of like "bricking" your Pi, so please don't forget that very important "&".