Working RFM22 Library

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 RFM22B-S2 SMD Wireless Transceiver - 434MHz - WRL-10153 - SparkFun Electronics 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 pins Arduino pins Notes
GND GND
VCC 3.3v
SDO digital 12 in SPI terms, SDO is also called MISO - no voltage divider needed since 3.3v is high enough for the arduino to read HIGH
SDI digital 11 in SPI terms, SDI is also called MOSI
SCK digital 13
NSEL any other digital pin, I used 9 for one, and 10 for the other
NIRQ any IRQ pin, I used digital 3
SDN GND this 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(C is for Colin: Arduino and RFM22) for a repost of this comment with a pic or two, and github for the code GitHub - niloc132/arduino-rfm22: A c++ library for the arduino to talk to the HopeRF RFM22 wireless radio.
Sample sketch:

#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() {
  Serial.begin(9600);
  rfm22::initSPI();
  
  radio1.init();
  radio2.init();
}
void sendByte(uint8_t data) {
  // move to ready
  radio2.write(0x07, 0x01);
  
  // reset fifo
  radio2.resetFIFO();
  
  //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
  radio1.readAndClearInterrupts();
  
  // 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
  radio1.resetFIFO();
  
  // 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
    readyToRecieve();
    delay(50);
  }
  // Send the next chunk
  sendByte(i++);
  delay(1000);
}

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 :slight_smile: :slight_smile:
I'll try this library as soon as possible and let you know, thabk's!

Simon

also check out RF22: RF22 library for Arduino

mikem:
also check out RF22: RF22 library for Arduino

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.

Thank's!

Simon

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:

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.

Although this is a very old post now, however today I will start playing with this library and see how it goes; I will provide detailed feedback about my experience with it.

Thx for the library again.

One thing I can tell now after reading the library in details, the library is very well written (code wise). It is a clean code, and I think you are missing a declaration for variable i, something like:

uint8_t i=0;

After placing the definition for "i" the library compiled nicely, now I will upload and provide further details.

Regards.