Author Topic: RFM12B Library: CanSend() Problem  (Read 2877 times)

Soeren

  • Newbie
  • *
  • Posts: 3
RFM12B Library: CanSend() Problem
« on: October 07, 2013, 02:42:47 PM »
Hello all,

Using the RFM12B library and the provided sample code (transmitter/receiver) it was pretty simple to establish a radio link between two boards. So thanks for sharing this library!

However, when activating acknowledges the receiver got stuck trying to acknowledge a received data packet. Some debugging showed that the problem is related to the function CanSend() which always returns false because of the RSSI check.

This raises the following questions:

1. What is that RSSI check used for?
It's not clear from the comments in the source code. A reply in the thread "Reset radio?" suggests that this would be used to implement some sort of LBT (listen before talk). Is that correct?

2. How does this SPI access work at all?
The RSSI check calls the function Byte() to read some data from the SPI interface. However, it cannot be seen that the nSEL line is pulled low as it is done in the XFER() function. Byte() doesn't change the select line.
In addition wouldn't accessing the RFM12B module via SPI be done using a 16 bit transfer? Byte() only writes/reades 8 bits.

I'd be very happy if someone could clear that up.
Thank you very much.

Cheers,
Soeren

Felix

  • Administrator
  • Hero Member
  • *****
  • Posts: 5938
  • Country: us
    • LowPowerLab
Re: RFM12B Library: CanSend() Problem
« Reply #1 on: October 07, 2013, 05:49:53 PM »
Soeren,
What hardware are you using?

Indeed the RSSI check is a listen-before-talk feature.
I would refer you to the datasheet for the specifics of this mechanism, but basically the RFM12B transceivers have a register where you can set an RSSI threshold that you consider "busy channel" and then read another register for a bit that will say whether that threshold is exceeded or not. That's it in a nutshell. High noise and interference might also trigger that bit.

RFM69 radios havea much nicer ability to actually tell you what the RSSI is. RFM12B just tells you YAY (you can talk now) or NAY (someone is talking).

The RFM12B library is based on the Jeelib, and while I changed some features, I did not mess with the low level SPI data transfers. There's a reason why the Byte() function won't deal with the SEL line. Bottom line - the lib should work, it was pretty extensively tested on the Atmega328P platform.

Soeren

  • Newbie
  • *
  • Posts: 3
Re: RFM12B Library: CanSend() Problem
« Reply #2 on: October 08, 2013, 11:49:39 AM »

Hello Felix,

Thanks a lot for looking into the described problem. For the receiver I'm using an ATmega168 on a prototype breadboard.

Looking at the code of Jeelib at
https://github.com/jcw/jeelib/blob/master/RF12.cpp
it shows that CanSend() uses rf12_control() which is a function that writes and reads back 16 bits on the SPI and also takes care of the select line.

To me it looks like as if that might be a glitch in the RFM12B library for the Moteino. I hope I'll be able to check that within a couple days.

Cheers,
Soeren

Felix

  • Administrator
  • Hero Member
  • *****
  • Posts: 5938
  • Country: us
    • LowPowerLab
Re: RFM12B Library: CanSend() Problem
« Reply #3 on: October 08, 2013, 12:45:45 PM »
Not sure, all I can say, there is no issue with the library running on Moteino R2.
If you find a bug that you can document and I can replicate I'd be more than happy to fix it.

Soeren

  • Newbie
  • *
  • Posts: 3
Re: RFM12B Library: CanSend() Problem
« Reply #4 on: October 10, 2013, 02:38:19 PM »
Hello,

Now I've completed some tests using the debugger to look at the value of the read back data.

Code: [Select]
bool CanSend() {
uint8_t status = Byte(0x00);
if (rxstate == TXRECV && rxfill == 0 && (status & (RF_RSSI_BIT >> 8)) == 0) {...

With that code status is always read back as a byte value of 0xFF and no Ack is send.
Then the code was changed to this:

Code: [Select]
bool CanSend() {
uint16_t status = Control(0x0000);
if (rxstate == TXRECV && rxfill == 0 && (status & (RF_RSSI_BIT >> 8)) == 0) {...

Now the status variable contains values different from 0, also the read back value often changes each time this function is called. In this case the Ack is send.

This indicates that the if statement should be changed to

Code: [Select]
if (rxstate == TXRECV && rxfill == 0 && (Control(0x0000) & (RF_RSSI_BIT >> 8)) == 0) {

What do you think?

Cheers,
Soeren
« Last Edit: October 11, 2013, 08:23:54 AM by Felix »

Felix

  • Administrator
  • Hero Member
  • *****
  • Posts: 5938
  • Country: us
    • LowPowerLab
Re: RFM12B Library: CanSend() Problem
« Reply #5 on: October 11, 2013, 08:39:35 AM »
You are probably right, that Byte call should perhaps be replaced by Control.
However the lib works fine as is on atmega328. I will need to do more testing before such a change.
Thanks for your insight.