Using a Teensy to program a breadboard Arduino

It’s possible to use a bare ATmega328 on a breadboard to act as a minimal and cheap Arduino core. All you need to do it is an existing Arduino board. The catch? I don’t have an Arduino, I have a Teensy.

There’s a solution, and it doesn’t involve anything more complex than the Arduino IDE.

Arduinos are cool things that enable some amazingly productive microcontroller programming, but a) I prefer to work on a breadboard, b) it’s silly that they don’t use native AVR USB, and c) a full-fledged Arduino is a bulky and expensive chunk of hardware to integrate into a permanent project. In response to criticisms (a) and (b), I began my foray into microcontroller programming not with the Arduino hardware proper, but rather with a great little piece of hardware called a Teensy. But point (c) still stands — even the elegant Teensy is around 20 bucks a pop.

Fortunately, a Teensy can be used to program a bare ATmega. We’ll basically follow the steps in the “Minimal Circuit” portion of the ArduinoToBreadboard tutorial, but adapt as needed for our different hardware.

At the time of writing, I’m using the latest versions of Arduino and Teensyduino, 1.0 and 1.06, respectively. My Teensy is a Teensy++ 2.0. If you have a different Teensy, you should check to see whether the pinout differs.

From the ArduinoToBreadboard tutorial, follow the steps to add support for the “ATmega328 on a breadboard (8 MHz internal clock)” board. After setting that up, we can do the rest of it without having to exit the IDE.

Open the “ArduinoISP” example (File > Examples > ArduinoISP). This is what we’ll write to the Teensy to make it act as a programmer to put the Arduino bootloader on the AVR. First, look at that file’s header, which lists the pins associated with SS, MOSI, MISO, and SCLK — 10, 11, 12, and 13 on a true Arduino. On the Teensy they’re a bit different. We don’t need to change them in the ArduinoISP code, because it will reference the correct pin definitions when it’s built for the Teensy. But we do need to connect the right pins of the Teensy to our ATmega. Combining the Teensy’s pinout with the layout in the ArduinoToBreadboard tutorial yields the resulting circuit (click for full-size view):

After the circuit’s ready, let’s make one small change to the ArduinoISP code. Three LEDs are called for, and we’ll skip two of them, but we might as well at least make use of the Teensy’s onboard LED get one of the status indicators. Find the line #define LED_HB 9 and change it to #define LED_HB 6 to match the Teensy’s LED pin. Now make sure the right board (Tools > Board > Teensy++ 2.0) and USB mode (Tools > USB Type > Serial) are selected, and upload the sketch to the Teensy. If the LED “heartbeat” starts blinking, your Teensy is now a programmer, and it’s on to the next step.

Now, without touching the circuit at all, we can move on to putting the Arduino bootloader on the ATmega. Switch the IDE so it targets the ATmega instead of the Teensy: Tools > Board > ATmega328 on a breadboard (8MHz internal clock). Also make sure that the Teensy’s virtual serial port is selected: Tools > Serial Port > /dev/ttyACM0, in my case. We’re ready to burn the bootloader: Tools > Burn Bootloader. The IDE will tell you, honestly, that it may take a minute. When you see “Done burning bootloader,” your ATmega’s now got the brains of an Arduino. Almost there!

The last part of the process is to use the Teensy to upload a sketch to the ATmega. We’ll have to change the Teensy’s operating mode, and rewire its connection to the ATmega. Again, this is analogous to the ArduinoToBreadboard instructions, but with the pins corrected for the Teensy. Instead of an Arduino board sans chip, we’ll use the Teensy as a bridge between its virtual serial port on the PC, and its hardware UART connected to the ATmega. The Teensy’s creator, as part of a different venture, has provided code for using the Teensy in this manner. The Teensy’s UART gets connected to the ATmega’s RX and TX pins, and another pin on the Teensy is used to reset the ATmega. The resulting connection is like so (click for full-size view):

After adjusting your wiring, grab the Teensy_Benito code and open or paste it in a new sketch. Target the Teensy (Tools > Board > Teensy+ 2.0) and upload it. Now the Teensy’s performing the same role as the serial bridge in the real Arduino, and we’re ready for the final step: uploading an Arduino sketch to the ATmega.

Load up the “Hello World” example sketch. Once again set your target for the ATmega: Tools > Board > ATmega328 on a breadboard (8MHz internal clock); Tools > Serial Port > /dev/ttyACM0. Click upload. A few seconds later, your ATmega will be running its first sketch! (I concede that it’s a boring one.) Now go off and do something creative with it!

  • RamblinWreck35

    I just wanted to thank you for this – I have an UNO and a teensy, and since I couldn’t seem to find any luck using the UNO to burn the bootloader for a few chips I’m working on (no optiboot support for UNO as a bootloader), I was getting so frustrated before I found this! I’m working with a regular Teensy, but the pinouts just swap around and it works the same. Molto grazie!!!

  • Robin

    Will it be able to program an ATmega8 micro controller? I hope I’m incorrect about it working only with an ATmega328 and ATmega168, thanks.

  • Twister21

    Hello,
    First of all thanks for posting this method for Teensy.
    But I’m stranded at this point: “Also make sure that the Teensy’s virtual serial port is selected: Tools > Serial Port > /dev/ttyACM0”
    I only have COM23 in that menu (using Windows 7 btw) and I have installed the INF drivers from: http://www.pjrc.com/teensy/usb_serial.html .

    After successfully uploading the ArduinoISP code on my Teensy 2.0 ++ and just using COM23 as a serial port, I get this error when trying to upload the bootloader:
    avrdude: usbdev_open(): did not find any USB device “usb”

    I don’t think the bootloader is necessary because my ATmega328 already came pre bootloaded with UNO firmware (16MHz).
    But after skipping the bootloader part and upload my own code to the ATmega328 after filling my Teensy with the Benitocode, it just sticks at uploading…

    After googleing I haven’t gotten much info about the subject since I’m using Teensy instead of an Arduino. Please help.

  • The Teensy Tutorial 3 will let you test basic serial port communication with the Teensy. Once you have established comms, take note of the port number, which I believe will stay the same after you burn Benito. Generally speaking, if you have burned the Benito code without issue, the Teensy should then be transparent to the Arduino IDE; it’s just functioning as a USB to serial bridge. The answer might even be as simple as unplugging and reconnecting the Teensy from the PC. (And BTW you’re correct that the bootloader isn’t necessary to worry with.)

  • I think these steps will work with an ATmega8 if you edit the boards.txt file you get from ArduinoToBreadboard.
     

  • moto233racer

    Just wondering if there is a reason I can’t use the External 16MHz Clk setup from the Arduino site?

  • That should work great. I like the minimal arrangement where I can get away with it, but if you have a crystal and want to run at 16MHz, the rest of the instructions still apply just fine.

  • EnriqueD

    @dnrce  Could you please post the values for the Atmega8 and Atmega16?
    Thanks!

  • @EnriqueD  @dnrce Not off the top of my head. Look at the boards.txt that comes with the Arduino software, and copy/translate the appropriate section(s) into the version included with ArduinoToBreadboard.

  • EnriqueD

    @dnrce the boards.txt file has many different settings for the same atmega, depending on the arduino board. Im not sure about which one I have to use

  • EnriqueD

    @dnrce The boards.txt file has many different settings for the same atmega, depending on the arduino board. Im not sure about which one I have to use

  • @EnriqueD  @dnrce Neither am I. Start here if you want to understand boards.txt: http://code.google.com/p/arduino/wiki/Platforms
     
    The fuses are the key part of enabling the chip to run standalone.