USB and serial ports on Arduino Leonardo


The difference between Arduino UNO and Leonardo

The biggest difference between Arduino UNO and the new Arduino Leonardo is in how USB communication is handled.

Arduino UNO and earlier devices have all used a discrete USB controller (an FTDI chip, or in the case of the UNO a dedicated ATMega8U2 chip programmed to act as a USB to serial converter). This means that the UART on the main processor is used for communication with the computer.

The new Arduino Leonardo uses an Atmel Atmega32U4 chip that comes with a USB core on-chip, and thus this and not the UART is used to communicate with the computer.

The practical result of this is that (when using the Leonardo) communicating with the computer (for example for debugging) does not use up your UART. The Serial object is used for communicating with the computer, and the hardware UART on the processor is bound to the Serial1 object (the hardware uart is connected to pins 0 and 1, as it is on the Arduino UNO).

In conclusion: The Arduino Leonardo has two serial ports, one connected to the USB port and one connected to pins 0 and 1.

Installing drivers for USB

For Linux and Mac, the device just works, for Windows you will need an INF file. (Included in version 1.0.1 of the Arduino IDE).

The USB protocol has 2 ways of recognizing a device: the VID/PID and the Class.

The Class tells the OS what kind of device it is, eg HID (for Mouse and Keyboard) or CDC (USB communications device class for serial ports) etc.

When you plug in a USB device on OS X and Linux, the USB class will be checked first. The Leonardo bootloader will identify itself as a serial port, and this is enough for OS X / Linux: A generic serial port driver will be loaded, and used to upload sketches.

Windows works a bit differently: It first looks at the VID/PID (Vendor ID/Product ID) of the device. The VID and PID are unique identifiers that are used to match the correct driver to the device.

Thus, to make Leonardo work on Windows you need to give it a INF file that tells Windows that this VID/PID combination is a serial port and should use the common USB virtual serial driver.

What about clones?

A Leonardo clone must supply its own unique VID/PID combination. This causes no problems on OS X and Linux since the Class will be the same as a genuine Leonardo, and the correct generic serial port driver will be loaded.

This won't work on Windows, since Windows looks at the VID/PID combination first (as explained in the previous section).

To complicate things, the Leonardo and any clone needs two VID/PID combinations: One is for the bootloader (which is a pure serial port) and one is for the actual Leonardo device, the one that runs your sketch after exiting the bootloader (which is a combined serial port and HID device).

The practical upshot of this is:

On OS X and Linux, a Leonardo clone will work out of the box, and can be identified as "Arduino Leonardo" in the Boards menu in the Arduino IDE. It is of course better practice to add an entry specifically for the clone device in boards.txt.

On Windows, a unique INF file for the clone device must be installed. Also, it will not work without editing the boards.txt file to add a unique section for the clone device.