I tasked our intern with creating an Arduino clone. His job is to create a schematic and printed circuit board with connections similar to our Firstbot product (shown above). The main reason for the task was to introduce him to the concept of a bootloader and familiarize him with the popular Arduino product line. It also helps that he gets more experience writing C code for microcontrollers, and creating a printed circuit board. If you don’t know what a “bootloader” is you can read about it here.
The short story is that a bootloader is a simple program that resides in memory. It is used to communicate with the outside world and program other memory locations in the device. With the Arduino, the bootloader looks for a specific signal at power up, and if present it will copy serial data to its own program memory. Bootloading programs are generally restricted from writing to memory locations where the bootloader resides (otherwise a bootloader could inadvertently overwrite itself) .
Bootload code in a microcontroller is usually at the beginning or end of program memory, and it will jump to a fixed program memory address when not executing its core function as a bootloader. If you imagine memory as a single page of paper the bootloading function might look something like what I’ve shown below.
A flow chart is another way to visualize the bootloader process. Imagine a piece of code that looks for specific commands to be received after a reset occurs. That same code runs a one second timer, and if the timer elapses code is sent to a known start point to execute. Under normal operating conditions a device reset would be followed by a 1 second delay, and then the code would execute. However, the bootloader code could receive a special serial command during the first second after reset that caused it to write data to program memory, and reset the timer.
So at the heart of an Arduino clone is the bootloader. But how does it work?
I designed an Arduino clone a few years ago when we created our Firstbot product. As part of that project I figured out how to program the Arduino bootloader using an Atmel programmer.
The Arduino Uno 3 comes loaded with a serial bootloader. This allows serial data to be loaded into the ATmega328P program memory (ZU4 on the schematic). When uploading a sketch from the Arduino development environment the bootloader is what avrdude is talking to (well, I guess its really what the programmer code called by avrdude is talking to).
The USB to serial conversion on the Arduino Uno 3 is accomplished with U3, an ATmega16U2-MU (according to the schematic). I’m not sure why the makers of the Arduino decided to place a second microcontroller on the Uno 3 to accomplish USB/serial conversion. The decision It might have been based on pricing, or post production testing/programming capability. Who knows?
One thing that is apparent is that U3 doesn’t do a whole lot other than execute a reset via the DTR connection. This reset is followed by sending program data on the MBRXD and MBTXD lines to the bootloader. Here’s the section of the schematic associated with the reset signal on the DTR line. I’ve shown where I connected my oscilloscope to the circuit.
The image below show the DTR and RESET signals that initiate bootloading in the Arduino Uno 3. I’m not privy to the exact actions/requirements of the Arduino’s bootloader. My guess is that details can be found via Google-Fu.
My assumption is that after a reset the bootloader looks for serial data in a specific format, and if it does not see the correct data in a within a short period of time the bootloader routine exits. The DTR serial line is used to initiate a reset.
The people who invented the Arduino have been nice enough to open-source the bootloader for the official Arduino products. I pulled my bootloader from a pretty out of date Arduino folder, so you might see a different directory structure. I located the bootloader in the following directory…
I think newer versions of the Arduino software use the same bootloader, but I could be wrong. I used the optiboot_atmega328.hex file.
With this bootloader firmware, an appropriate circuit, and an Atmel programmer, you can easily create an Arduino clone. In our case we replaced U3 on the Arduino Uno 3 with an FTDI FT232RL, which is a USB to serial converter. It has a DTR output (as well as the other serial lines you may be familiar with).
Here is the circuit we used.
If we attempt to upload a sketch from the Arduino development environment to this board the DTR and RESET lines look very similar to the Arduino scope capture.
The only thing preventing our circuit from behaving like an Arduino is getting the bootloader into the chip. To do this we used an Atmel-ICE which runs about $60US. We connected the Atmel-ICE to a 3×2 0.1” header wired the same as the connector labeled ICSP on the Arduino Uno 3 (ICSP stands for in-circuit-serial-programming, or something similar). Atmel provides a handful of connector types with the Atmel-ICE but isn’t very clear on the pin out of the receptacle that matches the Arduino ICSP header. I determined that the tab on the receptacle faces pin 1 of the 3×2 header. On the Arduino Uno 3 the tab faces the “MADE IN ITALY” text. Below is an image of how it fits on our clone.
Our clone uses an ATmega328. The Arduino Uno 3 used the AtMega328P. This difference didn’t seem to impact the bootloader selection.
Once your board is connected to the Atmel-ICE, and powered, you can launch Atmel’s development environment Atmel Studio (we used version 7). When the program is loaded select Tools and Device Programming. You should see a window similar to this…
Select the IC you’re using and press the “Apply” button.
Then press the Read button… you should get a device ID and see the board voltage if the connection between the Atmel-ICE and the processor is correct.
Select the Fuses tab by clicking on “Fuses” in the left hand side of the window. For the Arduino Uno 3 the extended fuses should be 0x05, the high fuses 0xDE, and the low fuses 0xFF. Press the Program button.
Now, navigate to the Memories tab. Select the button marked with “…” and navigate to the location where the Arduino bootloader is stored. In my case it was in the Arduino folder under hardware/arduino/bootloaders/optiboot. I selected optiboot_atmega328.hex. When you have selected the bootloader press the program button.
If everything worked out okay your clone should be running a program that toggles the logic state of P13. This pin is routed to an LED on the Arduino Uno 3, as well as our clone. If your hardware has this connection you should see the LED blinking.
To make sure the bootloader is installed correctly you can select another example program and upload it to your clone using the Arduino development environment, as I’ve done below.
With an Arduino clone you can customize your circuit board and still have the ability to use all of the global knowledge and ecosystem associated with the Arduino. That’s pretty cool.