Arduino microcontroller upgrade

Micro controllers
Vector graphics

My Arduino board is a very old one - it is an Arduino USB v2.0, which comes with a Atmel Atmega8 microcontroller (MCU). Newer Arduino versions use for example Atmega168 or Atmega328p MCUs instead. All three MCUs have them same pins - the 168 and 328 just have more available flash memory (available for program storage), RAM (memory for program execution), and EEPROM (persistent storage).

Atmega8 8 kB 1 kB 512 bytes
Atmega168 16 kB 1 kB 512 bytes
Atmega328 32 kB 2 kB 1 kB

Since the three MCUs all have the same pin outs, it is easy to upgrade an older board to use an ATMega328p instead. To upgrade the board to use an ATMega328p you will need

Step 1: Swapping MCU

Remove the old MCU
Remove the old MCU
Insert a small screw driver between the MCU and the socket. Use the screw driver to gently lift the MCU out of its socket, alternating from side to side to avoid bending the legs. Once the old MCU is out it is time to insert the new one. A brand new MCU will have its legs bent slightly out, which means it won't quite fit into the socket. Gently bend the legs against the desk top until they are facing straight down, and can go into the socket.
IC orientation tab
IC orientation tab
The MCU IC has a small tab on one of its short edges. There is also a small tab in the outline printed on the board around the MCU socket. When placing the new MCU these two tabs should line up. Place the MCU, make sure all legs are in the socket, and press down until the MCU is fully inserted into the socket.

Step 2: Setting the fuses

The fuse bits of a MCU control different aspects of how the MCU should behave (for example, if a bootloader should be used or not). The default fuse settings on a brand new ATmega328p are not quite suitable for use in an Arduino board , and will need to be changed. The fuse settings I use are :
  • efuse: 0x04
  • hfuse: 0xd8
  • lfuse: 0xff
I am not quite sure these are exactly the same as the defaults on a new ATMega328p Arduino, but they work for me. If you need details on what each fuse bit does, please refer to the
ATMega328p datasheet.

stk500 programmer and arduino
stk500 programmer
Connect the programmer to the 2x3 ICSP pins on the Arduino, and issue
avrdude -p ATMEGA328P -P /dev/ttyACM0 -c stk500v2 -t -F -u
to go to the terminal mode of avrdude. Set the efuse (extended), hfuse (high) and lfuse (low) with
write efuse 0 0x04
write hfuse 0 0xd8
write lfuse 0 0xff
After having done this, the new fuse settings can be verified with
dump efuse
dump hfuse
dump lfuse
When you are done, exit avrdude with

Step 3: Upload bootloader

The last step in the upgrade process is to upload the bootloader. Locate the ATmegaBOOT_168_atmega328.hex file (it will be somewhere among the Arduino IDE files, and do
avrdude -c stk500v2 -P /dev/ttyACM0 -F -e -p ATMEGA328P
avrdude -c stk500v2 -F -P /dev/ttyACM0 -U flash:w:ATmegaBOOT_168_atmega328.hex -p ATMEGA328P
to upload.

Uploading the bootloader can also be done in the Arduino IDE. Just make sure to pick the correct programmer and MCU type.

There is also a second thing really old Arduinos lack - a way to trigger reset in software. This is convenient since it removes the need to physically press the reset button prior to transferring a new program to the MCU. This can be done by
connecting one of the serial control signals of the FTDI chip to reset on the MCU. WARNING: This requires a bit of fiddly soldering! This connection between a serial control signal and reset is already done on all but the oldest Arduino versions, so you probably won't have to mess with it.