Introduction: Cheap, One Chip Arduino

This Instructable will show you how to build an Arduino using only an ATMEGA328P IC. If you are new to embedded systems, you will find all the steps needed to do this explained completely and clearly. Along the way, you will learn how to unbrick a previously programmed 328P and how to hook up a usb to serial interface. As a final result, you will be able to use the Arduino you create to create another.

Why another Instructable on creating an Arduino on a breadboard (that is, using just an ATMEGA328P chip)? The reason is simple: when I tried to do it, I found lots of gaps in the documentation that I had to fill in myself. Since I'm an experienced embedded systems engineer, I thought I'd share what I learned to help those with less experience. My target audience is the young person, or newcomer, eager to build a cheap Arduino and start experimenting. So very little of the material in this Instructable is new, I just pull it together here and make sure all the steps are explained.

Before you begin, you should understand how to use a solderless breadboard, be able to recognize a resistor and capacitor, and be familiar with the Arduino programming environment. (I'm using version 1.6.7 and I recommend you use the same.) Having basic soldering skills is helpful, but not at all required if you have a friend who can do a bit of soldering. If there is a hacker space near you (such as this one), you can get help and training there if you need it. Your local library or school might also offer training and help. Here are some links to help you if you are truly a total beginner.

Solderless breadboard: How to Use a Breadboard

Basic Electronics: Basic Electronics Instructable

Beginning Arduino: Beginning Arduino Instructable, How to Install the Arduino Programming Environment

Basic Soldering: Soldering Guide

Electronic components may be obtained from Digikey, or other sources. Digikey part numbers are provided. Atmel ATMEGA328P microcomputer ATMEGA328P-PU-ND

100nF (0.1uF) capacitors - 2 required BC2665CT-ND

10K resistor CF14JT10K0CT-ND

If you want to blink an LED, you'll need these parts as well. Pick your favorite color for the LED. I provide two part numbers, but there are zillions to choose from. The resistor can be pretty much any value from 330 Ohm to 1K Ohm.

470 Ohm resistor CF14JT470RCT-ND

Blue LED C503B-BCN-CV0Z0461-ND

Amber LED C503B-ABN-CW0Z0251-ND

You'll also need 22 gauge, solid not stranded, jumper wire to connect parts on your breadboard. Whoever you're working with is likely to have this. But if you plan to experiment with your Arduino, you'll want your own supply. You can get a nice assortment from Sparkfun. Here's the part number.

Your friends, a local hacker space, library, or school can help with these.

  • Access to an Arduino (you need one to program your first part)
  • A USB to serial interface (such as an FTDI board - but lots of others will work)
  • A pair of wire cutters and a pair of wire strippers to make jumper wires.
  • A solderless breadboard - borrow one or buy your own.

An Arduino "sketch" is simply a "program". I will use both terms to mean the same thing: the code that you will put into your Arduino to make it do stuff.

The process of putting code into your Arduino is known as "loading", "uploading", or "burning". I will use the terms interchangably.

I will often use "cap" for "capacitor".

A note on quotes is in order also. I will use quotes around terms when it seems to aid clarity. Unless noted otherwise, these quotes are not part of the term and should not be entered.

The version of Arduino we will create is "ATMEGA328 on a breadboard (8MHz internal clock)", or at least that's the menu entry for it in the Arduino Tools -> Board menu. For the purposes of this Instructable, I will refer to it as "328/Duino" - a more terse, but still descriptive term.

Beyond the fun of creating this, what use does it have? That is, can it be used instead of an Arduino? Obviously, you can do experiements on a breadboard just like with an ordinary Arduino, and save a little money. When does the 328/Duino really benefit you? The 328/Duino is especially useful if you have a project that doesn't need to be connected to your PC via USB all the time. For example, if you want to collect data from a sensor (such as temperature or GPS position) and log it to an SD card for later analysis, then not only will the 328/Duino be a cheaper solution, it is also much more compact than a regular Arduino. In other words, the 328/Duino can allow you to economically use Arduino applications in many areas without requiring a full Arduino board. Even if you need continuous USB communication, there are very cheap serial interface boards available (besides the FTDI boards). Using one of these is discussed in Step 7.


Fritzing was used for the circuit diagrams in this Instructable.

Screen captures were done using Irfanview.

The Secret Decode Ring is from Note that the pinout for the 328P is identical to that for the 168, so this diagram works fine for us.

Step 1: Breadboard Setup

Let's get started!

Inserting the 328P into your breadboard: To insert the 328P into your breadboard, you must bend the pins carefully so they line up with holes in the breadboard. The first picture shows how the pins on a new 328P often poke out at a slight angle and don't perfectly align with the holes in a breadboard. The second picture shows how the pins should be. They have to be bent slightly to line up. To do this, grip the chip by the edges, then place one set of pins against a hard surface and rock the chip forward to bend the pins slightly. The third and fourth pictures should give you the idea of how to do this. Repeat for the pins on the other side. Be careful so you don't bend them too far. Press the chip firmly but carefully into the breadboard. The part should go easily into the breadboard. It's all easier than it sounds, but a bit daunting the first time you do it.

The notch on the 328P package indicates Pin 1. With the notch facing your left, pin 1 is the first pin on the left closest to your body. The figure titled "Atmega 168 Pin Mapping" shows the physical pins of the 328P (same as 168) and the corresponding pins in the Arduino programming environment. I refer to this figure as the "Secret Decoder Ring". You will find yourself referring to it frequently. The diagrams and instructions to follow assume the inner red row of the breadboard is Vcc (+5 volts) and the inner blue row is Gnd (Ground or zero volts). The outer rows are not used.

Connect pins 8 and 22 of the 328P chip to Gnd; 7 and 20 to Vcc. Place a 0.1uF (100 nF) capacitor across 7 and 22.

Step 2: Connect the Arduino

The Uno, or similar ATMEGA328P-based Arduino running at 5 Volts is strongly suggested for this process. If you use another type Arduino, you must determine where MOSI, MISO and SCK are, and identify a digital pin for Reset to your target. If you have a 3.3V Arduino, then make sure your target (the part you are programming) runs at 3.3V also. Don't connect 5V to any part of the system! Better to avoid all these gotchas and just use an Uno.

An Arduino Uno R3 is used as our programmer.

Hook up:

Arduino Pin <_> 328P Pin <-> Purpose

10 <--------------------> 1 <----------> Reset

11 <--------------------> 17 <----------> MOSI

12 <--------------------> 18<---------->MISO

13 <--------------------> 19 <----------> SCK

5V <--------------------> Vcc Row on Breadboard

Gnd <--------------------> Gnd Row on Breadboard

See diagram.

Step 3: Install 328/Duino Software

Browse to and scroll down to the section entitled "Minimal Circuit (Eliminating the External Clock)". Click the link in Step 1 of that page labeled "" to download it. You may follow their steps 2 and 3, or you can just locate the Arduino-1.6.7/Hardware folder and move the breadboard folder from the zip archive into that folder (see picture). Close Arduino if it is open and reopen it. If you select Tools -> Board you should see "ATMEGA328 on a breadboard (8MHz internal clock)" in the drop down menu (see picture). Don't select that Board yet, however. That happens in Step 5.

Step 4: Turn Your Arduino Into an In-System Programmer

Turn your Arduino into an in-circuit programmer (ISP) by selecting your Arduino board (Uno in this example) from the Tools -> Board drop down, then select File -> Examples -> 11. ArduinoISP -> ArduinoISP.

Be sure "AVRISP mkII" is selected from Tools -> Programmer.

Upload the sketch to your Uno. It is now an ISP!

Unless you are well experienced with Arduinos, I suggest you ignore the comments at the start of the ArduinoISP sketch - they can be very confusing! As long as you are using an Uno, this program will work just fine as it is. The one detail of interest is that pins 7, 8, and 9 are configured to drive leds: 7 blinks during communication to the target, 8 lights if an error occurs, and 9 is a heartbeat that pulse while the program is running. LEDs may be connected via the usual resistors to these pins, but are not at all required.

Step 5: Burn the Bootloader to the 328P

Your 328P was connected to the Uno in Step 2, so you're all ready to go. We now want to target the 328P. Go to Tools -> Board and select "ATMEGA328 on a breadboard (8MHz internal clock)".

From Tools -> Programmer, select "Arduino as ISP". DO NOT confuse this with "ArduinoISP"!! They are not the same.

Double check your settings and select Tools -> Burn Bootloader.

You should get a satisfying message from avrdude. (The "avrdude" is the programming software used by Arduino.)

Step 6: "My Chip Won't Program!"

If you get the message "Error while burning bootloader", even after double checking all your connections and trying again, you are probably pretty frustrated. Never fear! The common symptom here is that the chip ID is read as 0000. Sometimes, verification fails. Usually, if either of these two conditions happen, it means that your 328P chip has been programmed already and configured for an external clock. This can be the case with "new" 328P chips. Some vendors helpfully program them for use in Arduino Unos, which require an external clock. Fortunately, it's not difficult to recover the chip and program it to use its internal 8MHz clock. What is necessary is to provide a clock to the chip while it is being programmed. Since we are using an Arduino already as the programmer, we will just program the Arduino to also put out the required clock.

There is more than one way to create the necessary clock, but I'm only going to detail one of them. As mentioned in Step 4, Arduino pin 9, which has PWM capability, is configured to be a "heart beat" when the ArduinoISP program is loaded and running. Nice, but hardly necessary. We'll modify the ISP program to use pin 9 as a clock source. We want a 500KHz pulse rate*, 50% duty cycle clock signal and will use the TimerOne library to create it. Note that we must use the TimerOne library so we can set the frequency as well as the duty cycle of the PWM.

The instructions that follow are mostly illustrated in the screenshots above (except for stuff done in earlier steps or otherwise obvious - post a comment if anything is not clear). Refer to them if you get confused.

To download the TimerOne library, go to Sketch -> Include Library -> Manage Libraries...

Enter "Timer One" in the "Filter your search" box.

The TimerOne library should be listed. Select it and click Install; then close the window when done.

The TimerOne library is now ready to use, you don't even need to restart Arduino.

Now let's create a custom version of the ArduinoISP that uses TimerOne to make a clock signal on Arduino pin 9. This might seem scary if you're new to Arduino, but it's not hard and I'll walk you through all the steps.

Use File -> Examples -> 11. ArduinoISP -> ArduinoISP to get the ArduinoISP program to modify.

Use File -> Save as to save your new version. Call it "AruinoISPClock" or some other meaningful name. To use it in the future, load it from your sketchbook.

Right after the header block, find the line "#include "Arduino.h" and add the line "#include ". (Remember: No quotes!)

Find "void setup() {".

Just after "SERIAL.begin(BAUDRATE);" insert these two lines:

Timer1.initialize(2); // 2 us = 500 kHz

Timer1.pwm(9,512); // 50% duty cycle, output on Arduino Pin 9

Comment out the lines that reference LED_HB.

A little further down, find the section that defines the heartbeat and comment out that function. (I used "/*" and "*/" to comment out the block.)

Find loop() and the call to heartbeat(). Comment out the call to heartbeat().

File -> Save to save your work and it's ready to test.

To burn this code into your Uno, select your Arduino board (Uno in this example) from the Tools -> Board drop down. Be sure "AVRISP mkII" is selected from Tools -> Programmer. Upload the sketch you just created to your Uno. It is now an ISP with a clock signal!

Let's fix that 328P chip that wouldn't program before. Use the same hookup as in Step 2, but add a wire from Arduino pin 9 to pin 9 on the 328P (XTAL1). See Figure. With this in place, we now want to target the 328P. Go to Tools -> Board and select "ATMEGA328 on a breadboard (8MHz internal clock)". From Tools -> Programmer, select "Arduino as ISP". DO NOT confuse this with "ArduinoISP"!! They are not the same. Double check your settings and select Tools -> Burn Bootloader. You should get the satisfying message from avrdude that eluded you in Step 5 (include it).

* Why 500KHz for the clock? You may have read elsewhere that a 100KHz clock is adequate for recovering an AVR chip. That is true. However, in our case, we are using HW SPI and need a minimum SPI clock rate of 16MHz/128 or 125KHz. The actual rate we will use is 1MHz / 6 or 167KHz. Our CPU clock rate should be a minimum of twice that rate; we use 3x for safety. 3 X 167KHz = 500KHz. Exactly the value we specify to TimerOne! That is, TimerOne will use 2uSec as its period resulting in a 500KHz clock.

Step 7: Connecting a Serial Port

To use your shiny new 328/Duino, you need to connect your USB to Serial interface to it. Interfaces using the FTDI chip are very popular, but there are other, cheaper versions. Two examples are shown in the picture; one FTDI-based, one Silicon Labs CP210x. These boards have the connections we need to control the 328/Duino and connect to a PC via a USB cable. The Gnd is the ground pin and is connected to Gnd on the 328/Duino. The Vcc / PWR / 5V pin should have 5 volts on it. Measure it with a DMM if you're not sure (if it's not marked 5V). Be sure the interface is plugged in to a live USB port when you do this. Unplug the USB connection while you are wiring it up to the 328/Duino.

IMPORTANT: The CP210x board shown has a 5V output on it, but the chip can only be used at 3.3V (which is also available). DO NOT use the 5V to power your 328/Duino. If you do, you'll destroy the CP210x board. The 328/Duino will work just fine with 3.3V, but you can't use any parts with it that need 5 Volts.

The Rx / In pin connects to Pin 3 on 328/Duino (TX), and Tx / Out connects to Pin 2 (Rx) on 328/Duino. Note that the Figure I provide assumes an order of Rx and Tx. Be sure to check your specific device for the correct pins.

Find the Interface pin labeled DTR or RTS. If you have both pins, use DTR; otherwise use the one you have. Either will work. This pin will provide the Reset pulse to the 328/Duino so it will enter bootloader mode and you can load Arduino programs. Connect a 10K resistor from Pin 1 (Reset) of the 328/Duino to Vcc. Connect a 0.1uF capacitor from Pin 1 to DTR or RTS - whichever one you're using. Some interface boards have holes for pins, but no pins. They might also have a hole labeled DTR or RTS, but no wire or pin from it. This is where a minor bit of soldering skill comes in handy. Add wires or gold square pins to the holes so you can plug your interface into your breadboard. Note carefully which pin is which so you connect everything correctly.

Step 8: Proof of the Pudding: Let's Blink!

With your USB Serial Port Interface now wired to your 328/Duino, it's time for some fun! Unplug any other Arduinos you might have connected to your PC, close the Arduino program (if it's open) and plug the USB cable from your Interface in to your PC. Restart Arduino.

Select the correct port in Tools -> Port and select the "ATMEGA328 on a breadboard (8MHz internal clock)" in Tools -> Board. Select "AVRISP mkII" in Tools -> Programmer.

Select File -> Examples -> 01. Basics -> Blink.

Change the line in Blink that says "int led = 13;" to "int led = 7;". That is, we will use Arduino Digital Pin 7 (physical pin 13 - see the Secret Decoder Ring) as the pin we attach an LED to so we can blink it. Our next step is to connect an LED via a resistor to the pin. See Figure. With the LED connected and the sketch modified, click the upload button. Is the LED blinking? Success! If it's not blinking, be sure you have the LED connected properly, on the correct pin, and have modified the sketch correctly. Still not blinking? Time to ask for help in the comments.

Unless you want to change the "led = 13" line every time you want to run Blink, use"File -> Save as" and save the modified sketch with a new name into your Sketchbook.

Step 9: Using 328/Duino to Create Another

One obvious thing you may want to do with your 328/Duino is to create another. That is, use the 328/Duino as the programmer to burn a bootloader into another 328P chip. Now you can give that Uno back to your friend and still be able to create more cheap Arduinos! You already have nearly all the info you need. Your 328/Duino is set up and working after Step 8. You can follow Step 1 to wire your new part to the breadboard. This should be the same breadboard your 328/Duino is on. Then follow Step 2 to wire up your new part to your 328/Duino. You can refer to the Secret Decoder Ring, or use the following cheat sheet showing the physical pin numbers on the 328/Duino part. Note that 5V and Gnd are connected in Step 1.

Arduino Pin <-> 328/Duino Pin <-> 328P pin <-> Purpose

10 <--------------------> 16 <-----------------> 1 <---------> Reset

11 <--------------------> 17 <-----------------> 17 <---------> MOSI

12 <--------------------> 18 <-----------------> 18 <---------> MISO

13 <--------------------> 19 <-----------------> 19 <---------> SCK

You can now mostly follow Step 5 to burn your new part. The only difference is that the programmer will be your 328/Duino, not the Uno.

"What if my chip won't program. Do I follow Step 6?" Yup. That does it. The same custom version of ArduinoISP will work as well. Use it if you need to supply a clock. Take the clock from 328/Duino physical pin 15 and run it to pin 9 on your new part, then proceed as in Step 6.

Step 10: Going Further: Standalone 328/Duino

If you want to do more experimenting with your 328/Duino, there are a few things you should do to improve its performance. First, to make use of its analog to digital converter (the analog in pins), you should connect pin 21, AREF, to 5V and put a 100nF (0.1uF) cap to Gnd on the same pin. To use the I2C bus, be sure there are pull-ups in the SCL and SDA lines that connect to pins 28 and 27. If your slave device does not provide any pull-up, use 4.7K to 5V on each line.

Having a cheap Arduino on a breadboard is all well and good, but what if you want to be independent of your PC (the USB connection that provides power)? You'll need an external power supply. This page shows one easy way to add circuitry for a power supply. Scroll down a bit to find the appropriate section. You can ignore most of the rest of the page - we've already done it in a simpler fashion. Note that the 7805 shown is an older part and not as efficient as some newer parts. There are low-drop out regulators, like the KA378R05; and buck converters such as this one that are much more efficient. For battery operation, there are boost converts like this one that provide 5V from one or two AA cells or a single LiPo package. Obviously, you can google to find more (perhaps cheaper) alternatives.

Have fun exploring the world of Arduino using the 328/Duino!