Home > microcontrollers, PIC32, programming, RF, RFM22 > RFM22 Programming tutorial – PART #2

RFM22 Programming tutorial – PART #2

RFM22 internal registers
When you look into datasheets, you may feel a little bit lost 🙂
Yeah, there are near 127 registers in this little module, but many of them are set-and-forget ones.
Moreover, there are MSExcel spreadsheet calculators, providing you with set of calculated values for
your RFM22 module. You only have to enter desired transmittion parameters.
Look at : Calculator for Vx silicon revision
Calculator for A0 silicon revision
Calculator for B1 silicon revision

To determine your RFM22 chip’s silicon revision, read register at 0x01.

More important registers are (these you should become familiar with, these needs frequently changes during operation):

  • 0x02 – Device status register
  • 0x03 – Interrupt flags register #1
  • 0x04 – Interrupt flags register #2
  • 0x05 – Interrupt enable register #1
  • 0x06 – Interrupt enable register #2
  • 0x07 – Mode of operation register #1
  • 0x08 – Mode of operation register #2
  • 0x72 – Frequency deviation / AFC limiter
  • 0x02 – Device status register

  • ffovfl – FIFO overflow, you’ll see this, when you try to upload more than 64 bytes into TX FIFO, or module receives more than 64 bytes or you didn’t downloaded RX FIFO in right time.
  • ffunfl – FIFO underflow, set, when module is trying to send more data than is in its TX FIFO (eg. you’ve set longer packet than you uploaded into TX FIFO)
  • rxffem – RX FIFO empty – module should awake with this bit set, self-explanatory, I think.
  • headerr – Header error – indicates corrupted header of recently received packet
  • freqerr – Frequency Set error – you’ve tried to tune RFM outside its operating range (240-930 MHz).
  • lockdet – Synthesizer Lock detected – RF synthesizer is working ok and locked to specified frequency… rather informative/diagnostic than useful in everyday work 🙂
  • cps[1:0] – Chip Power State – indicates whether module is IDLE (00), RX (01) or TX (10)
  • Notes: Normally, there is a little need to read this register in FIFO Packet Handler mode. Frankly, I don’t pay attention to this register at all, using FIFO+PH.

    0x03 – Interrupt flags register #1
    0x04 – Interrupt flags register #2
    These registers are quite good described in the datasheet, all flags are more or less self-explanatory.
    Reading these registers clears indicated interrupt request and releases nIRQ line of RFM22.
    You should read them after nIRQ goes LOW.
    if (!nIRQ)

    0x05 – Interrupt enable register #1
    0x06 – Interrupt enable register #2
    When specific bit in these registers is SET, then asserting particular flag in 0x03/0x04 also drives nIRQ LOW.
    You should set ONLY these interrupts enabled, you’re interested in during current mode of operation, e.g. you should enable PKTSENT interrupt before entering TX mode – when nIRQ goes LOW you would know that packet has been sent, and you don’t need to check all interrupt flags. That approach would simplify your code to maximum extent.

    0x07 – Mode of operation register #1

    This is the most important register of the module.

  • swres – soft reset request – writing 1 to this bit would reset RFM22 to default state. You should do this after powerup of your system.
  • txon – TX mode ON – manual start of the transmittion. You should set this bit, after filling TX FIFO with data you want to send. Module will start transmittion and asserts ipktsent flag after sending whole payload. After transmittion module will fall into IDLE mode.
  • rxon – RX mode ON – manual start of reception. Setting this bit to 1 simply starts reception. RFM22 would wait for packet, receives it, checks its integrity and checksum and asserts corresponding flags (see 0x03,0x04 registers) during and after reception :
    ipreaval – valid preamble detected – asserted during reception of valid preamble. THIS IS THE MOMENT when you should save RSSI variable (content of 0x26 register) – that would indicates signal strength of transmittion.
    iswdet – synch word detected & match – module would assert this bit, when valid synch words are detected during reception of current packet, rather informative…
    icrerror – CRC error – received packet is corrupted – CRC calculated & received don’t match. You should respond to this IRQ with restarting RX mode (reset RX FIFO & set RX mode ON).
    ipkvalid – Valid packet received – this is the most wanted flag during reception – indicates that RX FIFO contains healthy data, just as you sent them on the TX side.
  • pllon – PLL ON during IDLE – leaves PLL working during IDLE mode – results in faster transitions between IDLE->RX and IDLE->TX modes. (PLL is tuning up for about 1 ms). With xton set would indicate TUNE-IDLE mode (higher current consumption ~9.5mA)
  • xton – XTAL ON – setting only this bit in this register would indicate READY-IDLE mode (low current consumption <1mA)
  • 0x08 – Mode of operation register #2

    This register controls mainly RX/TX FIFO buffers. Other settings are less important.

  • rxmpk – RX multiple packet mode – Once rxon set, the reception would continue, and RX FIFO would be filled subsequently after each valid packet reception. You can see ffovfl flag here. If rxmpk is cleared, RFM22 would fall into IDLE mode after reception of packet (either valid or invalid !!!)
  • autotx – Automatic TX mode – when set, module would enter transmittion mode each time TX FIFO is filled up to almost-full-condition. With this bit cleared, RFM22 would wait for txon bit set in 0x07 reg.
  • ffclrrx – RX FIFO Clear – to reset RX FIFO, you should write 1 and subsequent 0 to this bit. See code : send(0x08,0x02); send(0x08,0x00);
  • ffclrtx – TX FIFO Clear – accordingly, writing 1 and then 0 to this location would reset TX FIFO buffer and pointer.
  • 0x72 – Frequency deviation / AFC limiter
    Why this magic register is important? It depends on silicon revision of your RFM22 chip. When it is V2 (register 0x01 == 0x02) it has double function. In RX MODE it acts as Automatic Frequency Control Limiter – you should set this reg BEFORE entering RX MODE, according to calculated value. In TX MODE this register acts as Frequency Deviation register. You should write desired frequency deviation value BEFORE entering TX MODE.

    1. Daniel
      November 24, 2010 at 11:47 am

      Thanks a lot for the informations!

      I’m myself trying to communicate with a RFM22B module from an ATMEGA328P running at 8MHz (internal RC oscillator). Whenever I want to read from a given register address at the RFM module, I always get the contents at register 0x00. Whatever read gives me the response at 0x00.

      Does this tells you something?


      • November 25, 2010 at 9:38 pm

        Hmm… Maybe your SDO (atmega->rfm) line is tied to ground (short-circuit?) ?
        Have you checked your circuit against errors ?
        Have you tried to programm different values into 0x0b, 0x0c, 0x0d registers (GPIOx pin config) ?
        Or try to change 0x0a register (MCU clock divider) with values 0x00 – 0x07, and scope GPIO2 pin (MCU clock output by default).


    2. Daniel
      November 25, 2010 at 11:06 pm

      Thanks for your response.

      SDO is working well since I’m receiving valid register values (Reg 0x00 = 0x08, Reg 0x01 = 0x06, etc). In any case, the problem may be in the SDI line IMO. I’ve also tried to write different values at some locations without success – the burst read always return the default values. I should verify the MCU clock output as you suggest…

      On the other hand, I’ve read some posts where people complains about SPI problems between MCU and RFM modules. Thus, I’ve decided to bitbang the SPI by software, following the examples provided by HopeRF. I’m suspecting that sending the two bytes via hardware SPI is introducing some delay between address and value. Anyway, I’ll hook the oscilloscope this time in order to get a better idea about the problem.

      Thanks again for your ideas and tutorials,


      • November 25, 2010 at 11:23 pm

        Writing SDO (atmega->rfm) I had RFM’s SDI on my mind… just the manner of naming convention (host-centric or rfm-centric) 🙂
        Bitbanging RFM is always an option you should consider and try when things go wrong.
        As far as I recall, my PIC32-RFM22 library is using 8-bit SPI mode, thus introducing some small delay between address and value bytes, and it works properly. I don’t think it is a problem.
        I suggest :
        – double check your PCB/wiring
        – try bitbanging rfm
        – check for any reaction to register (0x0a-0x0d) change.

    3. Daniel
      November 25, 2010 at 11:32 pm

      Thanks again for your suggestions.

    4. Daniel
      November 29, 2010 at 3:26 pm

      I just wanted to let you know that I solved the problem. As you suggested, there was a shortcut that was pulling MISO down. Once the shortcut removed I’m now able to read RFM22’s registers without problems.

      Thank you very much.

    5. Daniel
      December 2, 2010 at 5:14 pm

      Sorry to bother you again with my questions…

      I have some problems with the RFM22 interrupts:

      1. enpksent from Interrupt Enable 1 (reg 0x05, bit 2) is correctly set but sending a RF packet is not making the nIRQ pin to go low. ipksent from Interrupt Status 1
      (reg 0x03, bit 3) does reports the interrupt properly.

      2. Once ipksent activated, Reading both Interrupt status registers (0x03 and 0x04) is not clearing any of the interrupt bits.

      I’m following your example but I’m surely forgetting something… Have you any idea about what I could be doing wrong?

      Thanks again!

      • December 2, 2010 at 10:11 pm

        Wow… That’s strange :/

        I’m assuming that your nIRQ line is correctly connected to MCU, without any shorts holding it up to H level…
        1. Is your nIRQ changing its state during operation ?
        2. Do you read status registers after enabling enpksent ?
        I have something like this on my mind :
        Write(0x05, 0x04); // enable enpksent
        Write(0x06, 0x00); // disable all other ints
        ReadStatus(); // read regs 0x02-0x04
        3. Can you observe any change on TX_ANT line after loading up the FIFO and setting mode to TX ?

    6. Daniel
      December 3, 2010 at 7:53 am

      Aaaagh!! A bad solder point again… on two different boards!! Thanks again!

      I’m now able to send/receive RF packets between both boards, even with the antenna unplugged.

      I’m also receiving a lot of valid-preamble (0xAAAA) traffic from the outside. I should maybe increase the valid preamble threshold to something longer than 20 bits 🙂

      • December 3, 2010 at 10:28 am

        First of all, you should always check all your tracings on board with universal multimeter (metering: diode/beeper) – this will save you about 90% time seeking errors of the project.

        Are you using FIFO+PacketHandler mode ? If so, you shouldn’t receive preamble bytes, ever! PacketHandler, when configured to use CRC, will respond with IRQ only after receiving healthy, correctly addressed (when using header bytes) packet!

    7. Daniel
      December 3, 2010 at 10:42 am


      Yes, FIFO’s and packet handling are enabled. As I wanted to know about my neighbors’ RF traffic,I enabled the “valid preamble interrupt” flag. I know that I can disable that flag anytime 🙂

      As for the shortcuts, I’m using SMD IC’s only and sometimes thin shortcuts are created without being detected by the multimeter, In other words, the multimeter does not beep but detects a resistance instead. I should look at the multimeter screen more often, instead of waiting for the beep only. Undesirable pull-ups or pull-downs often bring more problems than simple shortcuts 😦

      • December 3, 2010 at 10:58 am

        If you’re using your own etched PCBs – good PCB design & routing can save a lot of headaches. I’m routing my PCBs with 10 mils tracks (minimal width is 8 mils, usually enough) using termotransfer method of masking. When soldering, you have to use good solder flux. I’m using my own mixture of pine-tree resin (colophonium) in acetone. It has good properties, making shiny solder points and creates high surface tension of liquid solder, protecting from shorts between nearby pads and traces.

    8. Vianney Lecroart
      December 6, 2010 at 4:37 pm

      I used a RFM22-S 868MHz rev 2 in my test and it works fine.
      I tested it after with a RFM22*B*-S 868MHz rev 2 and not the test failed. I can send a packet but when I receive one, all I receive from the FIFO is 0xFF…

      Do you have an idea of what changed between RFM22 and RFM22B?
      In your test, which RFM model do you use?

      • December 9, 2010 at 7:08 pm

        Well, I thought that RFM22 and RFM22B are the same chips, but B version has more TX power (+20dBm)…
        I have no idea, why your test failed with *B version.
        I’m using RFM22 in my apps.

        On the first look at datasheet, RFM22B has AFC limiter & freq deviation register (0x2A, 0x72)… RFM22 (the revision I got) has shared 0x72 reg for this functions.
        But this shouldn’t have impact on basic functionality…

        Have you checked your wirings ?

    9. December 10, 2010 at 8:46 am


      RFM22B uses a Si4432 rev B1 and requires some changes to work.
      Some registers changed so they have to set different values depending of the revision. It’s so different that they provide different excel file to compute the register.

      My problem was in fact a stupid problem, the pin SDN wasn’t connected so it has a random state and half working.

      Now things go fine except that after a few minute of send/receive packet, during a send packet, the radio never send me ipksent interrupt so the mcu block in the while loop that wait the interrupt! I don’t know if it’s related to rev B1 or not but I never had that with ‘old’ RFM22.

    10. Daniel
      December 10, 2010 at 9:37 am

      Even if the ipksent bit remains cleared, is the nIRQ pin going low? If not, your RFM may be waiting for other interrupts to be cleared (valid preamble, CRC error, …) Have you tried disabling all interrupts except ipksent?

    11. vianney lecroart
      December 10, 2010 at 9:42 am

      I was not clear 🙂 The code is working fine 99.9999% of the time but one time, i had an infinite loop waiting the ipksent that never happen (nIRQ never gone low for an unknown reason).

      I’m not able to reproduce this “bug”, I only had it only one time for the moment after thousand packet sent correctly…

    12. Daniel
      December 10, 2010 at 9:52 am

      This has not happen to me yet but I assume that a transmission may fail for any reason. I’m too doing those endless loops whilst waiting for nIRQ to go low. Maybe we should include a timeout after which a transmission could be considered as failed…

    13. Daniel
      December 10, 2010 at 10:24 am

      Do you know how to sniff raw RF traffic with a RFM22B module? I wanted to sniff the complete packets coming from other RFM’s, including sync and header words but this is more difficult than I thought. “6.4.1. Packet Handler Disabled” in the manual seems to explain that clearing enpacrx (reg 0x30, bit 7) would let receive raw packets (without sync though) in the RX FIFO but this does not work. I’ve also tried clearing crcen and setting skipsyn (reg 0x33, bit 7) without success.

      • December 10, 2010 at 8:02 pm

        I’ve never did such things, but…
        Sniffing raw RF can be done via RX_ANT pin – but mcu will do a lot of work filtering noise and finding needle in a haystack…
        I don’t believe that interrupts corresponding normal activity of Packet Handler (valid preamble, valid sync, valid packet) would work with PH disabled…

      • xberger
        May 19, 2011 at 7:41 pm


        Even if the RX Packet Handling is disabled, you must define a synchronisation word and a preample length. But in this case, you should receive in the RX FIFO all the RAW data (NRZ coding) after the synchronisation word. I do it and it works for receiving one frame.

        But I don’t how to reset the synchronisation word detection and receive another frame. Have you a idea ?



        • May 4, 2013 at 4:19 am

          Will you please let me know what should be suggested hardware connection if we want to receive raw data ?


          • May 5, 2013 at 4:53 pm

            Frankly, I dont know for sure. I’ve never did such hw, never need it too. There are some comments here that may lead you to the solution.

      • Paul
        September 26, 2011 at 3:27 pm

        Can you help me? I need to sniff a ook protocol without preambe/sync.
        I want use the rfm22b as a “old” rf receiver.. reading the pulse in raw mode..

        • xberger
          September 26, 2011 at 4:07 pm


          You can use the Direct Mode. In this case, RX/TX data are available with the GPIO_x pins. for Direct Synchronous Mode, the Data Clock is available with a GPIO_x, SDO, or nIRQ pins.



    14. Daniel
      December 10, 2010 at 9:04 pm

      gobotronics :
      I don’t believe that interrupts corresponding normal activity of Packet Handler (valid preamble, valid sync, valid packet) would work with PH disabled…

      That may be the problem… I’ll try polling the FIFO instead.


    15. vianney lecroart
      December 13, 2010 at 5:09 pm

      In your code, you use “rfm22_last_rssi” can you tell us the value you get in your test?
      For mine, with a distance of 30cm between the rx and tx antenna, I have 55 that correspond, with the graph in the datasheet, to -95dBm.

      • December 14, 2010 at 6:08 pm

        rfm22_last_rssi depends on :
        – tx_power set at TX side
        – antennas you’re using … (probably the most important factor)

        During my tests, I’ve managed to get values about 0xB0-0xD0, with 1/4 lambda antenna made of single wire in insulation @ 868MHz.

        Using 1/2 lambda antennas I obtained poor results (about 0x60-0x70).

        Try using different antenna and verify your TX_POWER settings.

        To be full legal, using +17dBm tx power, you should implement frequency hopping algorithm, to free up spectrum you’re using, and which is shared quite frequently..

    16. P.
      December 9, 2011 at 2:26 pm

      did you get the RX direct mode (GPIO out) working? I tried it with an RFM23B, but it doesnt receive anything. Maybe, some registers are set wrong. Do I have to set FIFO stuff, AFC, etc. if i dont need these in direct mode?


      • Anonymous
        December 9, 2011 at 3:05 pm

        I did not play with direct modes, so I have no idea how to set it up.
        Why do you need it ?

    17. P.
      December 9, 2011 at 7:17 pm

      transmitting in direct mode is working perfectly, but i cannot receive anything though playing with all registers and values.
      the idea behind the direct mode is to get a real time bitstream to your microcontroller to decode it manually. This way, the RFM should work like the simple RFLINK Modules.

    18. Anonymous
      December 9, 2011 at 7:51 pm

      Yeah, I got the idea. As I think you need to transmit long bitstreams, but I doubt about the stability of transmittion… Anyway you would have to pack the stream into packets, checking checksums etc… or you are designing application that allow losses of data…
      Anyway, FIFO has nothing to do with direct mode. Have you checked WDS (silabs) for some info about direct mode ? (RF22/23 chip is equal to EZRadioPro)

      • P.
        December 9, 2011 at 9:00 pm

        thanks for the information with EZRadio, there are several useful App notes 🙂

        I am trying to switch these cheap “wireless eletric sockets” (hard to translate to English) and receive their signals, so that I know, when someone switched them with the standard remote control.
        Pakets are short and predefined, thats not the problem. Just receiving these data packages is kinda hard.
        In AN537 I found this statement: “All that is required to place the
        chip into RX Direct mode is to configure one of the three GPIO pins as the RX Data output function” but also this one “The Preamble and Sync fields must still be present in the packet
        structure, as the RFIC relies upon these fields to acquire bit timing, perform automatic frequency correction (AFC),and to qualify a valid signal.”
        So, is it possible to directly output all sort of data, even a modulated DC Signal (continuous 1)? There are no preample or any sync bits…


    19. January 1, 2012 at 6:12 am

      I’ve been using the RFM22B with a Atmega328P with Arduino bootloader and the RF22 library from http://www.open.com.au/mikem/arduino/RF22/ and so far it has been working, but I haven’t done any much in depth testing yet. Thanks for this info, I think it will be helpful as I go through and verify and check the code in the RF22 library.
      The board I’m working on will use the RFM22B to make a generic wireless UART link.

    20. Jon
      March 5, 2012 at 5:50 am

      I was curious to know what your register reset values are. I have 2 transceivers and both have slightly different reset values. For example the FIFO access registers have different reset values. Also, I immediately get a FIFO almost empty interrupt even if I set the threshold to zero and reading the interrupt status registers does not clear it. After just writing one byte into the FIFO, I get the overflow flag and also the FIFO almost empty flag, which is counter-intuitive. Clearing the FIFO clears the overflow flag though. This happens on both transceivers so I’m beginning to suspect a problem with my method. I’m able to write to and read every register except the FIFO access register. When i try to read them I just get the default values despite writing to then. Any hints on what’s going on?
      Thank you.

      • March 24, 2012 at 7:51 am

        Can you show us your register values ? make a reg-dump using procedure like this one :

        void regdump()
        int i;
        putsUART1(“RFM22 regs : \n\r”);
        for (i=0;i<0x7F;i++)
        putsUART1(" = ");

        rfm22_StartBurst, EndBurst and BurstRead to be found in rfm22.zip library…

    21. Jim
      December 14, 2012 at 1:45 pm

      A quick query really. You mention that on the Rev V2 silicon that reg: 0x72 has a double purpose as the AFC Limiter register. However when I look at the Silicon Labs V2 datasheet it does not mention it at all. Can I ask where you found that information ?

      • December 14, 2012 at 6:51 pm

        Frankly, I don’t remember where I got this info, but the latest version of my lib contains following code in initialization proc :

        if (rfm22.type.DVC >= 0x06)
        // no workaround-version... two different registers for AFC limiter & freq-deviation range

        And go_tx() and go_rx() functions are defined as follows :

        void rfm22_go_tx(void)
        rfm22_Write(0x07, 0x03); // tune mode
        if (rfm22.type.DVC<0x06) // afc/dev workaround for earlier EZRadios
        rfm22_Write(0x72, rfm_freq_dev);
        rfm22_Write(0x07, 0x09); // go TX


        rfm22.state = RFM22_TX;
        rfm22.tx_state = RFM22_TX_TRANSMITTING;

        void rfm22_go_rx(void)
        rfm22_Write(0x07, 0x03); // tune mode
        if (rfm22.type.DVC<0x06) // afc/dev workaround for earlier EZRadios
        rfm22_Write(0x72, rfm_afc_limit);

        rfm22_Write(RFM_IER1, 0x03); // enable RX PKT valid & CRC-error int
        rfm22_Write(RFM_IER2, 0x00); // DISABLE ALL : /// was: enable IPVD & IREA - valid preamble detected (RSSI measuring)
        rfm22_Write(0x07, 0x04); // enable RX chain

        rfm22.state = RFM22_RX;

        Resuming, after DeviceVersion >= 0x06 these registers are split in different location, before 0x06 – shared at 0x72 reg.
        I wrote this code months ago, it works for me, I have no way to check its hardware manner. Modules programmed with this code communicate each other at long distances (~500m) (I’m using it for controlling flying models, half-duplex communication).

        I hope it helps somehow.

    22. Laurent
      April 2, 2013 at 1:32 pm

      I’m fighting since several weeks to get RFM22B S2 433Mhz modules working with a PIC (18F2620) µC.

      I can’t get the communication working.
      Would someone be kind to share a simple working code for PIC please ?
      I would help me a lot.

      Many thanks,

    23. Brian Hanley
      May 21, 2013 at 11:35 pm

      I’d really like to try working with these RFM22B modules. I was looking at a breakout board for them (saves me soldering them) and I’ve found one I quite like, as it has an SMA connector for the antenna http://modtronicsaustralia.com/shop/rfm22b-s2-rf-transceiver-breakout-board-v2/. Anyone tried it? Or know of a better setup board?

    24. Ian Daintith
      December 19, 2014 at 4:33 pm

      Hi, I finally got the HopeRF23b to receive 434 OOK in Raw mode. Config below. Hope this helps someone.

      void SPIHopeRF1Init(char power)
      volatile BYTE Dummy;

      SPIRF1_SDN_IO = 1;
      SPIRF1_SDN_TRIS=0; // make sure SDN is low = power on.

      SPIRF1_SDN_IO = 1;
      SPIRF1_SDN_IO = 0;

      SPIRF1_CS_IO = 1;
      SPIRF1_CS_TRIS = 0; // Drive SPI Flash chip select pin

      SPIFLASH_SCK_TRIS = 0; // Set SCK pin as an output
      SPIFLASH_SDI_TRIS = 1; // Make sure SDI pin is an input
      SPIFLASH_SDO_TRIS = 0; // Set SDO pin as an output

      SPIHopeRF1Write(0x06, 0x00); // interrupt disable
      SPIHopeRF1Write(0x07, 0x01); // to ready mode

      //read interrupt status registers to clear
      // the interrupt flags and release NIRQ pin
      Dummy = SPIHopeRF1Read(0x03);
      Dummy = SPIHopeRF1Read(0x04);

      // Set crystal osc load capacitance
      SPIHopeRF1Write(0x09, 0x7F); // cap = 12.5pf

      // Set frequency to 434
      SPIHopeRF1Write(0x75, 0x53);
      SPIHopeRF1Write(0x76, 0x62);
      SPIHopeRF1Write(0x77, 0x00);

      // packet handler
      SPIHopeRF1Write(0x35, 0xF8);
      SPIHopeRF1Write(0x71, 0x63);

      // set to avoid false packet detection
      SPIHopeRF1Write(0x30, 0x84);
      SPIHopeRF1Write(0x32, 0x0F);
      SPIHopeRF1Write(0x33, 0x77);
      SPIHopeRF1Write(0x08, 0x10);

      // packet handler settings
      SPIHopeRF1Write(0x35, 0xF8);
      SPIHopeRF1Write(0x71, 0x63);
      // set GPIOs
      SPIHopeRF1Write(0x0b, 0xD4);
      SPIHopeRF1Write(0x0c, 0xCF);
      SPIHopeRF1Write(0x51, 0x36);
      // Set Non default registers
      SPIHopeRF1Write(0x69, 0x60);

      // Modem Parameters
      SPIHopeRF1Write(0x1F, 0x00);
      SPIHopeRF1Write(0x1C, 0xC7); // 412.1 KHz BW
      SPIHopeRF1Write(0x20, 0x7D);
      SPIHopeRF1Write(0x21, 0x63);
      SPIHopeRF1Write(0x22, 0x86);
      SPIHopeRF1Write(0x23, 0x25);
      SPIHopeRF1Write(0x24, 0x01);
      SPIHopeRF1Write(0x25, 0x08);
      SPIHopeRF1Write(0x2C, 0x18);
      SPIHopeRF1Write(0x2D, 0xD0);
      SPIHopeRF1Write(0x2E, 0x2E);
      SPIHopeRF1Write(0x71, 0x69);
      SPIHopeRF1Write(0x70, 0x0E);

      // Turn Receiver ON
      SPIHopeRF1Write(0x07, 0x04);

    25. Monica
      April 28, 2015 at 7:28 am

      Hi! I need to work with the RFM22 module and I’m a newbie when it comes to making radio communication. So far the information peresented was extremely helpful but I am not able to access the library from the website. Could you please upload it on a new server? Thank you!

    26. April 28, 2015 at 3:25 pm

      Link updated.
      also here:

    27. Florin
      May 6, 2015 at 3:54 pm

      I have one RFM22B module in my drawer and I’d like to make a radio beacon from it. There is a lot of info about using RFM22 for transmitting data in many complex ways but there is nothing about transmitting a simple FM modulated audio tone in FSK mode. I am an AVR advanced beginner a learned a few things about SPI transmission, I even managed to write a small program for sending commands to other FM chip with an ATTINY13. But with RFM22 I just got lost in so many control registers.
      Could you sketch please, a pseudo code for initializing RFM22 in order to be able to trasmit an audio tone in FSK mode? I know that using RFM22 for this simple task is kind of overkill but I need the ability to variate the TX power from time to time.

      Thank you!

      • May 6, 2015 at 6:51 pm

        Hmm. Why would you like to transmit audio tone via RFM22 ? Its designed to send “high-level” transmittion. FSK modulator is internally controlled by TX shift register, which, in turn, is controlled via direct pin-mode or via packet handler. Do you want to send digital audio data with this module? There is no options (to my knowledge) to send analog audio with this one – why would you?
        Why you need to variate TX power? Using ISM band you should avoid continuous transmittion at all times. This band is specifically designed and open for non-licensed use with strong pressure on using short-time transmittions, with FHSS where aplicable.

        • Florin
          May 6, 2015 at 7:30 pm

          I want to build a radio beacon. If you know about radio fox hunting this explains all if not .. on short, this is a tiny low powered device that emits short audio modulated tones in 433Mhz band. Like this one: https://www.youtube.com/watch?v=_TkplgAwzxE. I built this using a cheap OOK RF transmitter but in terms of modulation OOK is somehow like AM (amplitude modulation) and sound is not very clear, because the ham radio I am using as a receiver knows FM only. OK, so what is the purpose of this radio beacon. I am an RC modeler and sometimes my planes go further and eventually got lost. Such a functional beacon (for many days would be better) gives me the necessary time for search and rescue by tracking the radio signal with a directive antenna. So I need something tiny, with small consumption (the received audio beeps have large pauses between them and also this tones will have different RF power output (when approaching the beacon the signal is almost everywhere).
          My plan:
          The audio tones will be produced with attiny13 and they will be fed into RFM22. The same mcu will be in charge to sent the right commands to the registers by SPI (attiny13 can’t do hardware SPI but I managed to make unidirectional SPI. I don’t understant very well what registers in RFM22 do I have to load with words in order to fulfill my goals. I think of few necessary registers: 0x07, 0x71, 0x75, 0x76. As I mentioned, the modulation must be FSK, those beep should hear better into the FM radio. And finally, between the beeps would be large pauses (15-20 seconds) and all time both the host MCU and RFM22 will be in their lowest power consumption mode.
          This is what I want to achieve. Any help would be appreciated.
          Thanks again.

    28. Florin
      May 6, 2015 at 7:34 pm

      I forgot to mention that the audio beeps will be in fact 50% duty cycle PWM bursts generated by Attiny13, so indeed, no analog beeps. But as I told you, translating OOK ans FSK in analog radio world, FSK sound best in FM mode and OOK in AM mode. My radio is FM so I must build something for it.

    29. May 7, 2015 at 4:03 pm

      I’m RC modeler too, and I’ve found another way. I’ve bought old Graupner FM414 and stripped down whole electronics. I’ve substituted my own board with PIC32MX and RFM22 as a RF part. RFM is doing bidirectional communication with receiver, also stuffed with RFM22. TX is sending channel positions and after each packet is waiting for incoming data from RX. RX after response is sending info packet with few params like battery pack voltage.
      RFM22 has something like RSSI measurement, after each packet reception you can read RSSI register that holds received signal strength of last transmittion. This may give you a info about distance (not directly related, of course, but with some approximation) between TX and RX modules. Of course you can fit a small & cheap GPS module into RX and send model position via RFM back to your land equipment. There are many posibilities…

    30. Florin
      May 7, 2015 at 5:35 pm

      Yes there are many possibilities but I still want to build just a simple RF beacon :). The reason: a small long life independent powered beacon worth more than a trusty telemetry system. You say you are a RC modeler too, so you know about FPV. I am using a few such systems and believe me that foamy little plane has 3 RF links: telemetry, video with OSD and the main RC. On top of all is the autopilot that never let me down (until now). But no matter how much sophisticated gear an RC plane would carry, in the situation of a crash everything is very, very likely to get destroyed or unpowered. So now comes my tinny little beacon independently powered from a coin cell that is virtually indestructibly and that could transmit days or even weeks its audio signal. These gives me the chance to search more days (on fields, woods etc.), not only until the main power battery of the plane would eventually die (if I got lucky and the plane survived the crash).
      I hope now I was convincing about the utility of a RF beacon 🙂
      Anyway, I’ll try to power the RFM module, I will study more focused the datasheet and by trial and error I hope I could make it serve my purposes.

    31. Anonymous
      May 19, 2015 at 12:56 pm

      Hi, I am back. I manage to control the RFM22B module eventually. Feeding an audio range PWM signal into it is leading to a nice beeping radio beacon.
      Now I can’t solve this problem: after beeping I must turn off the carrier wave, I have 2 options: put SND pin to High or putting FRM22 into one of the Idle modes (Standby). I’d prefer the second option as the register’s content will not lost.
      OK, as in datasheet says, writing register 07h with “0x00” would turn off the transmission. But it doesn’t. This is what I don’t understand. I have to mention that this thing happens only if I try to put RFM22 into Standby mode AFTER I previously had it into TX mode. If I try to put FRM22 into Standby after power cycling it works but this doesn’t help me at all.

      Finally, here is the registers I used for making the RFM22 to transmit:

      0x0B, 0x30 //GPIO set to TX_data
      0x07, 0x0B // txon, pllon, xton to High
      0x6D, 0x04 // 8db TX power

      0x71, 0x00 // FSK modulation, Direct mode modulation type
      0x72, 0x05 // Frequency deviation

      0x75, 0x53 // TX frequency
      0x76, 0x37
      0x77, 0xA0

      But what do I have to change in order to stop the transmission? I already changed 0x07 to 0x00 but no result.


      • May 19, 2015 at 1:53 pm

        Which pin are you using to feed the signal ?

        • Florin
          May 19, 2015 at 3:30 pm

          I am feeding the signal on GPIO_0 pin.
          By trial and error (I admit it might not be the best way to get a result) I fed the PWM signal to RX_ANT and TX_ant pins. I don’t know how but the modulation was OK in combination with certain 71h values modulation. But as I learnt later, the direct modulation must be fed through one of the GPIO pins (at least this is what I understood). I also must say that the PWM signal is interrupted from time to time so there is no modulation signal all the time.

          • May 19, 2015 at 4:09 pm

            Hmmm, you’re using direct mode – in this mode, data provided via GPIO_0 is treated as digital stream and modulated according to modtyp register setting, eg. GFSK, FSK or OOK, but you wont have an access to physical modulator input.
            Look at Si4430-2 datasheet (https://www.silabs.com/Support%20Documents/TechnicalDocs/Si4430-31-32.pdf), on page 2 you’ll see functional diagram, there is no direct access to modulator, you’ve to go through digital logic. This module is strictly designed to send digital data.

            Using your setup should work, setting 0x07 to 0x00 should end transmittion, if not then recheck your SPI communication.

            What equipment you gonna use for reception of this signal ?

            • Florin
              May 19, 2015 at 5:46 pm

              Yes, RFM is meant to send digital signal and I assume a PWM signal, even is variable period, is a digital stream, right? I’ll post o short video for you to hear the beacon, the demodulated signal is very clean. I use a Wouxun UV6D radio.

              • May 19, 2015 at 6:18 pm

                Ok. Have you checked that setting 0x07<=0x00 doesn't stop transmition?

    32. Anonymous
      May 19, 2015 at 7:04 pm

      I just came from a friend, he has the equipment for some measuring. I was in doubt if my module is really a RFM22B and not RFM23B (it looks like many RFM23B pictures on the internet, with the little RX/TX switch) even if the PCB is marked as being RFM22B the power was not +20dbm but lower. Anyway, the RF carrier TX output power was 16,5dbm so over the RFM23B limits.
      This is how the beacon sounds:

      This is how is looks my module:

      Some measurements:


      But back to my problem with putting RFM22B into Standby mode… I am making some changes to my code, adding a little delay between changing modes and I’ll report back if 07h = 0x00 will stop the transmission eventually.
      The SPI part of my code is software emulated (bit banging on ATTINY13) and as far as I checked it with the logic analyzer and the oscilloscope the wave and timing are OK. The fact that the RFM22B TX frequency is set correctly (as calculated in the Excel calculator) makes me think the SPI thingy is working properly.

      • May 19, 2015 at 7:13 pm

        Your module seems to be a RFM22 – this little 6pin chip is a additional PowerAmp in HF circuit. RFM23 does not need this one (at least those I’ve seen).
        Proper timing commands to RFM is essential, but I don’t have a good recipe. My code works on PICs 32MX series properly. It is always good idea to add some delays after SPI_cmd() for debugging purpose.
        I’d suggest to implement SPI_read procedure for additional verification/debugging purposes – to check if write command successfully set requested bits in register.

    33. Ziro
      June 18, 2016 at 9:47 am

      I have problem with addressing the registers on Si 4432. I’m using STM32F3 board, and I’m pretty sure that SPI communication works fine. When I try to read the first register it returns the value of the second, when I read the second it returns the value from the third, etc.. When I try to read in burst mode it returns the value of every second register (example: read 3 registers starting on address 0x00, it will read the registers 0x01, 0x03, 0x05). Also it does the same when I try to write to the registers.
      Does anyone have idea what can be the issue?
      Thank you!

      • June 18, 2016 at 1:06 pm

        I don’t know STM32F3, but I believe you’ve narrowed down the problem to 4432 only (ie. connected some other SPI peripherial that works ok, did you?). If so, then I’ve got no idea what is going on.

        EDIT: Also, is there something like 7-bit SPI transfer mode?

        • Ziro
          June 18, 2016 at 4:34 pm

          Yes, I’ve tested with other peripheral and it works ok. There is a 7 bit transfer mode, but I’m using 8-bit mode. Also I’ve tested on the other board and the results are same. The boards are RF4432-A.

          • June 18, 2016 at 6:43 pm

            Hmm.. There must be something that advances address pointer by 1 (eg. 0x00 byte) sent to 4432…. Do you have some kind of logic signal scope? Did you tried different SPI clock freqs? I don’t believe its 4432 related problem, although sometimes those modules are problematic to communicate with (but always its related to software or hardware problems)….

    34. September 19, 2016 at 3:01 pm

      Hey there. I’m having trouble with the preamble detection… I’ve set the preamble length to 64 bits and the threshold is 24 bits. Yet the ipreaval is never set to 1! rxon bit is cleared (valid packet found), but the ipreaval bit is never set to 1. What could be causing this problem?

      • Gobotronics
        September 21, 2016 at 11:54 am

        That was long time ago, but as far as I recall, when you have packet handler enabled the preamble detection may not be available. Why do you need to detect preamble? It seems you have PH enabled (packet detected ok).


    1. No trackbacks yet.

    Leave a Reply

    Fill in your details below or click an icon to log in:

    WordPress.com Logo

    You are commenting using your WordPress.com account. Log Out / Change )

    Twitter picture

    You are commenting using your Twitter account. Log Out / Change )

    Facebook photo

    You are commenting using your Facebook account. Log Out / Change )

    Google+ photo

    You are commenting using your Google+ account. Log Out / Change )

    Connecting to %s

    %d bloggers like this: