How to use all available pins on Leonardo (atmega32U4)

Q: Help I need more pins from my Arduino Leonardo board. Is it possible?
A: Yes it is! Read lines below for explanation, how to.

Arduino Leonardo board is using an Atmel atmega32U4 microcontroller which have 26 I/O pins. Arduino R3 platform is designed only to use 20 of them. So if you are working on Leonardo board and you are running out of pins on your Leonardo board, don't worry, you can get most pins without changing anything.
So where are my 6 lost I/O pins?

First lets see how does the atmega32U4 looks like:

From the image above you can see that some pins of atmega32U4 are used as Arduino digital or analog pins, some pins are for power supply, on the left side is a USB port, there are two pins for crystal... but some of the I/O pins aren't used for I/O operations. Or are they?

MISO, MOSI and SCK:
First there is an SPI header on the Leonardo board. The pins connected to the SPI header are MISO (PB3), MOSI (PB2) and SCK (PB1). If you want to use them as I/O pins here is a secret. You can use them same as any other digital pin on Leonardo. Use the corresponding digital pin number:
MISO as digital pin 14
MOSI as digital pin 16
SCK as digital pin 15

RX and TX LEDs:
If your sketch doesn't require USB communication or you have an atmega32U4 without bootloader and you are programming uC via SPI or Atmel Flip, you can use RX and TX too. To use RX LED pin as I/O, use corresponding digital pin number:
RXLED as digital pin 17
TXLED can be used only (if you don't wan't to change DDR, PORT and PIN registers) as an output pin. Commands for controlling TXLED pin are:

TXLED0;      //To turn TXLED pin on
TXLED1;      //To turn TXLED pin off

Note: you can controll RXLED pin just the same way as TXLED pin, with using RXLED1; command to turn RXLED pin HIGH and RXLED0 to turn RXLED pin LOW.

HWB pin:
I haven't researched HWB pin yet, so any comments below are welcome. Some day I will add instructions how to use HWB pin as I/O pin.

So this is it, quite simple right?
Note: all functions above were tested on Arduino Leonardo board, using IDE 1.5.6r2 on Windows 7 x64 based computer.

Is there a way to have the RX_LED functionality on TX_LED too? Meaning the pin will light an LED when either receiving or transmitting?

Also, can the RX pin be reassigned even if you are using USB but don't need to blink the RX_LED?

Hi, I see in the picture that there are more Acc connected pins, I have read this in different places also..... Problem I am having is working out how to reassign a digital pin, say pin 26 (pd6t1/0c4d/adc9).

I would really love to see some example code to do this....

I hope someone can help....

JUGmobile:
HWB pin:
I haven't researched HWB pin yet, so any comments below are welcome. Some day I will add instructions how to use HWB pin as I/O pin.

I've not tried to use that pin, so this is theoretical: That pin is used as an input for the bootloader, and is tied low through a 10K resistor. If you try to use that as a general purpose input, it's possible that the external hardware could be driving that line in a high state while you are resetting, and that could change the behavior of the bootloader. If you want to use that pin, it's best to use it as an output, in a circuit that won't be affected by having a 10k pulldown resistor on it. (Not with an AVR processor, but I have run into problems like that trying to use a boot mode pin on other processors - it just isn't reliable to use such a pin as an input, it will come back to bite you eventually.)

There doesn't appear to be any support for that particular pin in the Leonardo's pin definitions, so you will probably have to resort to accessing the DDRE and PORTE registers directly to set it up as an output and set its output state.

GrahamPrattWyalong:
Hi, I see in the picture that there are more Acc connected pins, I have read this in different places also..... Problem I am having is working out how to reassign a digital pin, say pin 26 (pd6t1/0c4d/adc9).

You say Acc, but I assume you mean ADC, and I guess you are saying you want to use pin 26 as another analog input? The file hardware/arduino/avr/variants/leonardo/pins_arduino.h in your Arduino program folder defines all of the pins It has this section:

// Mapping of analog pins as digital I/O
// A6-A11 share with digital pins
static const uint8_t A0 = 18;
static const uint8_t A1 = 19;
static const uint8_t A2 = 20;
static const uint8_t A3 = 21;
static const uint8_t A4 = 22;
static const uint8_t A5 = 23;
static const uint8_t A6 = 24; // D4
static const uint8_t A7 = 25; // D6
static const uint8_t A8 = 26; // D8
static const uint8_t A9 = 27; // D9
static const uint8_t A10 = 28; // D10
static const uint8_t A11 = 29; // D12

So, while I've not tried it, it looks like all you might have to do to use pin 26 (D12) as an analog input is to use pin A11 in your analog read call. Same for the other pins, they look to be mapped as A6 through A11.

This seems to be confirmed later in the file, where the An numbers are mapped to analog hardware channels:

const uint8_t PROGMEM analog_pin_to_channel_PGM[] = {
 7, // A0 PF7 ADC7
 6, // A1 PF6 ADC6 
 5, // A2 PF5 ADC5 
 4, // A3 PF4 ADC4
 1, // A4 PF1 ADC1 
 0, // A5 PF0 ADC0 
 8, // A6 D4 PD4 ADC8
 10, // A7 D6 PD7 ADC10
 11, // A8 D8 PB4 ADC11
 12, // A9 D9 PB5 ADC12
 13, // A10 D10 PB6 ADC13
 9 // A11 D12 PD6 ADC9
};

A6 through A11 do have ADC hardware channel numbers assigned, and the comments match up with the pin names/functions mentioned in the diagram above. So, simply try using those analog pin names, and it should just work.

OK thanks for that, my wife said i only had a "boys look"...

I had played here a couple of days ago trying every combo I could think of then it hit me.... set all Dig pins to Input first.... derrrrr.

So the attached code displays the value of the pins as I have mapped them on the leonardo (SainSmart).

Using a flexible jumper to ground, the 0 becomes obvious....

Now the picture says that there is also an A11 and A12 these would be really useful as i am monitoring the voltage on each cell on a 24V battery so using all 12 pins for measuring leaves me nothing for grabbing the RTC value....

I would be happy to see the pins... several maps I have see appear to give differing ideas on this...

personally I cannot find them unless they are hidden doing some important function like flashing an led or something?

Any ideas?

dig_as_analog.ino (1.27 KB)

Any progress made on using PE2 and PD5? I'm using an ATMEGA32u4 with the Lilypad USB bootloader and I need literally every pin on the thing.

I hope this helps someone wanting to use HWB pin in a sketch...

DDRE |= (1<<2);

#define _HWB_H() (PORTE |= (1<<2))
#define _HWB_L() (PORTE &= ~(1<<2))

To pull HWB high, simply

_HWB_H(); // or _HWB_L(); to pull it low

1 Like

BlackJester:
Is there a way to have the RX_LED functionality on TX_LED too? Meaning the pin will light an LED when either receiving or transmitting?

Also, can the RX pin be reassigned even if you are using USB but don't need to blink the RX_LED?

Bump!

Im wondering this same thing...

I need to use PD5 (TXLED) as a general purpose output, but Im also using USB.

I dont care about losing the LED functionality; I need the output much more than I need an indication of USB activity.

Im starting with blank ATMega32u4 chips, so Ill be first flashing the Leonardo bootloader, and from then on be making changes etc via USB.

Maybe something can be changed in the bootloader software? To tell it to stop using PD5 as a default/automatic "TX LED"??

Ben

Here is an example of mapping / using many of those extra pins, including PD5

See the readme in that repo for instructions on replacing your pins_arduino.h file with the one provided.

This, for example, maps PD5 to Digital Pin 30. I am using it successfully with the Lillypad Arduino USB bootloader (this badge uses an external 8 MHz crystal)

Sorry for my english, i just have again this problem on 1.9.0 arduino ide beta version that i can not use this pin again as an output and input, with previous ide versions i just modified the pins_arduino.h on Arduino\hardware\arduino\avr\variants\leonardo, try my h file version, maybe can help someone, on the code just call the pin as "31" for PORTE2.

pins_arduino.h (9.7 KB)