Several years have passed since the Arduino project grew. It is well known that this development has drawn new generations in the world of microcontrollers and digital electronics. Mainly this is not about professionals, engineers, but amateurs, enthusiasts, hobbyists, makers. And obviously some of them are at the beginning.
This article is dedicated to those people who want to go beyond using Arduino boards to develop also its own hardware projects. It is also an attempt to present some USART issues in relation to this purpose.
Although likely there are many articles that deal with this topic, I think there is room for another one, which was written especially for those who have enough experience to try to make their own projects based on the Arduino, but have not yet mastered all hardware details (with a focus on USART/serial connection).
At first we compare how serial link is used in Arduino versus classic development board.
And we’ll start like this: We’ll pretend like Arduino was not yet invented. We have a microcontroller (ATmega incidentally) and we want to experiment or to develop a project with this microcontroller.
The first thing we need (in terms of hardware) is to put our microcontroller in a minimal environment to run and then a method (and device) to write our program in microcontroller. Usually our program (firmware) is a file (hex/bin) that is generated using specific software tools like assembler / compiler/ linker.
In the picture it is used the most common and most cheapest solution for a programming interface, open source programmer USBasp. There are several programming options (JTAG, HVPP, HVSP and of course ISP) but this is not the subject of this article. The point is that we need a programming method. And that’s it. If properly configure Arduino IDE, we can upload our programs like any arduino board.
So, to be clear, we can overlook (or ignore) the whole section that includes serial / USART / RS232. We can blink an LED, display on the LCD, we can communicate on the I2C or SPI, or to read a DS18B20 or other sensors, to write a eeprom … or even to communicate in an Ethernet network (LAN or WLAN) … you get the idea.
In many projects we will not need the serial interface at all. Or we need serial communication between the various modules of the project (eg. A GPRS modem, or a GPS module) but not for communication outside the project. And for these types of projects we can totally ignore Section 2.
And yet. What’s with serial? As we see from the image above, there are several options to connect a microcontroller to a computer:
- Usb to Serial adapter (or USB to RS232 adapter). The most common method (and probably cheapest). Development board is required to have an level adapter from + 15v / -15v to TTL. Usually this is done with a dedicated chip like MAX232.
- Serial cable. This should have been to be the cheapest solution, because is about a simple cable. But new computers no longer have RS232 connectors. And laptops even less. And sometimes I think it’s not a good idea to play with some unfinished projects and link them to a connector that goes (some way or another) directly to the southbridge of your expensive motherboard. So even if I had this port available, I still prefer to use the previous method. If something goes wrong it is possible/probable that cheap USB-to-serial interface to save my motherboard. It is not a bulletproof protection but is better than nothing.
- USB to TTL adapter. (or USB to TTL cable) It is a variant of USB to RS232 adapter. But instead climb voltage of USB to +-15V then subtract them to TTL level with help of another chip, this USB interface give us the right TTL voltage. So we can connect directly to RX and TX pins of microcontroller. Sometimes this is the best solution, especially when we want to reduce PCB size.
We see that we have to choose from, because a serial link can have multiple uses. But when we use it to connect to a PC, these possibilities can be divides into two:
- Exchange data between embedded device(our project) and PC;
- Update firmware of the embedded device (our project). This possibility worth being treated separately.
3.COM/RS232 interface as Programming interface.
We saw that the serial link can be used both for regular communication between the device and PC, and to update the firmware of the device. This double use has been the source of much confusion. Because we can use ATmega microcontrollers on Arduino IDE:
- With dedicated programmer (like USBasp);
- With dedicated programmer (like USBasp) and serial link to PC (one of the methods mentioned above);
- With serial link only (one of the methods mentioned above).
The first question that will have to answer is “Why we should use the serial interface of the microcontroller as programming interface?” To answer, we try to list pros and cons:
- only one cable is required;
- no need for a dedicated programmer (…if microcontroller already bootloaded);
- slightly more expensive (…microcontroller already bootloaded);
- usability for ready-made projects,standardization.
- wasted the program memory;
- it is required to setting microcontroller in a certain way (with a dedicated programmer);
- wasting programmer effort, the division of work between payload, bootloader and matching both to work together;
- it requires a method to switch between the two modes programming/communication – autoreset / manual reset.
- auto reset function can sometimes impede the desired operation
It seems that Cons are more heavy than Pros, and I think so is. I always used (in my custom hardware projects) a dedicated programmer.
And yet…Arduino boards have been very successful in his configuration; and when I used Arduino boards, I was glad that there were a bootloader. And I used to enjoy the advantage of having a single cable for both programming and data communication. It seems that I contradict myself: Why what is good for Arduino boards is not good for Arduino-based custom-hardware projects?
For Arduino creators/developers Arduino Boards are the final products. An Arduino board is both a (simple)development board and rapid prototyping module (especially). And must operate as out of the box, with predictable results. And it does its job very good and beautiful.
For the most rest of us, our final product is not a development board, but a project with a particular purpose, a concrete goal. And most of the time to integrate a bootloader (or a MAX232 or both) when it is not needed is an unnecessary complication that can lead to bugs, delays, less memory available, bigger PCB, more components… As always is all about selecting the right tool for the job.
Next we will consider the schematic of one of the oldest Arduino Board. This board use integrated circuit FT232RL as an USB to TTL adapter… 🙂 In fact IS a USB to TTL adapter and is included in the Arduino board. Apart from connections specific for serial link, namely RX and TX there are connections for auto reset. I have highlighted in red the auto reset path, and with blue serial RX/TX path.
Now it’s time to learn more about the inner-workings of AVR MCUs. And our best ally is always the datasheet. I quote here 16.2 Overview section from ATmega328 datasheet (page 277):
In ATmega88PA, ATmega168PA and ATmega328P, the Boot Loader Support provides a real Read-While-Write Self-Programming mechanism for downloading and uploading program code by the MCU itself. This feature allows flexible application software updates controlled by the MCU using a Flash-resident Boot Loader program. The Boot Loader program can use any available data interface and associated protocol to read code and write (program) that code into the Flash memory, or read the code from the program memory. The program code within the Boot Loader section has the capability to write into the entire Flash, including the Boot Loader memory. The Boot Loader can thus even modify itself, and it can also erase itself from the code if the feature is not needed anymore. The size of the Boot Loader memory is configurable with fuses and the Boot Loader has two separate sets of Boot Lock bits which can be set independently. This gives the user a unique flexibility to select different levels of protection.
Interesting things… so now we know that they could choose another interface than USART, but it would have been pointless because RS232/USB was the most common interface found in home computers.
A very good explanation of the boot process can be found here: at the arduino.cc website.
- We do not need a bootloader to use an independent ATmega in Arduino IDE. We need to configure Arduino IDE to “recognize” our boards, and we can use any programmer available in Arduino (in fact available in avrdude).
- We don’t need a bootloader to use serial port of an independent ATmega with Arduino IDE (serial monitor). We need a link between our computer and microcontroller board. Usually this link can be made with an adapter cable USB-to-RS232 or USB-to-TTL. USB-to-RS232 require a level shifter (like MAX232) on microcontroller board. USB-to-TTL not require a level shifter.
- We can use a bootloader if we really want this. To use a bootloader we need to write it to our ATmega MCU using a specialised programmer. The bootloader must fit exact
our microcontroller model. There are open source bootloaders available for most used ATmega MCUs. We still need to manual reset the MCU before uploading our code/sketch.
- If we want to upload the code with auto reset, we need to add a method to reset the microcontroller by the Arduino IDE. Usually this is done using RTS or DTR pins (or both). At the beginning autoreset feature used the RTS signal; in later boards they changed to using the DTR signal. We can follow schematic of any Arduino board with ATmega MCU. These schemes can be found easily at Arduino site (since they are opensource). For example Arduino Uno schematic.
This article does not intend to provide practical methods about how to use serial and/or bootloader with ATmega MCUs in Arduino IDE. There are many good articles that do this.
Instead, I want to present an overview of the issue, to remove some confusions that emerged from comments and discussion, here or elsewhere. I hope I succeeded… at least partially.