Skip to content
No description, website, or topics provided.
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.

Debugging Arduino Uno with opensource toolchain


set img

Arduino with an AVR8 microcontroller can be debugged with debugWIRE. This is often done with a debugger from Atmel and Avr Studio.

I found the dwire-debug project which contains an opensource implementation of debugging probe and server.

On computer side, Visual Studio Code is capable to debug ARM based Arduino, here I will also share how to setup VScode for debugging Uno.

The dwire project can use an FT232 or CH340 as debugging probe. However, debugWIRE may require changing fuses occasionally. So I used an Attiny85 both as ISP programmer and debugger.

Note: At Nov 12 2018, the PR hasn't been merged into master, optimized firmware and debug server can be found in this branch.

Hardware I used


Here I used a Digispark board as debugging probe with dwire-debug's firmware. I used an Arduino Mini Pro as the target. Arduino Mini Pro shares the same core hardware with Uno. Since I'm going to disable bootloader, there will be no different on the software side.

One advantage of mini pro is the absence of serial downloader. If you are using an Uno board, you may need to cut the RESET-EN trace to avoid interference with the serial downloader.

Step 1, convert Digispark to debugging probe

Choose one method below.

without bootloader

original fuse

This step requires updating firmware and fuse, so find your favourite ISP programmer. Be careful in this step as we are going to disable reset pin of Digispark. If you don't have a high-voltage programmer, you won't be able to program it anymore.

My Digispark comes with E1 DD FF fuses. You should check if yours has the same fuse (unless you know how fuses work).

Get firmware from dwire-debug's firmware, erase your attiny85, program and verify firmware.

Double check if everything is correct.

Now change the high fuse to 5D (RSTDISBL programmed). If you did everything correctly, your Digispark should be functional now.

with bootloader

With a bootloader, you don't need a high voltage programmer to update the firmware. However, if your bootloader got damaged or you want to change the fuse, you still need a high voltage programmer.

I used micronucleus bootloader. You can get the hex file from here.

Before programming bootloader, use ISP programmer to set fuses correctly. I used C1 DD FE fuses. Make sure you checked SELFPRGEN.

bootloader fuse

Then you use the command-line tool in micronucleus's repo to upload the dwire-debug's firmware.

If you do it correctly, everytime you plug in the ATtiny85 board, it will appear as a Vendor-Specific Device with PID:0x0753 & VID:0x16d0. If you don't upload firmware, it will automatically become USBtinySPI with PID:0x0c9f & VID:0x1781 after 6 seconds.

After you confirm your bootloader is working, set fuse RSTDISBL with the ISP programmer.

bootloader fuse

Step 2, prepare dwire-debug

I did some improvement on dwire-debug and created a release here.

If you are using Mac, you can download binary, add execute permission with chmod +x dwdebug, install libusb with brew install libusb libusb-compat .

If you are using Windows, you need to use libusb-win32 driver for ATtiny85. Refer to Readme of dwire-debug repo for more info.​

For other OS, try to compile the source in the release.

Step 3, reprogram fuse on ATmega328p

Connect all wires and USB cable. run the following command in terminal to read fuse. If the avrdude on your computer locates in a different location, change the path accordingly.

/Users/sundeqing/Library/Arduino15/packages/arduino/tools/avrdude/6.3.0-arduino9/bin/avrdude -C/Users/sundeqing/Library/Arduino15/packages/arduino/tools/avrdude/6.3.0-arduino9/etc/avrdude.conf -patmega328p -cusbtiny

read fuse

Check if the signature and fuses are read correctly.

If so, program new fuse values to enable debugWIRE and disable bootloader.

/Users/sundeqing/Library/Arduino15/packages/arduino/tools/avrdude/6.3.0-arduino9/bin/avrdude -C/Users/sundeqing/Library/Arduino15/packages/arduino/tools/avrdude/6.3.0-arduino9/etc/avrdude.conf -patmega328p -cusbtiny -U lfuse:w:0xEF:m -U hfuse:w:0x9B:m -U efuse:w:0xFD:m

write fuse

Power cycle your board to make fuse change take effect.

Step 4, check if dwire-debug is functional

In terminal, swtich to dwdebug's location and run ./dwdebug device usbtiny1. Check if ATmega328p can be connected. If so, press Control+C to terminate dwdebug.

check debug

Step 5, install VScode and Arduino extension.

First download VScode from

download VScode

Enable extensions side bar.

Enable extensions

Look for Arduino extension (the offical one from Microsoft, not a random person) and install it.

Install Arduino

Then you install Arduino extension.

Click reload after you finish install.

reload Arduino

Step 6, Add support for debugWIRE No longer needed after This PR has been merged

Quit Vscode (not close the window)

reload Arduino

In Mac, open finder, Click "Go"->"Go to Folder"


Open extension folder (you can copy & paste):

OS Path
Windows %USERPROFILE%.vscode\extensions
macOS ~/.vscode/extensions
Linux ~/.vscode/extensions

Paste path


Then you will arrive extension folder

extension Folder

Go into the Arduino extension folder (vsciot-vscode.vscode-arduino-0.2.22 at this moment) -> "misc", you will find debuggerUsbMapping.json and usbmapping.json file.

extension Folder

Refering to this commit, add support of USBtinySPI and Uno into debuggerUsbMapping.json and usbmapping.json

Step 7, load Blink Example

This repo contains a configured example. In VScode, open folder BlinkUno in this repo.

Change miDebuggerPath and debugServerPath launch.json. Make sure they are pointing to the correct files.

Add breakpoints and you can start debugging the code.

debug blink

Also tested on windows.

debug blink

If debug server can not start, it may be caused by exiting debug while code is running. Kill running dwdebug will fix it.

Step 8, disable debugWIRE and leave target for normal use

Exit any debugging session.

In terminal, swtich to dwdebug's location and run ./dwdebug device usbtiny1. Type qi to quit debugWIRE

quit debugwire

Then program fuse back with /Users/sundeqing/Library/Arduino15/packages/arduino/tools/avrdude/6.3.0-arduino9/bin/avrdude -C/Users/sundeqing/Library/Arduino15/packages/arduino/tools/avrdude/6.3.0-arduino9/etc/avrdude.conf -patmega328p -cusbtiny -U lfuse:w:0xFF:m -U hfuse:w:0xDA:m -U efuse:w:0xFD:m

set fuse back

Then you can burn bootloader back and reuse the board as before.

You can’t perform that action at this time.