The Arduino Leonardo is one of the most important classic Arduino boards because its ATmega32U4 has native USB built directly into the microcontroller.
That gives Leonardo a very different architecture from the UNO R3 and Mega 2560.
Instead of using a separate USB-to-serial processor, the ATmega32U4 itself handles:
- USB programming;
- virtual serial;
- keyboard HID;
- mouse HID;
- custom USB device classes.
The basic specifications are:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
ATmega32U4 8-bit AVR 16 MHz 5 V logic 32 KB Flash 2.5 KB SRAM 1 KB EEPROM 20 advertised digital I/O 7 PWM outputs 12 analog inputs native USB |
Arduino Leonardo Quick Pinout
| Function | Pins |
|---|---|
| Main digital pins | D0-D13 |
| PWM | D3, D5, D6, D9, D10, D11, D13 |
| Analog inputs | A0-A11 |
| Hardware UART | D0 RX, D1 TX |
| I2C | D2 SDA, D3 SCL |
| SPI | ICSP header: CIPO, COPI, SCK |
| External interrupts | D0, D1, D2, D3, D7 |
| Built-in LED | D13 |
| Logic voltage | 5 V |
| Native USB | Micro-USB, ATmega32U4 directly |
ATmega32U4 Architecture
The Leonardo uses:
|
1 2 3 4 |
ATmega32U4 |
running at:
|
1 2 3 4 |
16 MHz |
with:
|
1 2 3 4 5 6 7 |
32 KB Flash 4 KB used by bootloader 2.5 KB SRAM 1 KB EEPROM |
This is still an 8-bit AVR board, so it remains very familiar to classic Arduino users.
The Big Difference: Native USB
On an UNO R3, the main ATmega328P does not directly handle USB.
On Leonardo:
|
1 2 3 4 5 6 |
ATmega32U4 → runs your sketch → handles USB |
This allows the board to appear as:
- virtual COM/CDC serial port;
- USB keyboard;
- USB mouse;
- custom USB device.
This native USB capability is the main reason Leonardo is still useful for:
- macro keyboards;
- button boxes;
- game controllers;
- simulator controls;
- automation interfaces;
- USB HID projects.
Main Digital Pins D0-D13
The main header exposes:
|
1 2 3 4 |
D0-D13 |
with these ATmega32U4 mappings:
| Arduino pin | ATmega32U4 pin | Important functions |
|---|---|---|
| D0 | PD2 | RX / INT2 |
| D1 | PD3 | TX / INT3 |
| D2 | PD1 | SDA / INT1 |
| D3 | PD0 | PWM / SCL / INT0 |
| D4 | PD4 | A6 / ADC8 |
| D5 | PC6 | PWM |
| D6 | PD7 | PWM / A7 / ADC10 |
| D7 | PE6 | INT6 |
| D8 | PB4 | A8 / ADC11 / PCINT4 |
| D9 | PB5 | PWM / A9 / ADC12 / PCINT5 |
| D10 | PB6 | PWM / A10 / ADC13 / PCINT6 |
| D11 | PB7 | PWM / PCINT7 |
| D12 | PD6 | A11 / ADC9 |
| D13 | PC7 | PWM / built-in LED |
PWM Pins
The current Arduino AVR core defines PWM on:
|
1 2 3 4 5 6 7 8 9 10 |
D3 D5 D6 D9 D10 D11 D13 |
for a total of:
|
1 2 3 4 |
7 PWM outputs |
A normal Arduino PWM example is:
|
1 2 3 4 5 6 7 8 9 10 |
void setup() { pinMode(9, OUTPUT); } void loop() { analogWrite(9, 128); } |
On a classic AVR board:
|
1 2 3 4 |
analogWrite() |
is PWM, not a true DAC output.
No True DAC
Leonardo does not include a true digital-to-analogue converter.
If you need a real analogue voltage output, use:
- an external DAC;
- PWM followed by a low-pass filter;
- a dedicated audio DAC/codecs.
12 Analog Inputs
Leonardo provides:
|
1 2 3 4 5 |
12 analog inputs A0-A11 |
but they are arranged differently from UNO.
A0-A5 Are Dedicated Analogue Header Pins
The six dedicated analogue-header pins are:
| Analog pin | Core digital alias | ATmega32U4 pin |
|---|---|---|
| A0 | D18 | PF7 / ADC7 |
| A1 | D19 | PF6 / ADC6 |
| A2 | D20 | PF5 / ADC5 |
| A3 | D21 | PF4 / ADC4 |
| A4 | D22 | PF1 / ADC1 |
| A5 | D23 | PF0 / ADC0 |
So:
|
1 2 3 4 |
pinMode(A0, OUTPUT); |
uses the same pin that the core internally numbers as D18.
A6-A11 Reuse Existing Digital Pins
The additional six analogue channels are shared with digital header pins:
|
1 2 3 4 5 6 7 8 9 |
A6 = D4 A7 = D6 A8 = D8 A9 = D9 A10 = D10 A11 = D12 |
This means Leonardo can provide 12 analogue inputs without adding six more dedicated physical header positions.
Analog Mapping Table
| Analog | Physical digital pin | ADC channel |
|---|---|---|
| A0 | Dedicated analog header / D18 alias | ADC7 |
| A1 | Dedicated analog header / D19 alias | ADC6 |
| A2 | Dedicated analog header / D20 alias | ADC5 |
| A3 | Dedicated analog header / D21 alias | ADC4 |
| A4 | Dedicated analog header / D22 alias | ADC1 |
| A5 | Dedicated analog header / D23 alias | ADC0 |
| A6 | D4 | ADC8 |
| A7 | D6 | ADC10 |
| A8 | D8 | ADC11 |
| A9 | D9 | ADC12 |
| A10 | D10 | ADC13 |
| A11 | D12 | ADC9 |
ADC Resolution
The ATmega32U4 ADC is:
|
1 2 3 4 |
10-bit |
so a normal:
|
1 2 3 4 |
analogRead(A0) |
returns approximately:
|
1 2 3 4 |
0 to 1023 |
for input voltages between ground and the selected analogue reference.
AREF
The board exposes:
|
1 2 3 4 |
AREF |
for an external analogue-reference voltage.
If using an external reference, configure the sketch appropriately and follow the ATmega32U4 voltage limits.
Serial Is Not D0/D1 on Leonardo
This is one of the biggest Leonardo traps.
On Leonardo:
|
1 2 3 4 5 6 7 8 |
Serial → native USB CDC serial Serial1 → physical UART on D0/D1 |
That is different from UNO R3, where:
|
1 2 3 4 |
Serial |
is effectively associated with the hardware UART connected through the separate USB-to-serial interface.
USB Serial Example
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
void setup() { Serial.begin(115200); while (!Serial) { } Serial.println("USB serial ready"); } void loop() { } |
The baud-rate value is largely a compatibility parameter for native USB CDC rather than a physical UART clock setting.
Hardware UART Example
For a GPS, modem or another TTL serial device connected to D0/D1:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
void setup() { Serial.begin(115200); Serial1.begin(9600); } void loop() { while (Serial1.available()) { Serial.write( Serial1.read() ); } } |
The mapping is:
|
1 2 3 4 5 6 7 8 9 10 |
D0 → RX → PD2 D1 → TX → PD3 |
I2C Pins
I2C is on:
|
1 2 3 4 5 6 7 8 |
D2 → SDA D3 → SCL |
These are the pins used by:
|
1 2 3 4 |
Wire |
I2C Example
|
1 2 3 4 5 6 7 8 9 10 11 |
#include <Wire.h> void setup() { Wire.begin(); } void loop() { } |
Unlike some newer boards, Leonardo does not provide several separate I2C controllers through the standard Arduino API.
SPI Is on the ICSP Header
This is another major difference from UNO R3.
Leonardo hardware SPI is:
|
1 2 3 4 5 |
not D11/D12/D13 |
Instead, use the six-pin:
|
1 2 3 4 |
ICSP header |
which provides:
|
1 2 3 4 5 6 7 8 9 |
CIPO / MISO COPI / MOSI SCK RESET 5 V GND |
SPI Core Digital Aliases
The AVR core also maps the SPI signals to digital numbers:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
D14 → CIPO / MISO → PB3 D15 → SCK → PB1 D16 → COPI / MOSI → PB2 D17 → SS → PB0 |
But the normal Leonardo board connection for SPI peripherals is the ICSP header.
Why Some Old UNO Shields Fail on Leonardo
Older shields sometimes assume:
|
1 2 3 4 5 6 |
D11 = MOSI D12 = MISO D13 = SCK |
That assumption is correct for classic UNO AVR layouts but wrong for Leonardo.
A properly designed R3-format shield should obtain SPI from the:
|
1 2 3 4 |
ICSP header |
and can therefore support both UNO and Leonardo.
SPI Example
|
1 2 3 4 5 6 7 8 9 10 11 |
#include <SPI.h> void setup() { SPI.begin(); } void loop() { } |
The library automatically uses the ATmega32U4 hardware SPI peripheral.
External Interrupt Pins
The current Arduino AVR core maps:
|
1 2 3 4 5 6 7 8 |
D0 D1 D2 D3 D7 |
to external interrupts.
Use:
|
1 2 3 4 5 6 7 8 |
attachInterrupt( digitalPinToInterrupt(pin), ISR_function, mode ); |
Interrupt Mapping
| Arduino pin | ATmega32U4 interrupt |
|---|---|
| D0 | INT2 |
| D1 | INT3 |
| D2 | INT1 |
| D3 | INT0 |
| D7 | INT6 |
Pin-Change Interrupts
The ATmega32U4 also provides pin-change interrupt capability on selected Port B pins.
The Arduino core exposes PCINT-related mappings on pins including:
|
1 2 3 4 5 6 |
D8-D11 D14-D17 A8-A10 aliases |
but normal Arduino sketches usually use:
|
1 2 3 4 |
attachInterrupt() |
when a dedicated external interrupt pin is sufficient.
Built-In LED
The main onboard LED is:
|
1 2 3 4 5 6 |
LED_BUILTIN → D13 → PC7 |
so the standard Blink example works normally.
Separate TX and RX LEDs
Leonardo also has dedicated USB activity LEDs:
|
1 2 3 4 5 |
TX LED RX LED |
which are controlled by separate ATmega32U4 pins.
These are not the same as the D0/D1 UART lines.
Native USB Keyboard
Leonardo can act as a USB keyboard using:
|
1 2 3 4 |
#include <Keyboard.h> |
For example:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
#include <Keyboard.h> void setup() { Keyboard.begin(); } void loop() { if (digitalRead(4) == LOW) { Keyboard.write('A'); delay(300); } } |
Be Careful with Keyboard Sketches
A bad HID sketch can continuously send keystrokes to your computer.
Use a physical enable condition such as:
- button held during startup;
- jumper input;
- startup delay;
- safe-mode pin.
This makes development much easier.
Native USB Mouse
The same ATmega32U4 can emulate a mouse using:
|
1 2 3 4 |
#include <Mouse.h> |
This is why Leonardo became popular for:
- DIY controllers;
- assistive interfaces;
- simulator panels;
- custom pointing devices.
USB Reset Behaviour Is Different
Because the same MCU runs both:
|
1 2 3 4 5 6 |
your sketch and USB |
Leonardo disappears from USB when it resets into the bootloader and then reconnects.
Arduino’s upload system uses a:
|
1 2 3 4 |
1200 bps touch |
to trigger the bootloader during normal uploads.
This can cause the serial port name or COM number to change temporarily during upload.
Why Leonardo Can Seem to “Disappear”
If a sketch breaks USB handling or resets continuously, the normal application port may disappear.
The board can still usually be recovered through its bootloader/reset process.
This behaviour is fundamentally different from UNO R3, where a separate USB-to-serial chip remains present even if the ATmega328P sketch crashes.
5 V Logic
Leonardo uses:
|
1 2 3 4 |
5 V logic |
which makes it convenient for older:
- 5 V sensors;
- LCDs;
- AVR shields;
- TTL peripherals.
This is very different from modern 3.3 V boards such as:
3.3 V Rail
The board also provides:
|
1 2 3 4 |
3.3 V |
with the current official pinout specifying a maximum of:
|
1 2 3 4 |
50 mA |
from that rail.
GPIO Current
The current official Leonardo full pinout states:
|
1 2 3 4 5 |
20 mA maximum per I/O pin |
Some older Arduino store specification tables still show:
|
1 2 3 4 |
40 mA |
for the ATmega32U4 I/O figure.
For new designs, the current official pinout’s:
|
1 2 3 4 |
20 mA maximum |
is the safer board-level limit to follow.
Do Not Drive Motors or Relays Directly
Use:
- transistors;
- MOSFETs;
- relay drivers;
- motor drivers.
The GPIO pins are for logic signals, not power loads.
Power Input
Leonardo can be powered through:
- Micro-USB;
- barrel jack;
- VIN;
- regulated 5 V supply where appropriate.
Arduino specifies:
|
1 2 3 4 5 6 7 8 |
recommended input: 7-12 V absolute board input range: 6-20 V |
IOREF
The R3-style power header includes:
|
1 2 3 4 |
IOREF |
which indicates the board logic voltage.
On Leonardo:
|
1 2 3 4 |
IOREF = 5 V |
This allows compatible shields to adapt between 5 V and 3.3 V Arduino boards.
Leonardo vs UNO R3 Pinout Trap Summary
| Function | Leonardo | UNO R3 |
|---|---|---|
| USB | Native in ATmega32U4 | Separate USB-to-serial MCU |
| Serial Monitor | Serial = USB CDC | Serial = hardware UART via USB bridge |
| Physical UART | Serial1 on D0/D1 | Serial on D0/D1 |
| I2C | D2/D3 | A4/A5 plus SDA/SCL header |
| SPI | ICSP header | D11-D13 and ICSP |
| PWM | 7 pins | 6 pins |
| Analog inputs | 12 | 6 |
| USB keyboard/mouse | Native | Not from ATmega328P directly |
Quick Digital Pin Reference
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
D0 RX / INT2 D1 TX / INT3 D2 SDA / INT1 D3 PWM / SCL / INT0 D4 A6 D5 PWM D6 PWM / A7 D7 INT6 D8 A8 D9 PWM / A9 D10 PWM / A10 D11 PWM D12 A11 D13 PWM / LED_BUILTIN |
Quick Analog Reference
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
A0 = D18 = ADC7 A1 = D19 = ADC6 A2 = D20 = ADC5 A3 = D21 = ADC4 A4 = D22 = ADC1 A5 = D23 = ADC0 A6 = D4 = ADC8 A7 = D6 = ADC10 A8 = D8 = ADC11 A9 = D9 = ADC12 A10 = D10 = ADC13 A11 = D12 = ADC9 |
Quick Communications Reference
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
USB CDC: Serial Hardware UART: Serial1 D0 RX D1 TX I2C: D2 SDA D3 SCL SPI: ICSP header CIPO / MISO D14 / PB3 SCK D15 / PB1 COPI / MOSI D16 / PB2 SS D17 / PB0 |
When Leonardo Still Makes Sense
Leonardo is old by modern MCU standards, but it remains a good fit for projects where the priority is:
- native USB HID;
- simple 5 V logic;
- small AVR firmware;
- keyboard/mouse emulation;
- legacy Arduino shield compatibility.
It is less attractive when you need:
- Wi-Fi;
- Bluetooth;
- large RAM;
- high CPU performance;
- modern 32-bit peripherals.
Final Thoughts
The Arduino Leonardo is best understood as:
|
1 2 3 4 5 |
a classic 5 V AVR Arduino with native USB |
rather than simply another UNO-shaped board.
The most important pinout rules are:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
Serial → USB CDC Serial1 → D0/D1 hardware UART I2C → D2/D3 SPI → ICSP header PWM → D3, D5, D6, D9, D10, D11, D13 A0-A5 → core aliases D18-D23 A6-A11 → reuse D4, D6, D8, D9, D10, D12 logic → 5 V USB HID → native ATmega32U4 feature |
The unusual SPI, serial and analogue aliasing are the areas most likely to catch users moving from an UNO R3.
The next closely related board is the Arduino Micro, which uses the same ATmega32U4 and native USB architecture in a much smaller breadboard-friendly format.