Part 2 – RFM12 Hardware Interface
In this next part of the RFM12 tutorials I’ll be covering the hardware interface, signal descriptions and how you go about hooking it up to the MCU of your choice.
Packages
The RFM12 RF module comes in a couple of different packages, DIP and SMD, I’ll mainly be covering the DIP throughout these series, but will touch on the SMD where necessary. There is also a long range version of the RFM12B, this is the RFM12BP and has a reported range of 3000m. The RFM12BP only comes in an extended SMD package, but I won’t be covering it here in the tutorials, although all of the commands will be the same. The only difference is the RFM12BP has an on board power amp, which requires 12V to power the PA portion and has associated control pins for Tx/RX control.
DIP
The DIP package uses a 6×2 2mm pitch header to connect the various signals to the MCU, The size of this header is a bit of a problem if you want to do prototyping as it doesn’t breadboard well, initially I didn’t have any 2mmm pitch female headers so I hand soldered on individual wires to the back of each pin, not really good in the long run as the wires kept on breaking off, so I designed a breakout board to bring out all the signals onto a standard 100mil pitch, much easier to breadboard.
SMD
There are two version of the SMD module, and from what I can gather the only difference is the crystal, one is the standard HCU form factor, while the other is a ceramic oscillator.
Antenna: The only real difference when using the SMD over the DIP package is there is no on-board antenna connection, the antenna comes out via one of the pins, so you need to design in an antenna connection if using the SMD version.
ARSSI: The SMD package allows access to another useful signal that is not available to the DIP version, this is the ARSSI – Analogue Relative Signal Strength Indicator, which is basically the strength of the signal being received by the module, however it’s not bought out on any of the pins, beats me why? There a digital version of this signal accessible though the software interface, from what I can gather there is a difference from the Digital and Analogue versions of this signal. Anyway what it boils down to if you want to access this analogue signal then you have to manually solder on a wire to access this pad (shown as red circle).
UPDATE: the onboard DRSSI is a single bit returned in the status word that indicates if the RSSI is above the set threshold. The ARSSI hack mentioned gives an analogue value that is proportional to the RSSI signal received.

Antenna
The antenna mostly used will probably be a whip antenna, basically a piece of wire cut to the right length, I won’t be covering antenna theory here, as I don’t know it
, but suffice to say the approx lengths involved are as follows (measured from factory supplied antennas):
433Mhz – 173mm
915Mhz – 87mm
UPDATED: 03/07/2009
These antenna lengths are calculated for the respective bands
433 1/4 wave = 164.7mm
433 1/2 wave = 329.4mm
433 full wave = 692.7mm
868 1/4 wave = 82.2mm
868 1/2 wave = 164.3mm
868 full wave = 345.5mm
915 1/4 wave = 77.9mm
915 1/2 wave = 155.9mm
915 full wave = 327.8mm
With these lengths I’ve had no problem reaching 30m+ indoors through a number of walls and 120m+ outside, I’ve not yet trie different types of antennas such as SMA connected rubber duck type but they should work as I’ve spoken to tech support at HopeRF and they tell me that the antenna circuit on both modules is balanced to 50 Ohm, this means that most SMA rubber duck antennas in the right frequency range will also work. Make sure that the antenna is matched to the frequency range required to get the best range, i.e. don’t use a wifi antenna for 2.4GHZ on a 433Mhz module, it may work for short distances, but definately won’t be optimal for long distances, also you may damage your RF module (unconfirmed it this is is the case as these are low power devices), but usually antennas need to be SWR matched to stop reflectance back into the transmitter circuit.
There is also some technical documents on Hopes website for PCB based antennas, but I’ve not used these at all so your milage may vary with them.
As mentioned earlier the SMD has no direct antenna connection so you need to design in a connection, either a solder pad on your board or an SMA connector.
The DIP package on the other hand allows you to solder in the antenna right onto the module, usually you will solder in the wire directly, however you need to make sure that you get the right pad, as there are two very small solder pads right next to each other, one is the antenna, one is ground, both are not marked in anyway as to to their function, and the documentation does not show which one is which. You need to solder in the piece of wire to the one not connected to ground, best to check with a multimeter or continuity tester first.
It looks as though you can also uses these two pads on the DIP module to connect an external SMA connector with a pigtail to the module as well (both ground and antenna).
PIN Connections
The pin connections for the module is described below, I have indicated whether the connection is required or is optional when making connections. The basic connections as described will allow data rates of up to approx 12000bps on an 8Mhz PIC using a bit-bashed SPI, polled approach when handling sending and receiving data, higher data rates will require hardware SPI, higher MCU speed and the use of interrupts, these will be discussed in a later tutorial.
UPDATE: Please see this article for more detailed information regarding RFM12B bit rates and the different pin connections.
VDD (required) – The nominal working voltage is between 2.2v and 3.8v (NOT 5V), make sure that you have bypass filters in place on the supply rails.
nINT/VDI (optional) – This pin can be configured as either input or output, if configured as an input then it’s function is an active low interrupt request from the MCU, The MCU pulls this line low if it want to interrupt the RF module.
If configured as an output then its the VDI, Valid Data indicator, meaning valid data has been detected by the receiver and outputs a high. Factory Default is VDI
SDI (required) – SPI Data input, where the MCUs MOSI signal needs to be connected to.
SCK(required) – SPI clock input from MCU
nSEL (required) – Chip Select (active low). This signal must be pulled low before any signal is sent via SPI to the RF module,
SDO (required) – SPI Data out, where the MCU MISO signal needs to be connected to.
nIRQ (optional) – Interrupt Request output (active low), this is when the RF module wans to signal the MCU an event has occurred. This should be tied high with a pullup resistor.
FSK/DATA/nFFS (optional but requires 10K pullup when not used):
FSK – Transmit data input
DATA – Received Data output
nFFS – If pulled high then the FIFO is selected then data is transmited / received via the internal FIFO acessed via the SPI interface. If the FIFO is not being used then this is where the data is directly clocked into or out of the Tranceiver. Use this mode for high datarates.
DCLK/CFIL/FFIT (optional):
DCLK – is the data clock when no FIFO is used (used in conjunction with FSK/DATA/nFFS pin).
CFIL – is used to connect an external capacitor when using 256K datarates, this is for the analogue filter, normally the internal digital filter is used by default, only lower data rates are achieved with the digital filter.
FFIT – FIFO interrupt, interrupt signal is generated whenever the FIFO interrupt level is achieved (level is configured via SPI and is covered in the software interface tutorial), normally the interrupt level would be set to 8 if using the FIFO so that an interrupt is generated for every byte received. If using the FSK/DATA to clock in the data then the interrupt level should be set to 1, this way an interrupt is set for every bit sent/received.
CLK (optional) – Clock output, defaults to 1Mhz, but can be configured in increments up to 10Mhz, or switched off. This signal can be used to provide a clock signal to the MCU if it has no internal oscillator, i.e. cuts down on an additional crystal required for the MCU. This signal is also used in the calibration of the RF modules and will be explained later.
nRES (required) – this is reported in the Hope RF documentation as an output but is really an input (active low) and needs to be tied high at all times. If pulled low it will reset the module back to POR default (power on reset) settings.
GND (required) – Power Ground.
ANT (on SMD, required) – Where the antenna is connected.
Back – Part 1 | Next – Part 3a
Similar Posts:
- RFM12B Bit Rates and Throughput
- RFM12 Tutorial – Part 3a
- Preliminary RF Tests
- Introducing the RFM22/23, Big brothers to the RFM12B
- RFM12 Tutorial – Part1



June 30th, 2008 at 4:54 pm
Hi,
second part is also gr8. It help to clear a lot of concepts. waiting for the next part.Hope the controller u will use is AVR and programming will be in C language.
June 30th, 2008 at 5:02 pm
Yes working on the C for my Arduino, which is AVR based
Was actually just wiring up the RFM12B to the prototype board/shield as your comment came in lol
July 3rd, 2008 at 1:50 pm
Hi,
Stephen. Finally i have transmitted the data sucessfully using RFM12BP. i am reciving the data on hyperterminal of my pC. but there is still a small problem that is if I send numbers in sequince i.e from 1-9 it recives the odd numbers first and then the even one. i donot know y is this hapening if u can help me out with this problem .I know u will have some gr8 ideas for solving this problem. Thanks a lot dear.
July 3rd, 2008 at 3:07 pm
Well done! Please send me your code if possible, I would love see it.
The only thing I can think of is the TX levels maybe causing problems. How are close are the two units? The RFM12BP is for ranges up to 3000m so you may have to drop the Tx power right down to minimum and the Rx sensitivity down during development.
Are you doing any error checking with your packets? Such as CRC or a checksum? That way you can be sure that the packet you sent is the packet you received.
Also you may have to look at some forward error correction such as a hamming code, but I would not have thought it was needed for such small data streams.
July 4th, 2008 at 1:36 pm
Hi,
and useful tips too. My code is nearly same as the one given in the programming guide. if u still need give me ur mailing adress. the two modules are kept closer so,I think ur right I have to reduce the power. Also on some other website I have studied that these modules have no internal error correction and they say something about the SNAP protocol. Do you have any idea abt it? if any plz do share how to use this protocol with these modules. Thanks.
Thanks for ur appreciation
July 5th, 2008 at 7:57 am
None of the RFM12 modules have error correction, so you need to build that into you application. Just a basic CRC or checksum while testing should be ok, all depends on you application.
1) Build your packet
2) Do a checksum of everything, but not the sync or the preamble.
3) Add this calculated checksum to the end of the packet.
4) Transmit the complete
5) On the receiver you receive the packet containing the data and checksum
6) recalculate a new checksum on the received data using the same formula you used on the transmision side. Don’t include the received checksum in this calculation only the data.
7) if the calculated checksum and the received checksum are the same, then more than likely you have a good packet, if not then you have a corrupt packet and you either ignore the data or get it resent.
The snap protocol you are referring to, is S.N.A.P and is found here http://www.hth.com/snap/ this defines a simple network addressable protocol.
August 4th, 2008 at 7:30 pm
Just a note to thank you for these tutorials. After a couple of hours of coding and reading I have managed to get two of these devices communicating effectively.
Many thanks again.
Stephen (UK)
August 6th, 2008 at 9:50 am
Great to hear, thanks for the feedback
September 18th, 2008 at 1:22 am
Can you please tell me the difference between RFM12 and RFM12B ? (I noticed a VCC difference)
September 24th, 2008 at 12:41 pm
*reSpawn
Good question, I’ve only used the RFM12B variety, but from the looks of the data sheets you’re right, it only looks like a VCC difference. Even the chip programming guides looks the same.
Anyway I’ve asked just sent an email off to HOPE so “Hope”fully I’ll get a reply (lol sorry about that)
September 24th, 2008 at 1:42 pm
*respawn – you are half right
Response from Hope:
The differences between RFM12B and RFM12 are :
1.Sensitivity: RFM12 is -109dBm, RFM12B is -112dBm
2.Power supply: RFM12 is 2.2V-5.5V. RFM12B is 2.2V-3.6V
October 31st, 2008 at 2:31 pm
Hi
My name is nithin prakash, i recently started to work on RFM12BP, i have just established communication b/w RFM12BP modules. I have a doubt in the Power amplifier section. To the VCC-PA pin i have an input of 12V from a DC power supply. For the RF module that i am designing i want to give it a 5V supply, so know i am planning to introduce an voltage booster circuit i.e. 5v to 12v(say max1771). But if i connect a ammeter in series with the power supply the current drawn by the VCC-PA pin is at 0mA or 0A. I am doing continuous transmission for 10 seconds. The current consumption of the power amplifier is vital for the selection of voltage booster.
Thank you in Advance….
November 2nd, 2008 at 12:37 pm
Hi
My name is nithin prakash, i recently started to work on RFM12BP, i have just established communication b/w RFM12BP modules. I have a doubt in the Power amplifier section. To the VCC-PA pin i have an input of 12V from a DC power supply. For the RF module that i am designing i want to give it a 5V supply, so know i am planning to introduce an voltage booster circuit i.e. 5v to 12v(say max1771). But if i connect a ammeter in series with the power supply the current drawn by the VCC-PA pin is at 0mA or 0A. I am doing continuous transmission for 10 seconds. How can the current consumption be at 0A or 0mA?. The current consumption of the power amplifier is vital for the selection of voltage booster.
Thank you in Advance….
March 5th, 2009 at 4:36 am
heyStephen, will you post another tutorial, if that’s the case, I’m waiting for your next tutorial. Thank you so much!!!!!
March 5th, 2009 at 6:59 am
yes I Intend to finish the series. Currently I’m concentrating on the Strobit Triggr so I can have a board to play with.
March 17th, 2009 at 2:55 pm
Hi
I am looking into the RFM12B whether it is suitable for our project.This article helps me a lot.I have one question….
If my controller dose not have SPI interface means,How can I use RFM12B?
Please can any one help me?…
March 17th, 2009 at 3:27 pm
Hi subashini,
Yes you can still use the RFM12B without hardware SPI, you can bitbang your SPI interface, see the example pic code here on the forums http://forums.everythingrobotics.com/viewtopic.php?f=17&t=102
March 18th, 2009 at 8:23 pm
Hi,
Thank you for your clarifications…
I will work forward with this and get back to you…
April 14th, 2009 at 3:09 pm
hi.
can i send an modulated audio via Rfm12b?
if yes , how?
April 14th, 2009 at 8:47 pm
Only if you digitise it first, but I don’t think it would be feasible due to low bitrates, but if you use a codec run at low bit rates you might
May 1st, 2009 at 6:41 pm
thank you for your great tutorial. i cannot wait to see the next part. i am now working on this RF as well. and i think i did something wrong. will i burn the RF if i power it up as Vdd=5? and another question is do i need to connect a decouple capasitor to the antenna?
May 2nd, 2009 at 8:43 am
I have run the RFM12B at 5v with no apparent problems, however it is out of spec / at the upper limit so I wouldn’t run it permanently. The RFM12 is the 5V version.
No decoupling capacitor is required. The antenna is matched for 50 Ohms so it can connect directly to SMA or whip antenna (i.e. piece of wire at correct length)
May 2nd, 2009 at 10:30 am
oh~~ thank you for your reply. now i have felt much much better from worrying of burning all my buddies.
if so i think i have made the correct connection for the hardware. then the problem should dues to the software. so,stephen, have you tried the example 2 in the programming guide, since i use PIC16F877A. does this example have the same bug as example 1?(such as changing 0x82D8 to 0×8299).
and aspire for the part 3. they are great.
May 3rd, 2009 at 8:16 pm
no I haven’t tried the the second example, I ended up writing my own. I found their examples full of bugs. See http://svn.everythingrobotics.com/strobist/mk1/trunk/arch/pic16f88-boostc/src/test_rfm/ for some RFM12B Pic code
May 10th, 2009 at 3:21 am
Hello everyone. I recently bought the RFM12BP modules. Haven’t tested them yet. I am trying to get as much info as I can first. The BP type is different with these RX/TX Enable pins from the P version. What are these pins for when I can control the RX/TX functionality with software? Do I have to controll these pins (two pins more on micro), or can I just pull them both high? Great tutorial btw. Thx.
May 10th, 2009 at 9:25 pm
Hi Budilm,
Basically the RFM12BP is an RFM12B with a Power Amplifier added, this gives the extra range, and is also why it needs 12V and the control pins. You must control the pins when ever you Tx or Rx so yes you do need to have additional I/O control them via your driver software.
May 12th, 2009 at 3:37 am
Hi Stephen,
thank you for the reply. I found this info: http://micropet.me/blog/?p=5
Down there is a schematic of his board for the RFM12BP module. If you take a closer look you will find, that he simply pulled both controll pins for the RXEN and TXEN high. I wrote him a message but he did not reply yet so I dont know if it works. He writes also that the power amplifier section works with supply voltage from 0,5 to 13V but in the datasheet is 11V to 13V. Because I want to power my application from 3s LiPol battery (Voltage ranges from 9V to 12,5V) I am curious if the power section will still work with 9V? What do you think?
May 12th, 2009 at 9:24 am
Good question, I would suggest that you try it and see what happens. The only thing I think may happen is the distance stated in the Specs will be less.
May 17th, 2009 at 4:49 am
Hi, i just receive my RFM12 yesterday. Your blog have some good information. I’ll try to connect it with arduino, do you have some information about it?
Thanks
May 17th, 2009 at 9:45 pm
Good place for drivers for the arduino is here: http://code.google.com/p/jeelab/ download via SVN works well. Try the example first.
June 1st, 2009 at 2:17 pm
Stephen
for 915MHz, what is the correct antenna length?
You mentioned above is 87mm, but according to antenna length calculation, it is 77.949mm.
Tks.
June 10th, 2009 at 11:53 am
@bennyjo
The lengths I quoted I quote are from direct measurements I made of the antennas sent from HopeRF with the DIP version of the module. I would go with the calculated length over the measured one.
June 15th, 2009 at 3:36 am
Stephen
I am trying to use the ARSSI signal from the RFM12 as a type of rangefinder – your picture is a really good start. My RFM12 is slightly different – in this area (red circle) on my RFM12 I can see only an SMD resistor and a via-both alternate about 0.47V and aboüt 0.54V to ground when receiving an intermittant text string. What did you solder to to get the signal out? (Do you have a hires version image of this area on the module?)
Thanks
Martin
June 15th, 2009 at 9:19 am
@Martiv_v
The picture was sent to me by HopeRF when I asked the question regarding how to access ARSSI (thinking it was as simple as accessing the value via an internal registers) so I’ve not used it as yet.
Sorry but I don’t have a higher res photo, but looking at mine in front of me, it looks the same as yours, I have a resistor and a via, that is the same area in the photo in the photo.
I’ll contact Hope and see what their response is.
June 22nd, 2009 at 7:34 pm
I’ve also 4 RFM12BP modules and connected them to an Attiny2313 to send some data received from the serial port. My 2313 controls the data with the RFM12bp through SPI, just like in the example code. I`ve connected NIRQ,SDO,NSEL,SCK,SDI to my microcontroller.
When I powerup everything exept for the VCC-PA, I can see in an RF monitor that the module sends something at low power. But when I connect the VCC-PA pin to 12V, I expected a much higher RSSI value. (whithout +- -52dB with -42dB, transmitter and chipcon receiver both on same desk) but a much higher problem is that my power transistor on the module becomes very hot when the 12V is connected. Is somebody familiar with this problem? Can anybody show how the module should be connected when SPI mode is used?
June 25th, 2009 at 3:22 am
Stephen
Some feedback to the ARSSI signal: I wired the resistor pad as you suggested to an ADC (Mega32) and I get a pretty stable signal- (but only when I do the ADC sample right in the middle of the receive code loop- otherwise the signal is basically 0). At -21dB transmit power the raw ADC value (ref. 5V) ranges between 450 directly next to the transmitter and maybe 150 at about 20m range- so from ~2.2V to 0.73V. (reception cuts out at less than this.)Will see how this can be used for rangefinding in practise.
Thanks for the help
Martin
June 25th, 2009 at 8:31 am
@Martin
Ahh makes sense, I had actually wondered about this some time ago about the timing of reading the aRSSI in regard to Reception (as one does while lying in bed at 3am unable to sleep)
When are you doing the ADC reading, just before/after you process a received byte? or when you receive the INT from the RFM12?
Stephen…
July 1st, 2009 at 4:43 am
Stephen,
I have been using a modified version of the original code from Benedikt K and the BASCOM version from Joachim Fossie Bär Reiter (http://www.mikrocontroller.net/topic/67273- a German site). The relevant section looks like this:
Sub Rf12_rxdata(byval Maxchar As Byte)
Temp = Rf12_trans(&H82c8)
Temp = Rf12_trans(&Hca81)
Temp = Rf12_trans(&Hca83)
For Count = 1 To Maxchar
Rf12_ready
Temp = Rf12_trans(&Hb000)
Arssi = Getadc(0) ‘measure received signal strength in the middle of the receive loop
Rfdata(count) = Temp
Next Count
Temp = Rf12_trans(&H8208)
End Sub
So basically just after the transfer. This code uses only the 4 SPI lines – no interrupts- but works fine for low rate transfer.
Martin
July 3rd, 2009 at 8:42 am
Thanks for that Martin.
I might have a play around with it in the near future as I’ve allowed for an RSSI pad on my widget boards.
July 3rd, 2009 at 9:10 am
Just updated this article with calculated antenna lengths for all bands.
July 27th, 2009 at 11:07 pm
[...] were that simple…as mentioned previously that the RFM12 needs to be connected as described in the previous article via SPI, the second thing we need to do is access the the internal registers of the RFM12 for it to [...]
July 29th, 2009 at 1:37 pm
Hi StephenS
i m aamir i hve been workin on RFM12B module for the last six months.I first used AT89S52 controller and it worked fine.The RF was configured with some difficulty,Now i m using PIC16F726 but there is some trouble in communication with the RF via SPI.The controller is not communicatin with the RF and configurin it.I hve read urs code.i hve a simplified code written using the sample code given by HOPE RF for PIC.But tht code is not workin.I hve tryed alot but no succeess.The WriteCMD() function as written by u too in which u hve optimzed NOP() delay thts i think creatin problem.Do u hve problems with it too.Can u help me some how
thnxs
July 30th, 2009 at 12:32 pm
@Aamir
Have you tested the SPI to see if commands are getting through?
I test by hooking up a frequency counter or oscilloscope to the CLK and then I send through a change frequency command for the CLK. If that works then at least I know the SPI side of things is working. A point to remember is make sure that the SPI is within the specified frequency, I think is <=2.5MHz. If too low then you also may have problems.
Stephen…
July 30th, 2009 at 3:39 pm
hi
thnxs for reply.
I hve solved the problem the PIC pins are mulitipurpose and i thought tht by default these pins will work as I/O but the pins to which i connected nIRQ and FFIT were workin as A/D converter input.so i hve make the correction and its workin well now.
Can u tell me tht how u calculte the reciever bandwidth and how much deviation is good.Do u use the carson’s rule.There is a table i can see with different data rates and deviations and receiver bandwidth How u hve build it.
thnxs
July 30th, 2009 at 4:13 pm
@aamir
Great to hear.
In the latest series on the RFM12 Tutorials – Part 3a (http://blog.strobotics.com.au/2009/07/27/rfm12-tutorial-part-3a/), I’ve put up a table with values that I’ve gleaned from data sheets, both from HopeRf and Integration, before they were purchased by silicon Labs. These values seem to work well, but I’m sure could be optimised further.
I’ve never heard of Carson’s Rule, but am about to research it
July 30th, 2009 at 4:18 pm
@aamir
Just read up on Carson’s Rule, and would think that should work fine. I’m going to apply that rule to the figures I posted and see how they compare.
Stephen…
July 30th, 2009 at 6:39 pm
@Stephen
thnx buddy
yeah Carson Rule is used to calculate the Bandwidth of FM signal as well as FSK.And i hve learned tht for proper reception the signal bandwidth should be same as tht of channel.So to configure the receiver bandwidth i use Carson rule.Its works but as u gona know the receiver bandwidth in urs table didnt match as they are must less than we get usin this rule.i hvent tested urs table yet but i believe in urs words.i will test then later and i hve read urs articles as well as all the data sheets i duno about the updated datasheet i will check it out and i appreciate urs efforts
October 3rd, 2009 at 4:51 am
Hi,
I finally managed to connect and programm my module RFM12BP. But I have a problem. I connected the RFM module through 5cm long cables to my microcontroller board. Now when I select output power higher than the lowest setting, I get interference on the microcontroller inputs. The interference is so strong that it prevents the NIRQ signal from proper function. When I set the output power to the lowest setting I get a normal function. Can anyone suggest how to solve this problem? Or does anyone have a sample PCB layout that functions even with the highest output setting?
October 8th, 2009 at 11:45 am
@budlim
I’ve not yet played around with the RFM12BP so am probably not much help.
I can only suggest that if you are getting interference then look at more filtering and some form of shielding on the RF unit.
sorry I can’t be more of a help. Stephen…
November 16th, 2009 at 8:09 pm
hi,
Now i am working with RFM12b,the problem is,c8051F120 controller can transmitted and c8051F326 can received properly,but
while c8051F326 transmitting the c8051F120 is not receiving.for TX/RX, i am using RFM12b,,,,,,,,,,,,,,can u plz explain the problem ……………
November 16th, 2009 at 8:09 pm
hi,
Now i am working with RFM12b,the problem is,c8051F120 controller can transmitted and c8051F326 can received properly,but
while c8051F326 transmitting the c8051F120 is not receiving.for TX/RX, i am using RFM12b,can u plz explain the problem ……………
November 17th, 2009 at 11:39 am
@volt
How are you testing your Tx and Rx? as you say thet individually they both work?
Really the problem you are describing can be anything.
One of the common problems is incorrect bandwidth settings on the Rx. the Rx bandwidth settings must be greater than the Tx FSK settings? there are recommended settings in the datasheet from hope.
Also check the frequency and bitrate setting so they are the same on both Tx and Rx.
November 17th, 2009 at 12:58 pm
hi Stephen,
Thank you for the response.
In transmitting part i have c8051F326 controller.It always transmitting via RFM12b(3.3V).but the receiver side i am using c8051F120 controller to receive via RFM12b.
the thing is i can able to TX/RX in F326.but when i using different controller to TX/RX,it cause the problem.F120 can able transmit but not able to receive.
F120 F326
fine
(TX)——-> (RX)
not RX
(RX)<——- (TX)(no problem transmitting)
i can forward to work with u r ideas and get back to you.
November 17th, 2009 at 3:48 pm
hi,
i am checking what u r suggest.The frequency and bit rate settings are the same on both TX and Rx.and also correct bandwidth settings on the Rx. It is greater than the Tx FSK settings.Is there any problem in nIRQ pin or SPI,HAL int..
November 25th, 2009 at 11:45 pm
Hi,
do you have any idea how can I debug rfm12? Now, I have a transmitter, which send the data out in a loop and I have a receiver, which should receive the data, but it is only waiting in infinite loop and it doesn’t receive anything.
What can i do in this situation? How can i check the rfm12 got my instruction via SPI? There is a status register in rfm, is it useful check the value of it?
Thank you for your help!
Regards,
Gyorgy (from Hungary)
November 26th, 2009 at 11:45 am
@sogyu
debugging the RFM12 can be frustrating, especially on the RFM12 side of things.
to debug the SPI here is what I did:
use an oscilliscope to check that the SPI signals looked ok, i.e. the NSEL is pulled low at the start of the SPI command and being returned high at the end of the SPI sequence. also check that the SCK signals looks ok and you have data going in/out from your MOSI/ MISO pins.
If these look ok then try sending a command to change the frequency of the CLK pin. By default the Poweron value is 1MHZ (from memory) so put an oscilloscope or frequency counter on the output, then send the command to change to 10Mhz. if the SPI is working then you will see the frequency change to the new value.
November 26th, 2009 at 11:50 am
@volt
I have found that I need to have a pull up on the NIRQ line for it to work, on the AVR I use the internal pullup for that pin. Also make use that you are reading the status as part of the IRQ handling i.e. cmd 0×0000 this resets the NIRQ on the RFM12, else it will stay low.
Also don’t have any debug/printf to console in your main RFM12 Tx routines. The delay in Tx can cause the Rx to loose FSK sync.
Stephen…
December 2nd, 2009 at 9:12 am
@Stephen
Hi, I am trying to connect two PIC micro controllers using the RFM12B Transceivers and am having an issue with sending consistently. Each time I start up the transmitter and receiver sometimes I can start sending right away, and sometimes it takes a bit for the receiver to start catching the data that is being sent.
Once NIRQ goes low the receiver will constantly receive data until I pause sending for a brief period of time. I have noticed that after I stop sending for a brief period, if I restart sending I begin to get all garbage values. I have also noticed that once NIRQ goes low it will not go back high even once I have stopped sending data. The data I am sending is 5 quick packets each consisting of a preamble, two sync bytes, 4 data bytes, then 3 dummy bytes. I have tried using the read status command to bring NIRQ back up after the 5 packets send but am still having an issue. Is there a way to reset the entire module or another way to pull NIRQ high using software? Any insight or tips would be greatly appreciated.
-Thanks
Matt
December 2nd, 2009 at 9:35 am
@ernieb53
I would try adding a some more pre-amble bytes as it sounds like a FSK lock issue, i.e. the receiver is not getting FSK lock then sync. I think a single pre-amble is not enough, and adding a preamble as the last couple of bytes in your packet, this allows your Tx register to flush out. I run at least 3-4 preamble bytes and tail my packets with 2 pre-amble bytes e.g. http://code.google.com/p/strobit/wiki/WidgetMesh#Design
As for NIRQ, I’ve found you need a pull up for it to work properly, either an external resistor or easier still an internal one on your MCU port to pull the signal high. Remember when going into low power mode on your MCU you would need to disable the internal pull ups, before entering, and then re-enable when exiting sleep mode.
December 2nd, 2009 at 11:14 am
@ernieb53
I forgot to mention that you need to read the status command to reset your NIRQ as part of your interrupt handling routine, i.e. as each byte is received by the RFM12.
Stephen…
December 3rd, 2009 at 1:35 am
@Stephen
Thanks for the quick response and tips. As it turns out I am not using an interrupt but am just polling the NIRQ pin. I have tried the pull up resistor on both the micro and RF side along with the status read after each byte is read in, but I still never see NIRQ go high again. Could this be fixed if I enable interrupt instead of VDI for the p16 status bit? My preamble and dummy bytes are just how you suggested and the receiver does pick up more promptly. I even tried polling the FFIT instead of NIRQ and have found the same results of valid continuous data until I stop for a moment, then all garbage. If you have any other thoughts I would greatly appreciate any additional help. Thanks so much for the advice you’ve already given
-Matt
December 3rd, 2009 at 2:38 pm
@ernieb53
I always have P16 set to the POR values which is VDI, the INT is only for external interrupt for the RFM12, i.e. will stop the RFM12 from what its doing.
The RFM12 interrupt system works by latching the interrupt source and then triggering the NIRQ line if any of these IRQ bits are latched (bits 0 – 5 of the status register), these bits are only cleared by doing a status cmd, so If the NIRQ line is permanently low and you are doing a status command as part of how you are handling the NIRQ state then you may need to read out the result of the status command to find the source of the RFM12 NIRQ is, you may find it’s low voltage or something else causing it, not the actual reception process.
You might need to post or (email them to me via the contact form ) the commands being sent to the RFM12 as part of your initialisation sequence and then your Rx / Tx routines so I can see what’s happening,
Also It’s important to remember that when initialising the RFM12 is to set the FIFO level to 8 bits (so when 8 bits get received/transmitted it will cause the FFIT interrupt to trigger) and also before you start any transmission/reception of your packet buffer you need to first disable (this resets the FIFO) and then enable the FIFO, then once everything has been transmitted/received you need to disable the FIFO.
If you are only polling the NIRQ pin, then an easier way is to run the RFM12 in ‘polled mode’ basically this works during the reception (or Transmission process) by bit-banging a single 0 bit out the SPI and reading the single status bit back (FFIT), if the FFIT is 1 then do what ever, if 0 then do it again until a 1 is read back, (basically the same as doing a status CMD but only a single bit long) you don’t need to read the NIRQ line at all, keep in mind the MCU is tied up polling the RFM12, so not the most efficient.
Basically sequence is:
SCK = LOW
NSEL = LOW
SDI = LOW
SCK = HIGH
read SDO pin
SCK = LOW
NSEL = HIGH
Stephen
December 6th, 2009 at 4:09 am
@Stephen
Sorry about the delay, but once again thanks so much for your help. I did start using the FFIT read idea and it is working much better. I’m also going to include my code for transmitter, receiving, and initialization (receiver side).
INIT
writeCmd(0x80E7);
writeCmd(0×8299);
writeCmd(0xA640); //freq select
writeCmd(0xC647); //4.8kbps
writeCmd(0x94A0);
writeCmd(0xC2AC); //AL,!ml,DIG,DQD4
writeCmd(0xCA81);
writeCmd(0xCED4); //SYNC=2DD4;
writeCmd(0xC483);
writeCmd(0×9850);
writeCmd(0xCC17);
writeCmd(0xE000);
writeCmd(0xC800);
writeCmd(0xC040); //1.66MHz,2.2V
Transmit
void rfSend(unsigned char data)
{
while(!NIRQ);
writeCmd(0xB800 + data);
}
unsigned int writeCmd(unsigned int cmd)
{
unsigned char i;
unsigned int recv;
recv = 0;
SCK = 0;
CS = 0;
for(i=0; i<16; i++)
{
if(cmd&0×8000)
SDI = 1;
else
SDI = 0;
SCK = 1;
recv<<=1;
if( SDO == 1 )
{
recv|=0×0001;
}
SCK = 0;
cmd<<=1;
}
CS = 1;
return recv;
}
short FFITcheck(void)
{
SCK = 1;
CS = 0;
if (SDO == 1)
{
SCK = 0;
CS = 1;
return 1;
}
else
{
SCK = 0;
CS = 1;
return 0;
}
}
Receive
unsigned char rfRecv()
{
unsigned int data;
while(1)
{
data = writeCmd(0×0000);
if ( (data&0×8000) )
{
data = writeCmd(0xB000);
return (data&0x00FF);
}
}
}
void FIFOReset()
{
writeCmd(0xCA81);
writeCmd(0xCA83);
}
That is most of my code for sending and receiving, and if you see anything that stands out as an obvious issue I would appreciate the help. Thanks so much for all the info so far!
-Matt
December 14th, 2009 at 2:28 pm
Hi Steve
Great tutorial info. Just wondering if you can clarify some comments regarding nRST and FSK/DATA/nFFS. You mention that they should be tied high (directly and via 10k respectively) Reading the RF12B datasheet, nRST is a bidirectional pin with an internal pullup, and FSK/DATA/nFFS also has an internal pullup. I’m not worried about the couple of cents, but do they really need the external connections?
Cheers
Colin
December 16th, 2009 at 4:11 pm
@colinh
The RFM12B really doesn’t require a pull up and will work without it, however the RFM12 does else it won’t work.
Stephen…
December 16th, 2009 at 4:22 pm
@matt
Sorry for the delay in getting back to you. can you email me your complete application so I can see how you’re using the functions in the main loop.
Regards,
Stephen…
December 17th, 2009 at 6:36 am
Hi Steve,
Thanks for this tutorial, it was very handy in getting this radio module working.
Just to point out that the RFM12B uses the Si4420 chip from Silicon Labs and is basically the Si4420 chip with the antenna circuitry shown in the Si4420 data sheet. This datsheet contains much more information than the Hoperf’s RF12B.pdf datasheet and actually explains for example how the transmission buffering works.
From this you can see that it is not actually necessary to send preamble bytes. If the ET bit is off, the two stage transmission buffer pre-loads AA’s into this stage automatically. Once the ET bit gets set high these preamble bytes are sent as the first two bytes. If you want you can add more by pre-pending AAs to your data to tranmit. BTW you can override these two bytes if you write to the transmission register while ET is low (the datasheet shows this as a timing diagram).
Mark.
December 18th, 2009 at 8:25 pm
Proper Use of AFC:
It seems to me that the AFC function is very useful to minimise the differece between the tranmitter and receiver frequencies, and hence to allow the minimum receiver bandwidth to be used.
I’m a little unsure of exactly how the AFC function should be used though. Here is my basic understanding, maybe someone could shed some light on this and whether this is correct:
When a receiver detects an incoming RF signal that is above it’s programmed VDI threshold the VDI signal goes active. This occurs during the preamble phase before any sync word. If the status word is read immediately VDI goes active (i.e. during the preamble stage), then the lower 3 bits show the frequency offset between the two frequencies, and this can then be programmed into the receiver frequency PLL register to match them. The sync word is then decoded with the receiver PLL now matched to the transmitter’s frequency, and subsequent data received (all further bytes received are not qualified with VDI, so the receiver will continue to receive even if the transmitter is turned off until either the receiver is disabled or the FIFO is reset).
I’m also unsure about turnaround times between transmit to receive and back again. The datasheet gives a maximum time for these, but is this delay handled automatically by the hardware or does the micro have to add these times to allow it to settle? For example could the user immediately go into receive mode and the hardware prevent reception until the turnaround time has elapsed? Also could the user immediately try to transmit by setting ET after a reception and the hardware hold that transmission off until its internal turnaround time has elapsed?
One last question: Does anyone know the ppm spec of the crystals used on the RFM12B? If AFC is not used this seems to be an important parameter when calculating the receiver bandwidth to be used.
Thanks!
Mark.
January 19th, 2010 at 2:59 pm
I have seen a couple of comments about the RFM12B being based on the Si4420. It might be a minor point but from what I can see the RFM12B is actually based on the Si4421. My reason for thinking this is the 3.8V max supply, no support for 315MHz and flexible sync pattern (1 or 2 bytes) – this is what I have spotted so far. The fact that there are register differences between the Si4420 and RFM12B mean that it is not a good reference.
Any comments welcome…
January 23rd, 2010 at 1:56 am
i have tested the rfm12bp modules but the problem is with the range , it does not give good range . has anyone field tested it , i have the 915Mhz version . i don’t know if is a noise issue or something else. i have connected the module with a whip antenna . it should have enchanced range , hope rf says they have 800m range.
February 5th, 2010 at 8:43 am
@colinh
Yes, I think you’re right. The RFM12 is based on the Si4420, the RFM12B is it seems is based on the Si4421 (the corresponding Hoperf documents for the chips are rf12.pdf and rf12b.pdf respectively). Thanks for pointing it out!
Mark.
February 5th, 2010 at 6:10 pm
@faizanbrohi
Not sure what data rate you are using. There is a relationship between data rate and distance, basically for each doubling of the
data rate the receiver sensitivity reduces by 3dB (roughly). Since power received reduces by 6dB for each doubling of distance this means the distance will reduce by 1/sqrt2, i.e. 0.707. Now you need to know what conditions the 800m is quoted for. You can bet this is at the lowest data rate the chip will handle, and at a releatively high Bit Error Rate (maybe 1E-3).
Quick calculation: Assuming 800m is quoted at 600 bps, and you used 57600 bps in your app, this is (very roughly) 6 doublings, so your distance will reduce to 1/(6*sqrt2), i.e. again very roughly 1/10. You’ll get 80m, not 800m. And even that is at high BER rate.
Here’s a useful link:
http://www.ce-mag.com/archive/02/Spring/cutler2.html
Mark.
February 5th, 2010 at 6:28 pm
Edit: I think I made an error in that post. It should have said 6/sqrt2, i.e. 1/4 not 1/10 (which is 200m).
February 11th, 2010 at 8:45 pm
I am transmitting at 4800bps and it has reached 400m with only changing the board from Veroboard and a messy layout to a Well designed PCB one . i also changed the antenna. i am now looking forward to the 433Mhz module to increase the range as it low frequency so greater wavelength . will the low frequency module make a difference ?
March 29th, 2010 at 2:19 am
Dear All,
Please help me out with this issue:
I am reading the status register but getting only 0′s
This is the init function:
void RF12_INIT(void) //868MHz!!!
{
RFXX_WRT_CMD(0x80E7);//el,ef,868band,12.0pF
//If both et and er bits are set the chip goes to receive mode.
RFXX_WRT_CMD(0×8259);//!er,ebb,!et,es,ex,!eb,!ew,DC
RFXX_WRT_CMD(0xA640);//868MHz
RFXX_WRT_CMD(0xC647);//4.8kbps
RFXX_WRT_CMD(0x90C0);//VDI,FAST,67kHz,0dBm,-103dBm
RFXX_WRT_CMD(0xC2AF);//AL,!ml,DIG,DQD7
RFXX_WRT_CMD(0xCA81);//FIFO8,SYNC,!ff,DR
RFXX_WRT_CMD(0xCED4);//SYNC=2DD4
RFXX_WRT_CMD(0xC483);//@PWR,NO RSTRIC,!st,!fi,OE,EN ??
RFXX_WRT_CMD(0×9830);//!mp,45kHz,MAX OUT
RFXX_WRT_CMD(0xCC77);//OB1COB0, LPX,!ddy,DDIT,BW0
RFXX_WRT_CMD(0xE000);//NOT USE
RFXX_WRT_CMD(0xC800);//NOT USE
RFXX_WRT_CMD(0xC000);//1MHz,2.2V
}//void RF12_INIT(void)
the write command function:
unsigned int RFXX_WRT_CMD(unsigned int aCmd)
{
unsigned char i;
unsigned int temp=0;
_delay_us(10);
LOW_SCK();
LOW_SEL();
_delay_us(10);
for(i=0;i<16;i++)
{
if(aCmd&0×8000)
HI_SDI();
else
LOW_SDI();
aCmd<<=1;
_delay_us(40);
HI_SCK();
_delay_us(20);
if(SDO_HI())
temp|=0×0001;
temp<<=1;
_delay_us(20);
LOW_SCK();
}//for(i=0;i>8);
USART_TransmitByte(tmp&0xFF);
RFXX_WRT_CMD(0xB800+aByte);
}//void RF12_SEND(unsigned char aByte)
And a part of main():
…. RFXX_WRT_CMD(0×8279);//!er,ebb,et,es,ex,!eb,!ew,DC
//RFXX_WRT_CMD(0xCA81); //init fifo
//RFXX_WRT_CMD(0xCA83); //enable fifo
//RFXX_WRT_CMD(0×0000);//read status
//_delay_ms(5);
ChkSum=0;
LEDR_ON();
RF12_SEND(0xAA);//PREAMBLE
…
March 29th, 2010 at 2:21 am
Dear All,
Please help me out with this issue:
I am reading the status register but getting only 0′s
This is the init function:
void RF12_INIT(void) //868MHz!!!
{
RFXX_WRT_CMD(0x80E7);//el,ef,868band,12.0pF
//If both et and er bits are set the chip goes to receive mode.
RFXX_WRT_CMD(0×8259);//!er,ebb,!et,es,ex,!eb,!ew,DC
RFXX_WRT_CMD(0xA640);//868MHz
RFXX_WRT_CMD(0xC647);//4.8kbps
RFXX_WRT_CMD(0x90C0);//VDI,FAST,67kHz,0dBm,-103dBm
RFXX_WRT_CMD(0xC2AF);//AL,!ml,DIG,DQD7
RFXX_WRT_CMD(0xCA81);//FIFO8,SYNC,!ff,DR
RFXX_WRT_CMD(0xCED4);//SYNC=2DD4
RFXX_WRT_CMD(0xC483);//@PWR,NO RSTRIC,!st,!fi,OE,EN ??
RFXX_WRT_CMD(0×9830);//!mp,45kHz,MAX OUT
RFXX_WRT_CMD(0xCC77);//OB1COB0, LPX,!ddy,DDIT,BW0
RFXX_WRT_CMD(0xE000);//NOT USE
RFXX_WRT_CMD(0xC800);//NOT USE
RFXX_WRT_CMD(0xC000);//1MHz,2.2V
}//void RF12_INIT(void)
the write command function:
unsigned int RFXX_WRT_CMD(unsigned int aCmd)
{
unsigned char i;
unsigned int temp=0;
_delay_us(10);
LOW_SCK();
LOW_SEL();
_delay_us(10);
for(i=0;i<16;i++)
{
if(aCmd&0×8000)
HI_SDI();
else
LOW_SDI();
aCmd<<=1;
_delay_us(40);
HI_SCK();
_delay_us(20);
if(SDO_HI())
temp|=0×0001;
temp<<=1;
_delay_us(20);
LOW_SCK();
}//for(i=0;i<16;i++)
LOW_SCK();
HI_SEL();
return temp;
}//unsigned int RFXX_WRT_CMD(.. aCmd)
March 29th, 2010 at 2:25 am
The previous message got scrambled..
Here is again in two parts
Write command:
unsigned int RFXX_WRT_CMD(unsigned int aCmd)
{
unsigned char i;
unsigned int temp=0;
_delay_us(10);
LOW_SCK();
LOW_SEL();
_delay_us(10);
for(i=0;i<16;i++)
{
if(aCmd&0×8000)
HI_SDI();
else
LOW_SDI();
aCmd<<=1;
_delay_us(40);
HI_SCK();
_delay_us(20);
if(SDO_HI())
temp|=0×0001;
temp<<=1;
_delay_us(20);
LOW_SCK();
}//for(i=0;i>8);
USART_TransmitByte(tmp&0xFF);
RFXX_WRT_CMD(0xB800+aByte);
}//void RF12_SEND(unsigned char aByte)
March 29th, 2010 at 9:21 am
@laci:
first and for-most is your SPI bus working? i.e. An easy test is to send a command to turn off the CLK pin or change it’s frequency.
Regards,
Stephen…
April 1st, 2010 at 9:49 pm
I solved the problem, now my concern is that switching between tx/rx takes to long.
As trying to implement some anti-collision I need to stop tx for a while and check for any rx. Anybody has some ideas ?
When finished I will make the code public.
April 2nd, 2010 at 2:39 pm
@laci
Great to hear you have it working.
If you leave the crystal and synthesiser on then the turnaround time from Tx – Rx and visa-versa is 150usec. Initial crystal turn-on time is a couple of mSec so do that at initialisation toggle the et bit.
You can also the ATS, DQD and RSSI status bits to determine if there is something else transmitting.
Stephen…
April 21st, 2010 at 2:18 am
Hello , again , there is some problem with the module when i am using interrupt mode , i am using the following scenario ,
There is one Gateway ,router, base station or what ever you want or call it , which polls different nodes which are listening. the base station broadcasts an address packet to every node and the corresponding node answers if it matches the address . i have three nodes currently connected to the system .
Now the problem is that after some time the base station (when it is polling) receives zeroes at the end of every packet and it is consistent. when i introduced a watchdog and when it resets the system the zeroes are gone , but this does not solve the problem it can occur everytime , is it a timing issue , i am using my own interrupt based routine and check nirq for it to go in the external interrupt ISR and the ffit bit for receiving the valid data.
i have 1 second polling time for each node @ 4800kbps ( which is done under timer ISR ) and about 10 ms switch over time for tx-rx switching , it has enough time.
I mailed hoperf , they are saying add 10k pullup to the fsk data pin . however it did not solve the problem .
April 21st, 2010 at 9:23 am
@faizanbrohi
With your interrupt routing are you checking or handling all status bits? as the interrupt might be generated by something else.
It’s not safe to assume that when you receive an interrupt that it is from a Tx or Rx event.
Regards,
Stephen…
April 22nd, 2010 at 1:38 am
@stephen
Solved the problem , problem with node synchronization when handling two interrupts (timer and external), a programming bug not the rf issue. Thanks
April 26th, 2010 at 12:33 pm
hi stephen, I just started to work with the RFM12b and the pic 16F87. is the first time I do program a device, so I would like to know wich compiler could i use.
April 26th, 2010 at 12:33 pm
hi stephen, I just started to work with the RFM12b and the pic 16F873a. is the first time I do program a device, so I would like to know wich compiler could i use.
April 26th, 2010 at 4:46 pm
For the PIC I used sourceboost IDE, now I’m using AVR GCC I’m not too s what free compilers are available for the PIC
Stephen…
April 27th, 2010 at 1:23 pm
hi stephen,I just started to work with the RFM12b and PIC16F873, i have problem with
the program of datasheet programming guide hoperf, can me help with a program that is find Good and in C.
my email is enriquecarlos88@gmail.com
thank
May 9th, 2010 at 3:42 pm
@Stephen
I “reloaded” the rfm project, and still struggling with the rx/tx mode switch.
Before I issue the actual command
RFXX_WriteCommand(0×8279);//!er,ebb,et,es,ex,!eb,!ew,DC
or
RFXX_WriteCommand(0x82D9);//er,ebb,!et,es,ex,!eb,!ew,DC
I wait for the Status bit FFIT to be 1.
The problem is that the device switches to RX mode very slow, do you have any idea why?
Regards,
Laci
May 10th, 2010 at 5:51 pm
The other great mystery is that my RF12_GetData function needs specific delays between the calls otherwise won’t work…
May 10th, 2010 at 7:14 pm
hi all, i use rfm12b to transmit data from a PC to another one by rs232. most of my code from hope rf.
PC1–(1)–>MCU1–(2)–>RF1—(3)—>RF2–(2)–>MCU2–(1)–>PC2
but i’m puzzling with the bitrate among these devices.
as u see on the simple diagram above.
(1) : bitrate between PC and MCU
(2) : bitrate between MCU and RF
(3) : bitrate between RF and RF
acorrding hope code,
writeCmd(0xC647); //4.8kbps
data rate (3) is 4800bps.
is it necessary to be the same among them?
hearing from you soon!
May 11th, 2010 at 10:54 am
@laci
when you say the Tx/Rx turn around takes too long, how long is it taking?
Stephen…
May 11th, 2010 at 10:56 am
@realheaven
As long as you have some form of buffering between the RS232 and the RFM12 then it shouldn’t matter.
Stephen…
May 13th, 2010 at 4:33 pm
@Stephen,
Well it takes quite long(few 100ms), usually the first attempt gives a timeout, and sometimes can’t even switch between tx/rx.
May 16th, 2010 at 1:23 am
@ Stephen 89
I’ve set up a system using two rfm12 to transfer data from one node to another but it’s still not worked at all. I also used a electromagnetic energy device to detect the magnetic field but maybe that device was not sensitive enogh!!!
Would you mind telling me how to check if rf really sent out a frame?
may a oscilloscope can kick this problem?
thanks a lot!
May 16th, 2010 at 1:09 pm
@laci,
100mSec would seem long as a turn around time.
make sure you’re not tuning off the whole power chain when you change from Tx-Rx and vis-versa. If you want a fast turn-around then you need to already have the crystal oscillator and synthesiser turned on (part of your wakeup?).
Once initialised you should only need to toggle the er bit in the power control register(0x8208h) if both et and er are on then er takes precedence.
check out the turnaround timing in the datasheet (bottom page 10 on my sheet), in theory you should be achieving 150uSec turnaround times if you already have the synthesiser and crystal on.
Stephen…
May 16th, 2010 at 1:18 pm
@realheaven
AFAIK a spectrum analysers would be the only thing to see if you are transmitting on the wireless side of things. An oscilloscope would cause too much load on the circuit and then it won’t work, also the frequencies involved would be a high end oscilliscope.
You need to confirm your SPI is talking to the RFM12 first. An easy test is to send the comand to change the Cystal output frequency and measure with an oscilloscope or frequency counter.
If your having Tx Rx problems make sure you don’t have any debug printf etc in your transmit routines, just queue up your Tx buffer and then start the Tx sequence until your buffer is empty.
If there are any delays in this Tx sequence then the receiver will loose sync and will not receive anything.
Stephen…
May 16th, 2010 at 8:01 pm
@Stephen,
I am changing just the et/er bits in the power managment command
this is my function:
unsigned char RF12_SetMode(unsigned char SetMode)
{
static unsigned char timeout_cnt=0;
unsigned char RFXX_Response;
RFXX_Response=RFXX_WaitReady();
if( (SetMode==TX_MODE)&&(mode==RX_MODE) )
{
//Fill the TX with 0xAAAA preamble key
RFXX_WriteCommand(0×8279);//!er,ebb,et,es,ex,!eb,!ew,DC
_delay_ms(1); //RX/TX switch time
mode = TX_MODE; //switch to tx mode
RFXX_WriteCommand(0xCA81); //reset fifo
}
else
if( (SetMode==RX_MODE)&&(mode==TX_MODE) )
{
RFXX_WriteCommand(0x82D9);//er,ebb,!et,es,ex,!eb,!ew,DC
_delay_ms(1); //RX/TX switch time
mode = RX_MODE; //switch to rx mode
RFXX_WriteCommand(0xCA81); //reset fifo
}
if(timeout_cnt == RFXX_SET_MODE_TIMEOUT) //prevent infinit blocking
{
RFXX_Response=RFXX_READY;
timeout_cnt=0;
}
if(RFXX_Response != RFXX_READY)
{
timeout_cnt++;
return RFXX_TIMEOUT_ERR;
}
else
return mode;
}//unsigned char RF12_SetMode(unsigned char SetMode)
May 17th, 2010 at 12:23 pm
@ Stephen 93
thanks so much for your support. I checked my SPI interace and there was no trouble with it.
I gotta read the status register to comfirm that i can manage the rf completely.
There is a simple code to read the status register is :
writeCmd(0×0000) // form hope guide
but i failed in this section
is that enogh to read status register by a sigle command like that?
May 17th, 2010 at 3:23 pm
i thought i could get something but only 00 bits form reading status register!!!
why that happens?
May 18th, 2010 at 6:43 pm
here’s my complete code
// rs232 Init
void Tx(unsigned char data)
{
while(!(UCSRA & (1<<UDRE)));
UDR=data;
}
// write command function
unsigned int writeCmd(unsigned int cmd) {
unsigned char i;
unsigned int recv;
recv = 0;
LO(SCK);
LO(CS);
for(i=0; i<16; i++) {
if(cmd&0×8000) HI(SDI); else LO(SDI);
HI(SCK);
recv<<=1;
if( PINB&(1<<SDO) ) {
recv|=0×0001;
}
LO(SCK);
cmd<<=1;
}
HI(CS);
return recv;
}
to be continued…
May 18th, 2010 at 6:46 pm
void rfInit() {
writeCmd(0x80F8); //EL,EF,915band,12.5pF
writeCmd(0×8239); //!er,!ebb,ET,ES,EX,!eb,!ew,DC
writeCmd(0xAA6B); //frequency select
writeCmd(0xC647); //bit rate = 4.8kbps
writeCmd(0x94C2); //VDI,FAST,BW=67kHz,0dBm,-91dBm
writeCmd(0xC2AC); //AL,!ml,DIG,DQD4
writeCmd(0xCA81); //FIFO8,SYNC,!ff,DR
writeCmd(0xCED4); //SYNC=2DD4G
writeCmd(0xC483); //@PWR,NO RSTRIC,!st,!fi,OE,EN
writeCmd(0×9820); //!mp,deviation=45kHz,MAX OUT
// writeCmd(0xCC17); //OB1COB0, LPX,IddyCDDITCBW0
writeCmd(0xE000); //NOT USE
writeCmd(0xC800); //NOT USE
writeCmd(0xC040); //1.66MHz,2.2V
}
void main()
{
volatile unsigned int data;
#asm(“cli”);
delay_ms(1000);
rsInt();
portInit();
rfInit();
data=writeCmd(0×0000);
Tx(data);
}
status register value form hyperterminal : 00 00 00 00…
please help me in this case
May 18th, 2010 at 8:57 pm
oh i forget telling you that i’m using RFM12 not RFM12B, there are some slight changes between these two.
you can also get it from : http://news.jeelabs.org/2009/05/06/rfm12-vs-rfm12b-revisited/
May 19th, 2010 at 9:57 am
i sovled the case!!
May 19th, 2010 at 10:38 am
what funny!
when rf in Tx mode, i got a static valaue form status register is A100. but when i toggled it into Rx mode i got more than one value!?! for ex : 0000, 0120, 0020 and several strange values : 0040, 0044, 0067!?!
i note that there are two bits in status register having value changing are RSSI and ATGT.
anybody can explain why in Rx mode there are lots of diffrent values when reading status register? expecially bit RSSI & ATGT
May 22nd, 2010 at 11:57 am
at least my network works! i feel so happy! it’s worth to try hard rite!
but who can tell me why toggling between TX/RX & RX/TX take so so long time. I must to delay 500ms to guagrante receiving all packets whereas hoperf say that it takes 150us!?!
thanks a lot!
May 25th, 2010 at 12:10 pm
@realheaven
Glad you got it all working, what ended up being your problem?
One of the other members (laci) is also having problems with the turnaround time from Tx/RX as well, you might want to chat with him to see if a solution was found. Unfortunately I not currently in the position to do any testing for some time so I see why there is a delay.
May 29th, 2010 at 12:20 am
I hope somebody can help me out, I ran out of ideas, probably will switch to some other module/solution because this rf12b just won’t work …
May 29th, 2010 at 10:04 am
@laci 104
what’s your trouble, laci?
May 31st, 2010 at 6:16 pm
@realheaven
The TX/RX switching won’t work, at start up I can switch to TX(no received data yet), it sends out the data, after I start to receive the RX mode won’t gather any data, and I can’t switch back to TX mode.
See my previous posts, I even posted the mode select function.
June 1st, 2010 at 9:48 pm
@ laci 106
at first, if you want one node at TX mode then you should init it @ TX mode by writeCmd(0×8239). Next, if you want it at RX mode you should switch it to RX mode by writeCmd(0×8299).
You can also test the TX RX mode with one simple test. For example, you have 2 node A & B.
1. A (TX) —> B(RX)
2. A(TX–>RX) & B(RX–>TX)
3. B(TX)–>A(RX)
A sends out a byte to B, A immediately switches to RX mode; if B (@ RX)receives a byte and check if it’s from A then B switches to TX mode and sends out a byte; @ A you can easily check the data from B by send it to PC using RS232.
ps : you should test both two nodes that can transmit and receive data first to be sure that there’s no fault at any stage of the process.
good luck!
(feel free asking, rite!)
June 3rd, 2010 at 2:38 am
I will make a more thorough debug, maybe I made some stupid mistake somewhere… until then I remain skeptic
just won’t switch between tx/rx remains blocked somewhere
June 3rd, 2010 at 7:41 pm
@ laci 108
hi laci, you should read this :
http://zenburn.net/~goroux/rfm12b/rfm12b_and_avr-%20quick_start.pdf
i think it’ll help you to solve your problem.
hope you success!
June 4th, 2010 at 2:11 am
As soon as I have some spare time, i will get to the bottom of this issue
, and write my own tutorial and post my entire software on a blog.
June 17th, 2010 at 9:15 pm
Hello Stephen,
Really thanks for these nice tutorials!!!
i thought i gave up on that rfm12!!! i used the hm-tr from hope rf wich uses standrd rs232 protocol but they are very expensive !!! my question is if i want to use the hardware spi will the code be the same as the programming guide??
Note: I am Using Mikroc And has an spi library (hardware)(Pic16f876a)
Thanks Alot Stephen .
June 30th, 2010 at 10:28 am
@Nart_schinakow
I would suggest you look at other examples of code other than the ones supplied from HopeRF. I had no end of problems with them. However in saying that I did have some problems getting the hardware SPI working with the PIC and the RFM12B, this was a couple of years ago though.
July 17th, 2010 at 2:44 pm
Hi,
I am trying to interface a at89c52(5V) with the RFM12B(~3.6V) module. Whether I need to take care about including any delimiting resistors or other kind of level shifters between the SPI bus pins.
thanks in advance
Geo
July 22nd, 2010 at 11:25 am
@geo
The RFM12B has 5V tolerant I/O, however in saying that I wouldn’t leave it running at 5V for an application as it may shorten it’s life. When I first started development I didn’t use shifters etc and all ran ok.
July 26th, 2010 at 10:00 pm
[...] Next – Part 2 [...]
October 5th, 2010 at 12:14 am
@ geo 116
you may choose RFM12 instead of RFM12B because RFM12 can run well at 5V so there’s only one power supply for the two devices and to manipulate those RF is the same.
December 7th, 2010 at 10:49 pm
Hi Stephen
I have been researching and developting an application using the RFM12B.The data on this module is not good,
What i have noticed is a Digital signal analyzer or scope is required becasue of the lacking data sheets as to correct program flow.
What would be a good start is if an experience rfm developer(yourself) could provide timing diagrams showing the state of lines
NSEL,SCK,SDI,SDO,nIRQ, and VDI in relationship to el,et,synthersizer/pa etc,etc when running a sample program.
Now i am using a scope things are becoming much easier to grasp
Chippchipp
December 10th, 2010 at 9:55 am
@chippchipp
Yes I can certainly appreciate what rfm12 newbies go through. the biggest problems is what comes first the chicken or the egg, e.g. is the problem in the Tx, or is it in the Rx side of things.
I certainly agree with you. I could not have got my original design working without an oscilloscope watching the CLK and the MOSI/MISO however this was a pain as I only have a two channel CRO, I’ve since treated myself to a logic analyser that can decode SPI and find this invaluable when I troubleshoot.
When I get around to finishing off the tutorials I’ll look at putting some timing diagrams on.
stephen…
December 30th, 2010 at 6:42 pm
Hello
You wrote “nFFS – If pulled high then the FIFO is selected”. As I understood the datasheet the pin must be pulled low to select the FIFO.
Ulf
June 15th, 2011 at 5:52 am
[...] has been a bunch written about this signal. You can read about it here (German, with photo), here and here. There is work to translate this signal to an OOK [...]
September 27th, 2011 at 10:20 pm
hi
how can I used Rfm12 In No fifo mode?
Iwant read data direct. no in fifo register
September 28th, 2011 at 9:43 am
@Amir I’ve not used the non-fifo mode but it appears in the documentation that you need to set ef=0 and use pin 7 to get access to the incoming data for Rx and for Tx you need to use pin 6 to send your data.
December 18th, 2011 at 7:07 pm
hi,
The last time I contacted you was Dec 2010.
Now have my project working fully and I think I understand about 55% of the workings of the RFM12b.
The two modules communicate 100% no problems.
One thing I have notice.
I replaced my original Rfm 12b modules with two new rfm12b which I purchased in july 2011.
After power up i found problems with the first second and maybe third communication data packet occurs now and then but after say the fourth data packet the two modules will communicate continuously, not missing any data thereafter until I power off and power up or I move one of the modules out and then back in range.
I reverse fitted the new modules (swapped them round on my embedded application) and guess what.
I modules communicated perfectly from power up??
Have you seen this or have any ideas to what to change to debug or tune this out.
The two modules are embedded on exactly the same pcbs..
Just one module acts as the master and the other the slave.
I have increased the preambles.No change
Are there any parameters which you could point me to look at
Thanks
Chippchipp
March 27th, 2012 at 12:31 am
hello friends
plz help me
i worked on rfm12b for 1 month i have a problem that make me crazy
when i turn it on everything is good and a read status with 4000 hex
but when i initialize the module and switch to tx mode from ideal
the status run to a100 hex
i cannot solve the issue
plz help me i beg u friends