After purchasing an Arduino board (UNO) I decided not to use Arduino IDE as it lacked some features and all libraries are written in C++. I am coding with C. One thing that I really do miss is a serial interface that allowed my Arduino to talk to PC it is connected to.

So far I am familiar with SPI protocol, and thought to use USB-SPI converter chips, but since I already have USB implemented on the board I decided to seek information about how it is done and what USB consist of.

So far I found that it is UART that talks to a chip on Arduino board, and that chip is responsible for communication with PC.

But can somebody explain to me what actually happens on that board? And point me in the right direction please.


On "ordinary" Arduino boards like the Uno, the AVR microcontroller's serial UART is used to communicate with a PC.

Because modern PC's no longer tend to have serial ports, the 9-pin serial connector and level translators found on the earliest Arduino boards have long since been replaced with an on-board USB<>Serial bridge chip. Originally this was an FT232R, but from the Uno it has been a different Atmel MCU such as the ATmega8u2 or 16u2 running a firmware which provides similar functionality.

Essentially, the Arduino's main processor needs to have its hardware UART configured to output debug messages or program data at a chosen baud rate, using logic level asynchronous serial signaling. If the USB port is connected to a computer running appropriate CDC ACM drivers, the USB bridge chip will be commanded to batch the data received and forward it to the host computer, where it can be claimed from serial APIs just as if it came from a traditional serial port.

To communicate in the other direction, a program on the PC sends data through serial APIs, this is batched into USB packets and sent to the bridge chip, which turns it into asynchronous serial data and sends it to the main MCU. A program running on the Arduino itself would need to be written to collect this data form the UART, typically using interrupts (or optionally frequent polling) and then interpret it.

The bootloader used on the Arduino performs both of these operations on its own behalf while running - briefly after each reset, longer if it sees traffic related to a bootloader. But that capability is irrelevant to the main program (aka "sketch") which must re-implement the logic to interact with the UART itself. Worth noting that you can use the Arduino bootloader without using the IDE or writing Arduino-style programs.

If you look around online, you'll probably find many code examples for using the ATmega UART in a C program, vs. a C++ or Arduino one.

Some other Arduino boards work differently; for example the Leonardo uses an ATmega32u4 chip as its main processor, which can directly speak USB. In that case there is no extra bridge needed. But instead of simple UART configuration, the program on the main MCU must now include much more complex logic for dealing with the USB hardware itself, including interrupts that must run fairly frequently. This is much harder to implement in a from-scratch project, though it does mean a lower parts count and a little more flexibility since the USB port can be used for purposes beyond channeling a virtual serial stream.

  • 3
    \$\begingroup\$ Not FT2232, but FT232R. \$\endgroup\$ – CrossRoads Oct 26 '18 at 12:29
  • \$\begingroup\$ Indeed, that was a brain-fingers error on my part. I believe the ft232rl was used, while the ft2232 is the fancy chip suitable for things like jtag as well as serial. \$\endgroup\$ – Chris Stratton Oct 26 '18 at 16:11
  • \$\begingroup\$ some clones have CH430 for the interface chip. \$\endgroup\$ – Jasen Oct 26 '18 at 19:10

As pointed out in another answer, there is a USB to serial port conversion going on on the UNO board.

There is also a bootloader program installed on the microcontroller. The ability to program the UNO microcontroller through the serial port is 100% dependent on a bootloader. If during the programming development, something happens to that bootloader, you need to reload the bootloader on to the chip. This is done with an in circuit serial programmer (ICSP), which plugs in to one of the .1" header connectors on the UNO.

If you're going to develop in the way you describe, I would recommend purchasing and using an ICSP for programming, and just programming the serial port communications directly. The serial to USB conversion will be transparently handled by the on-board hardware.

  • \$\begingroup\$ So your suggestion is: In order not to harm boot-loader program on Arduino i better use another device (aka programmer) to do my serial stuff ? \$\endgroup\$ – Anton Stafeyev Oct 26 '18 at 13:53
  • \$\begingroup\$ Almost the opposite. If the bootloader is correctly installed it will prevent damage to itself during main program flashing. But using ISP to reload something is 100% guaranteed to erase the bootloader, as ISP can only erase the full chip. So once you start using ISP, you'll have to use it again to restore the bootloader if you ever want to do use that. Note that you can use another Arduino running the ISP sketch as an ISP adapter should you temporarily need one. The bootloader is every bit as appropriate for bare metal C as it is for Arduino sketches. \$\endgroup\$ – Chris Stratton Oct 26 '18 at 16:15
  • \$\begingroup\$ A Programmer is needed to access the Bootload area of the flash. Your sketch, in C or C++, will not have access to the calls to overwrite the Bootload area. You need a special bootloader that has the needed calls set up as a function in the bootload area, which the sketch can call to allow data coming in from the serial port to be written into the bootload area. \$\endgroup\$ – CrossRoads Oct 26 '18 at 16:18
  • 1
    \$\begingroup\$ As bad as the Arduino IDE is, if you are new to microcontrollers spending an hour or two trying some of its serial examples from the drop-down menu could give you some initial perspective on what the hardware can do before you switch to bare metal C programs and Serial.begin(9600); serial.println("hello world"); becomes a few dozen lines of hardware-oriented code. \$\endgroup\$ – Chris Stratton Oct 26 '18 at 16:24
  • \$\begingroup\$ @ChrisStratton i have already implemented UART and SPI, and so far it works. but a very simple implementation. i would like to get rid of bootloader, because it is not my code running on my device. Another question that is emerging at the moment is the Code inside of Atmega8 that handles the usb connection. why it is showing as com port on my pc. is it possible to ICPS that chip ? \$\endgroup\$ – Anton Stafeyev Oct 26 '18 at 18:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.