Go Down

Topic: Working RFM22 Library (Read 9701 times) previous topic - next topic


Jan 30, 2011, 06:44 am Last Edit: Jan 30, 2011, 05:40 pm by niloc132 Reason: 1
I've put together a simple RFM22 library based on the sample code at sparkfun and some google-translate assisted reading at http://www.3e-club.ru/view_full.php?id=19&name=rfm22. I've used this with the now-retired RFM22 purchased from http://www.sparkfun.com/products/9581, configured to operate at 434 MHz.

The replacement model at http://www.sparkfun.com/products/10153 should work more or less the same, but I won't know for certain until I have burned through my remaining 6 radios.

The device operates at 3.3v, as opposed to the 5v that most Arduinos seem to operate at. I used the diagram from http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1206874649/1 to set up SPI to talk back and forth to the device, operating from the apparently correct assumption that if it works for one SPI 3.3v to 5v system it will work for another. I haven't done anything too serious with this, but with both radios on the same board I can tell one to listen, push data into the FIFO of the second and trigger a TX, and be told by an interrupt that the first has gotten data. Soon I'll have a second avr to run with the second radio from another board, and start playing with how much data I can push back and forth, and from what range.

A few tricks I have learned from playing with this: SDN (shutdown) must be dealt with. If you leave it unconnected and 'floating', it will intermittently work and stop working, including allowing corrupt data to flow back and forth to the main board. For several weeks I did battle with a single register on all the radios I had soldered up which would subtract one from the top 4 bits I would write in... Very frustrating.

RX_ANT, TX_ANT appear to be unnecessary, making for an easier time of soldering the thing up. Same goes for the GPIO (general purpose I/O) contacts - I am sure some projects can make excellent use of them, but thus far leaving them alone has served me well.

From the datasheet, my connections:

RFM22 pinsArduino pinsNotes
SDOdigital 12in SPI terms, SDO is also called MISO - no voltage divider needed since 3.3v is high enough for the arduino to read HIGH
SDIdigital 11in SPI terms, SDI is also called MOSI
SCKdigital 13
NSELany other digital pin, I used 9 for one, and 10 for the other
NIRQany IRQ pin, I used digital 3
SDNGNDthis sets the device to stay on until power has been lost

I'd be happy to offer the code for people to play with, but all I can say at this point is that it works for me, with two radios on the same board with no antennas. The code will be available via git in the near future.

Err... Uploads dir for new forums is apparently no writable, so try my blog(http://www.cisforcolin.net/2011/01/arduino-and-rfm22.html) for a repost of this comment with a pic or two, and github for the code https://github.com/niloc132/arduino-rfm22.
Sample sketch:
Code: [Select]

#include <SPI.h>
#include <RFM22.h>

rfm22 radio1(10); // radio 1 with NSEL on pin 10
rfm22 radio2(9);  // radio 2 with NSEL on pin 9

void setup() {
void sendByte(uint8_t data) {
 // move to ready
 radio2.write(0x07, 0x01);
 // reset fifo
 //write data (bursted, but it is only one byte) to the FIFO reg
 radio2.write(0x7F, data);
 //move to TX mode to send
 radio2.write(0x07, 0x09);
 //wait until sent...
 //move to ready
void readyToRecieve() {
 // move to ready state
 radio1.write(0x07, 0x01);
 // clear existing interrupts
 // set up interrupt to list to
 attachInterrupt(1, radio1_int, LOW);//1 is digital pin 3
 radio1.setInterrupt(RFM_INT_PKVALID, RFM_INT_PKVALID);
 // clear out the fifo
 // move to read mode
 radio1.write(0x07, 0x05);
char data_recieved = 1;
void radio1_int() {
 data_recieved = 1;
void loop() {
  static int i = 0;
 if (data_recieved) {
   // reset the flag
   data_recieved = 0;
   // Print the last recieved chunk (one byte)
   Serial.println(radio1.read(0x7F), DEC);

   // Tell the listener to be ready
 // Send the next chunk

EDIT: I made copying error in the code, such that the code would not compile, and if it did, every byte written to serial read '42' instead of continually incrementing. Should be fixed now.


I've put together a simple RFM22 library

Now, if you could put together a RTFM library, that would be really cool.


I've started some weeks ago a thread asking help with these modules, also this thread couldn't not make me happier :) :)
I'll try this library as soon as possible and let you know, thabk's!



also check out http://www.open.com.au/mikem/arduino/RF22


also check out http://www.open.com.au/mikem/arduino/RF22

Thank you Mike!
I'll try this library too! I'm landed on your page some months ago, when I've started to take a look around for some libraries, but I've seen only the HopeRF library which was not the right one.
I'll let you know!
Meanwhile, I can connect without problems using the 3,3V VCC of my Arduino NANO? I'm a noob, also sorry for my stupid questions. Trying wiring it I've registered these values with an tester:

On arduino, pin 3V3 is @3,54V, also ok.
BTW on RFM22, looking on the datasheet (I've the RFM22-S1 page 141) the pins with Voltage:

VCC: 3,54
GPIO_1: 3,54
GPIO_2: 1,78
SDO: 3,47
SDI: 4,50 !!!
NSEL: 4,50 !!!
NIRQ: 3,55

Hope they are ok, 'cause the operating range should work up to 3,6V.
I've wired it like written by niloc132 or by you - are the same.



I know this thread is a little old, but can anyone tell me where this SDN pin is at? The schematics are different than what the breakout board says from sparkfun.

Any ideas?


According to the specs I have, labeled v1.2, there are three different packages available. The two SMD packages, S1 and S2 appear to have identical pin positions, with the DIP package having its own layout.

I have ten of the RFM22-S2, and the shutdown pin (SDN) is next to ground in the upper right.

It looks something like this:
Code: [Select]

ANT               GND
GND               SDN
RX_ANT            NIRQ
TX_ANT            NSEL
VCC         /---\ SCK
GPIO_0      |CLK| SDI
GPIO_1 [IC] \---/ SDO
GPIO_2            GND

If you're just starting out with the thing, consider tying the shutdown to ground, so that it never shuts off. Bringing that to VCC (or letting it float, sometimes...) will turn it off, one of the several lower power modes it offers. The first unit I played with worked well without messing with SND, but all of the others needed to bring it to ground, else it would behave intermittently.

Thanks for the quick reply.

Hmmm. The breakout board from sparkfun has the back of the board labeled like this

ant         rx
-             tx
gnd        irq
3.3        csn
gpio0     sck
gpio1     sdi
gpio2     sdo


So Im not sure what is going on there, considering the schematics from the manufacturer do not match what they have.


Ah yes - if memory serves, the breakout board already has the sdn pin tied to ground... Yep - take a look at the second to last image, http://dlnmh9ip6v2uc.cloudfront.net/images/products/10154-05.jpg, and see how in the upper left (chip is rotated 90° CCW from HopeRF's diagrams) has both connections wired together to one pin.

As the breakout is mostly for dev stuff, it would make sense to have it always turned on.

Well that is good to know.

I have one with a break out board and one with out. So the one without the breakout board matches the schematics and your example up above?


Correct - according to sparkfun's pictures, you've got the -S2 package, you should be able to compare where the traces go on the breakout to confirm the schematics.

Go Up

Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

via Egeo 16
Torino, 10131