Blog
OpenEnergyMonitor

Arduino Leonardo (ATmega32U4) and RFM12B


I've just managed to get an RFM12B hooked up to an Arduino Leonardo. It's been a bit of port mapping nightmare!

The ATmega 32U4's  'special function' ports such as PWM, IRQ, SPI etc are quite different to the ATmega328. The Arduino port mapping table proves very useful, if a little difficult to interpret. I made a re-arranged table with the ports re-arranged into function groups. I'll publish it once I've tidied it up.

Once of the main differences is that the hardware ISP connections are no longer on digital pins 10,11,12 and 13. On the Leonardo they are

MISO -  Digital 14
SCK -   Digital 15
MOSI - Digital 16
SS -      Digital 17 

Unlike on the Arduino Uno These SPI pins are not accessible through any of the digital I/O pins, on om the Leonardo, their only accessible through the ICSP header. The SPI SS pin on the Leonardo is not broken out anywhere on the board, strangely it's used for the Rx LED. Can anyone explain why this is the case? It's not a big problem, we can use another pin as SS, digital 10 in this case.

The IRQ Interrupt connection is made to Digital 3 (INT0). This has moved from Digital 2 on the Arduino Uno.

The SEL connection is the same as with the Arduino UNO/ATmega328 goes to digital 10.

See the RFM12B documentation page for general info on RFM12B and details of how to interface with ATmega328: http://openenergymonitor.org/emon/buildingblocks/rfm12b-wireless . 

Arduino Leonardo Connections to RFM12B via JeeLabs RFM12B breakout for level shifting to 3.3V
ICSP Header
Now the hardware is complete it's time to tackle the software. We use the RFM12B driver as part of the JeeLib library from JeeLabs: https://github.com/jcw/jeelib. The library needs to be installed in the Arduino library's folder in the usual way. Arduino 1.0.1 is needed to be compatible with Leonardo.

To make the JeeLib library work with the Leonardo and RFM12B (hooked up as above) the following needs to be inserted into the RF12.cpp file on line 62 before the else // ATmega168, ATmega328, etc.


No change to RFM12.cpp is needed, just download the latest version, see update below.

#elif defined(__AVR_ATmega32U4__)


#define RFM_IRQ     0   //PD0, INT0, Digital3 
#define SS_DDR      DDRB
#define SS_PORT     PORTB
#define SS_BIT      6   //Dig10, PB6


#define SPI_SS      17     // PB0, pin 8, Digital17
#define SPI_MISO    14     // PB3, pin 11, Digital14
#define SPI_MOSI    16     // PB2, pin 10, Digital16
#define SPI_SCK     15     // PB1, pin 9, Digital15


I'm going to send JCW a git pull request to see if these changes can be integrated into the JeeLib library so it should work 'out of the box' in the future.

Update: Pull request has been merged, RF12 part of JeeLib Arduino library now has ATmega32U4 support :-) . Download it here: https://github.com/jcw/jeelib

For a simple RFM12B transmission demo/example see: https://github.com/openenergymonitor/RFM12B_Simple

I'm planning on using the ATmega32U4 in the emonTx SMT that I'm currently working on. Spot the common thread in my last few blog posts! To engage in discussion regarding this post, please post on our Community Forum.