Free your Arduino code from the Arduino board

Free your Arduino code from the Arduino board

Atmel AVRISP mk II programmer is getting ready to burn some Arduino bootloader code

Atmel AVRISP mk II programmer is getting ready to burn some Arduino bootloader code

Arduino as a system is a great development tool that makes it incredibly easy for a beginner to start programming microcontrollers and for a seasoned programmer to whip up a quick code in a hurry or keep a large embedded project organised when needed. I think it is very valuable for a user-friendly development environment to have a familiar setting to work in: a familiar IDE, set of libraries and a well-known hardware configuration, all of which Arduino provides splendidly.

However, the hardware – the Arduino boards, all 150,000 variations of :) – may not necessarily work very well for every occasion. Depending on your application there may simply be no space for a 2″x2.5″ board. Additionally, there’s always the question of cost: an MCU chip and a couple of extra components that you actually need for the project may not always justify the cost of the whole Arduino board, voltage regulators, LEDs and all of the extra goodness it provides.

I set out to figure out what it’s going to take to create an MCU development environment in which the code could be developed using all the familiar Arduino tools and then transferred to a stand-alone Atmel MCU so the Arduino board could be reused for future projects, along with all the above mentioned savings. My item of particular interest was to make all this work in Ubuntu Linux – my OS of choice for the last 4 years.

The quest has been helped in no small part by Newark – an electronic components distributor – who has generously provided an Atmel AVRISP MKII programmer – an essential tool for moving the code to stand-alone MCU chips. They carry a whole line of MCU development tools for your MCU family of choice and the AVRISP is one of the most economic ways to get you started programming Atmel chips. Check them out!

AVRISP mk II is a great tool because it’s recognised as one of the standard programmer options in the newest version of the Arduino IDE 1.0 If you are not using 1.0, you should really upgrade! Head over to and get yourself the latest release because the previous versions were only setup to upload an Arduino bootloader with an external programmer (AVRISP included) and that limits usefulness of the IDE for writing code for stand-alone Atmel MCUs. Arduino IDE 1.0 is out since November 2011 and some small modifications to your code that would be required if you are coming from older versions, are well documented.

I don’t know if you can say that was to be expected from Atmel, but they provide no instructions for using AVRISP mkII on a Linux system and it should come as no surprise that it won’t simply work with the Arduino IDE right after you plug it in. You need to edit device rules for AVRISP and Steve Karg has described the process in detail. I did a little modification of the names used.

1. Create a new file called /etc/udev/avrisp.rules with this content:

SUBSYSTEM!="usb_device", ACTION!="add", GOTO="avrisp_end"

# Atmel Corp. JTAG ICE mkII
ATTR{idVendor}=="03eb", SYSFS{idProduct}=="2103", MODE="660", GROUP="dialout"
# Atmel Corp. AVRISP mkII
ATTR{idVendor}=="03eb", SYSFS{idProduct}=="2104", MODE="660", GROUP="dialout"
# Atmel Corp. Dragon
ATTR{idVendor}=="03eb", SYSFS{idProduct}=="2107", MODE="660", GROUP="dialout"


My own AVRISP had product ID 2104 but I have seen two more versions mentioned so this code above should cover different versions of the programmer.
2. Run


to make sure you’ll have permissions to access the device as a member of the “dialout” group. You should see both your user name and “dialout” listed in the output.
3. Add a link to the rules file to the init.d directory so it would get initiated on udev startup

$ cd /etc/udev/rules.d
$ sudo ln ../avrisp.rules 60-avrisp.rules

4. Restart udev

sudo service udev restart

5. If AVRISP mk II was plugged in, unplug and plug it back in.

Voilà! You now have a working AVRISP mk II programmer on a Linux Ubuntu computer. The easiest and the fastest thing you can do with it now is to burn yourself an extra Atmega328 chip with an Arduino bootloader. There is a menu item under Tools just for that. Make sure you have Arduino Duemilanove w/Atmega328 selected as the board and AVRISP mkII as the programmer.

After than connect AVRISP mkII to the Arduino board’s ICSP header (the red stripe connects to pin 1) as shown in the beginning of this post and make sure to also power the Arduino board separately from the programmer either via a USB connection or an external power supply. After all preparations are complete, go to Tools->Burn Bootleader and observe the LED on the programmer blink and change colors for approximately 15 seconds.

This also works well if you had your Arduino shipped with Atmega168 chip and want to upgrade it to Atmega328. No reason to buy a whole new board – just buy an Atmega328 chip and burn a new bootleader into it.

When the process has been completed, you will have yourself an Arduino clone which can be plugged directly into a breadboard (I’ve seen it referred to as Breadboarduino :)) Note that a bare Atmega328 chip would be lacking the USB connectivity. You would have to provide an USB-TTL adapter, not unlike those used for Seagate HDD repairs. Nokia CA-42 is one of the most often cited and cheapest devices like that and similar devices go for anything between $2 and $10 on eBay. But if you loaded a sketch before pulling the Atmega328 chip from the Arduino board, it will be running the sketch on the breadboard and you may no even need the USB connectivity.

This just barely scratches the surface of what’s available once you get your hands on a programmer for the Atmel chips (and, BTW, Arduino itself could be converted into one). Some of the most exciting applications involve shrinking the Arduino project in size even further beyond just elimination of the board by loading the code onto MCUs with smaller pin counts, all the way down to ATTiny85,45 and even, with some limitations, ATTiny13 chips. There’s more involved in using the smaller chips here, so I’ll leave that for a future post.

14 Responses to “Free your Arduino code from the Arduino board”

  •  Just testing a new commenting system …

  • Carman:

    eLABZ:Thank you for your helpful post, however after following your step by step instructions, I get:—————
    avrdude: ERROR: address 0x10010 out of range at line 66 of hardware/Sanguino/bootloaders/atmega644p/ATmegaBOOT_644.hex
    avrdude: read from file ‘hardware/Sanguino/bootloaders/atmega644p/ATmegaBOOT_644.hex’ failed————–after trying to burn the Sanguino bootloader. Any advice?~Carman

    •  Carman,

      make sure you selected the proper board (see the sample attached here) and if you did pick the  right board, verify the names and locations in the boards.txt file . See if you can get some useful info from another post I did recently: It’s about a different chip but has the sample boards.txt format and the proper file locations.

      Also, it’s helpful to know the Arduino IDE versions because they do behave somewhat differently. Have you switched to the newest V1.0 ?

      Thanks for stopping by my site!

  • Carman:

    Thank you for your prompt response!

    I am using Arduino version 0022ubuntu0.1.

    Your link:  ( ) was very helpful for understanding the boot loader setup.  I was able to verify that I was using the correct boards.txt by moving the atmega644p directory and receiving a missing file error.

    The part of the error says:

    address 0x10010 out of range at line 66 of hardware/Sanguino/bootloaders/atmega644p/ATmegaBOOT_644.hex

    I checked ATmegaBOOT_644.hex line 66 and it is as follows:

    <– line 66

    If I understand Intel Hex files correctly, isn't line 66 referring to address 0x0000 to 0x000F?
    If so, why would the error refer to address 0x10010?

    I would appreciate any light you are able to shed on with this issue!

    Thank you,

    • Hello again, Carman!

      I have to admit I never delved into compiled bootloaders before. In fact, I find myself programming individual chips without a bootloader lately (using a dedicate programmer device of course).

      Anyhow, judging by the error you’re getting, it looks like the avrdude programming software does a check of the memory available on the target chip and throws an error because you’re trying to write something into the block of memory that does not exists. At least avrdude thinks it does not. It thinks the chip you’re writing to has only 64KB of flash program memory and you’re trying to write to just above that.

      So, are you burning a bootloader  to a Sanguino board? I heard a lot about it but never worked with one. Does it have only one version and uses atmega644p ? Atmega644p “only” has 64KB flash, so I am not sure why a bootloader compiled for the chip would need to address memory above what’s available. There’s also 2KB of EEPROM on it, maybe there’s a way to describe and address both blocks as one contiguous 66KB block? I don’t know – it is purely a conjecture on my part.

      Anyhow, it kinda sorta feels like you have Atmega1280p and  Atmega644p crossed somewhere in your configs. Also, a quick stop at the sanguino site ( reveals an interesting tidbit about the latest bootloader (sanguino-0023r3, dated Feb-19-2012):

      Do not have a 644p to test with, but hopefully fixed the issue with the .hex
      Tested Arduino IDE upload of bootloader for 1284p in both 8mhz and 16mhz, upload of sketch and verified correct timing of blink.

      So, maybe it is not supposed to work on Atmega644P after all? Maybe you should roll a couple of versions back to get a stable 644 bootloader?

      Good luck with sorting that out!

  • JC:


    I’m trying exactly the same; but still getting the same error…
    avrdude: usbdev_open(): did not find any USB device “usb”

    It there a way to verify what is working and what not?
    When connecting the Arduino board a USB port is added. Pluging in the AVRISP nothing happens – just a yellow light on the AVRISP ;-)

    Any ideas? That would be great!

    Jan Christian

    • JC, have you added the udev rules for AVRISP? Also, did you make sure your user is a part of the “dialout” and “plugdev” (Ubuntu 12.04+) groups? What’s the output of the dmesg command?

      Also, I’m finding that using blog comments for helping people with issues has its severe limitations – after awhile it gets hard to see who answers to whom and what’s being addressed. Could you please start a topic about your issue in the forums where I have just created a new board especially for Atmel and Aruino – where we can have an actual discussion, proper formatting and all other perks of a forum as opposed to a blog comment form.

      Cheers and thanks for stopping by my blog!

      • JC:

        Hi, I think I’m in the right group. These are the last comments from dmesg. First when pluging in. Second when trying to send a command.

        [ 4885.796053] usb 5-3: new full-speed USB device number 4 using ohci_hcd
        [ 4927.820969] usb 5-3: usbfs: USBDEVFS_CONTROL failed cmd avrdude rqt 128 rq 6 len 255 ret -110
        [ 4928.820521] usb 5-3: usbfs: USBDEVFS_CONTROL failed cmd avrdude rqt 128 rq 6 len 255 ret -110

        I will describe it more detailed on your new page and will also include rules file and group settings.

        Thanks, JC

  • [...] is a quick follow up on an eariler post describing installation of Atmel AVRISP MKII programmer on a Ubuntu Linux computer. The original post was based on Ubuntu 10.10 and several small changes have sneaked up on us during [...]

  • Zee:

    $ sudo ln ../avrisp.rules 60-avrisp.rules

    And the terminal’s reply:

    ln: accessing `avrisp.rules': No such file or directory


  • Rob:

    I had the same issue in Ubuntu 14.04. I found I had to make a few small adjustments to the above approach to make it work.
    1. the /etc/rule.d directory has a README indicating that you can’t put linked files there and expect the udev system to pick them up. You have to place the new rules file there directly.
    2. The SYSFS{idProduct} keyword had to be changed to ATTR{idProduct}

    begin avarisp.rules example
    SUBSYSTEM!=”usb_device”, ACTION!=”add”, GOTO=”avrisp_end”

    # Atmel Corp. JTAG ICE mkII
    ATTR{idVendor}==”03eb”, ATTR{idProduct}==”2103″, MODE=”660″, GROUP=”dialout”
    # Atmel Corp. AVRISP mkII
    ATTR{idVendor}==”03eb”, ATTR{idProduct}==”2104″, MODE=”660″, GROUP=”dialout”
    # Atmel Corp. Dragon
    ATTR{idVendor}==”03eb”, ATTR{idProduct}==”2107″, MODE=”660″, GROUP=”dialout”

    end avrisp.rule example

    After those small changes, the AVRISPMKII worked for me as well.

    Thanks for a great set of instructions!

Leave a Reply

Or use the Forums ! If your comment is a question, please consider posting it to a matching section of our Electronics Forums. The forums allow for a more natural conversation flow, especially if multiple replies are required. Additionally, you'll be able to style your writing (bold font, italics etc.) and post images which can help with a good answer.

Notify me of followup comments via e-mail. You can also subscribe without commenting.


Coming soon ...

Recent Comments
  • CHAARI: need an eagle file for the control of a stepper motor with easy drive or a microstepping driver
  • admin: Awesome! Thank you very much for sharing, Dani!
  • Dani: Here is my version, not perfect but I learned a lot.
  • Dani: Thanks for your reply! :)
  • Andreas Carmblad: Thanks for answer :) I use easydriver yes. The problem is solved though. I thought I was supposed...
  • admin: Hi Andreas, You did not specify which stepper motor controller you are using and it is an important bit of...
  • Andreas Carmblad: I would really need some help with this. I can’t get it to work. The axel of the motor is...
  • jordan: whoops just realised the error in my previous post, 250mW is the output but has nothing to do with the input...
  • jordan: hi, i managed to get my hands on two laser diodes and was a little too eager with the first one (it blew out)...
  • admin: I think you are correct, LinuxCNC should be able to control it using a more widely available CNC servo...