UPDATE: step about UNO as USB/TTL and regulated voltage added.
We are going to build the most basic Arduino. We are going to drop the need of crystal by using the internal oscillator running at 8MHz and would build custom bootloader to handle this. We only need a breadboard, an AVR microcontroller (Atmega328p-pu) and a bunch of wires. You might add an LED on pin 13 (to test most basic sketches) and its resistor. Hardware reset would need a resistor (10K ohm would work) and an optional button (you can use a wire). For auto software reset you would need a small capacitor (100 nano Farad).
- microcontroller (Atmega328p-pu)
- breadboard and male to male jumper wires
- LED and 300 ohm resistor
- 10K ohm resistor for reset
- 100 nano farad capacitor for software reset
- another Arduino (only needed once to burn bootloader)
- USB to TTL (this is need to upload sketches)
For burning the bootloader we would need an AVR programmer in this tutorial we are going to turn another Arduino into a programmer (this is only needed once).
To upload programs (called sketches) into our newly made Arduino we would need a way to connect it to computer, we are going to use any USB to TTL module you can pick any one of those
- FTDI cable
- FTDI module
- CP2102 module
- PL2303 module
- Arduino UNO (by removing its microcontroller from its socket)
- software V-USB running on another AVR.
Step 1: Preparing the Programmer Before Burning the Bootloader
First prepare the programmer Arduino by downloading Adafruit ISP programmer from github, open the file "ArduinoISP.ino" in your Arduino IDE and upload it to your host Arduino.
- Open "ArduinoISP.ino" in Arduino IDE (download into a sketchbook folder or copy/paste)
- from Board menu pick your Arduino board type (in this example UNO)
- from Serial Port menu pick the corresponding serial port (for example /dev/ttyACM0 or COM3)
- from Programmer menu make sure you are using the default "AvrISP mkII" option
- click upload.
Put the microcontroller on the breadboard (I like to start from 1 or 11 or 21 ...etc to simplify counting). Pin 1 of the microcontroller can be identified from the dot-like mark. Wire power and ground to pin 7 and 8 respectively and also to pins 20 and 22. Wire the microcontroller and the programmer as in the picture
- Arduino Digital 9 with uC pin 9
- Arduino Digital 10 with uC pin 1
- Arduino Digital 11 with uC pin 17
- Arduino Digital 12 with uC pin 18
- Arduino Digital 13 with uC pin 19
Arduino Digital pin 9 would generate frequency to drive the uC if it requires external crystal.
Since the old running software on the uC on the breadboard might set one of the pins down while the ISP is setting it high (eg. pin 13) you might want to connect a small resistor on each ICSP line (pins 11, 12, 13)
If you are using Leonardo instead of UNO you would need to edit the following line in ArduinoISP.ino before you upload it.
// #define RESET SS #define RESET 10
and you need to use the dedicated ICSP pins as in the attached picture.
Step 2: Burning the Bootloader (custom Optiboot5 for 8MHz)
Download my custom Arduino hardware definition (custom board and custom build of optiboot5 running at 8MHz and have buad-rate of 38400) extract the archive into your sketchbook folder (you should have a folder that looks like "sketchbook/hardware/myboard").
When you restart your Arduino IDE you should see a new board called "[Optiboot5] Arduino Uno 8MHz" pick it and change the programmer to "Arduino As ISP" then click burn bootloader from "Tools" menu. You should see TX/RX in the programmer blinking for about a minute wait until the burning is done by watching TX/RX LEDs or by looking at status bar at the bottom of Arduino IDE.
Now our new little bare Arduino (the one on the breadboard) is ready.What is included in my custom board and build?
regarding the board definition it's the same as standard UNO except:
- it uses different clock speed (8MHz instead of 16MHz)
- it set different fuses (3 bytes memory) to activate the internal 8MHz clock (called clock source).
- it uses 38400 buad-rate (which has 0.2% error margin) instead of the default 115200 (which has 7.8% error margin)
regarding the bootloader, I just grabbed it from optiboot5 and only build it with non-default configurations (no line of code was changed) to support the above requirements
Step 3: Uploading Sketches Using USB/TTL
To make sure your bootloader works fine just reset your board you should see the LED on pin 13 blinking for about 3 times. If this did not happen go back to previous steps and fix it.
You can grab cheap USB/TTL modules that support auto reset (which mean it should have DTR or RTS pins exposed) with less than 5$ just make sure not confuse Arduino REST or RTS with RST (the later is useless).
Just power your board by connecting VCC and GND from your USB/TTL. And connect DTR or RTS pin from your USB/TTL module to the pulled up RESET pin in the microcontroller (pin 1) through a small 100 nano farad capacitor (on leg to the DTR/RTS and the other on pin 1). And connect TX/RX on the microcontroller with the corresponding one in the module.
Open any sketch (eg. Blink), pick the right board (our custom Optiboot5 Uno at 8MHz), the right serial port (for example /dev/ttyUSB0 or COM4) and the right programmer (the original default one "AVRISP mkII" not "Arduino as ISP"), then click upload.
If you unable to locate the right serial port you might want to wait for the OS to recognize it or install the driver for your USB/TTL module. Sometimes you might need to restart your Arduino IDE for new things to appear.
Step 4: Using UNO As USB-to-TTL Serial
You can remove the microcontroller from Arduino UNO (label it and keep it aside because it got bootloader and needs external oscillator) then use digital 0 and 1 to provide serial communication with computer through TX and RX. In this case the USB-TTL chip in UNO will do the job, it was FTDI in previous revisions of UNO, but in latest revision it's a USB-enabled small AVR micrcontroller Atmega16U2 with open source firmware.
Step 5: Powering Your Board
You can power the Atmega328p-pu it with voltage between 1.8 - 5.5v (according to the datasheet) so you can use two AA-sized batteries (ie. 3.0v) to power it, which is fine unless you have other boards/sensors that require different voltage.
Many applications require 5v you can get that fro UNO or your USB/TTL modules as they have a pin that provide regulated 5v.
When not using UNO nor the USB/TTL modules, you can get stable regulated 5V from any USB charger, if you don't have a USB module/socket you can make your own by recycling any adapter as in the picture.Getting 3v3 regulated voltage
Some applications depends on having two voltages (the 5v that powers the main uC and 3v3 voltage for some small sensors or modules). As in the previous step you can use the 3v3 pin in your Arduino board or make sure to pick a USB/TTL module that provide both 5v and 3v3.Make your own zener-based regulator
One might consider using 3 AA batteries (4.5v) and a divider resistor to provide 3.3v voltage, we can't because the current (in mA) is not constant because the module or sensor running on 3.3v most likely have active components and different states.
Zener diodes can be used as the most simple and cheap regulators specially when we have to deal with small current magnitudes. Zener Doides in reverse bias won't allow current to flow when below the rated voltage (3.3v is usually written as 3v3) and allow all current to flow when that limit is exceeded which is what regulator allow about. You just need a very small resistor (put some in parallel if you don't have small values) to consume excess voltage.
So if we have 3 AA batteries (4.5v) and we want to provide 3.3v voltage to some module and all the 4.5v to the breadboard we can use a single 3v3 zener doide and take the regulated 3.3v between its ends. if we use 10 ohm resistor we could supply power up to 120 mA (because the current passes through the series would V/R and V between the edges of resistors is the excess of the regulator which is 4.5-3.3=1.2 so 1.2/10=0.120A=120mA)
So if we have 4 AA batteries (6v) and we can provide both 5.0v and 3.3v buy using two zener doids one is clearly 3v3 and the other is 2v7 (which is 5v - 3.3v = 2.7v) in series and connect it in series with a small resistor let's say 10 ohm and in this case we can supply up to 100 mA. (the excess voltage is 6.0-5.0=1.0 so I=V/R=1.0/10=0.1A=100mA)