LowPowerLab Forum

Hardware support => RF - Range - Antennas - RFM69 library => Topic started by: Lensdigital on November 26, 2013, 01:51:02 PM

Title: Can RFM69 communicate with RFM12B? [YES!]
Post by: Lensdigital on November 26, 2013, 01:51:02 PM
Sorry second question in a row from me today  ;D
I was wondering if it's possible to send data with RFM69 and receive it with RFM12b or vice versa?  i.e. between Moteino R2 and R3?
Title: Re: Can RFM69 communicate with RFM12b?
Post by: Felix on November 26, 2013, 07:49:48 PM
UPDATE: It's possible! See this entry (http://lowpowerlab.com/forum/index.php/topic,209.msg1081.html#msg1081) below!

Short answer is no, not with my original libraries. I think this was asked before in the forum. I did not spend too much time trying to get the 2 radios to talk to each other, just because they are so different. But not to say it's impossible.
There's a great post by kolumkilli who made a bridge between 2 such networks: http://lowpowerlab.com/forum/index.php/topic,204.0.html

I am moving towards RFM69 since they just work better, have much better range. I have yet to replace all my RFM12B nodes to RFM69, but slowly doing that.
Title: Re: Can RFM69 communicate with RFM12b?
Post by: Lensdigital on November 26, 2013, 08:38:18 PM
Thanks! I'll check it out. I think this might be of interest to some as many people already own R2. I've yet to make a switch to RFM69 with my Xronos clock since I made so many PCBs and got boatload of RFM12Bs :) 
Title: Re: Can RFM69 communicate with RFM12b?
Post by: NixHydra on November 27, 2013, 01:06:43 AM
@Lensdigital,

   Thanks to Felix writing a library for the various flavours of Hope RFM69 wireless modules, I've purchased five or so R4 Moteinos equipped with Hope RFM69HW wireless modules, to play with. Have to admit, from the testing I've done so far the RFM69s have got to be the way to go ... so much better ... in so many ways!! The fact that the RFM69CW flavour is a footprint/pin compatible replacement for the RFM12B, would seem to make it an ideal upgrade choice for any older RFM12Bs. I intend to use the R4 Moteinos equipped with the RFM69HWs as remote sensor nodes, especially since the inclusion of the 25X40CL flash chip on the R4 Moteinos, enable wireless reflashing of the R4 Moteino ATMEGA328s.

   This might be of interest, then again, maybe not? Couldn't help myself, so cobbled together an Arduino footprint RFM69HW pcb to use as a base station, to listen to the Moteino R4 sensor nodes. Please see the following link for details.

http://jeelabs.net/boards/6/topics/2934?r=3179#message-3179

cheers,


 

   
Title: Re: Can RFM69 communicate with RFM12b?
Post by: MikesTechBlog on December 12, 2013, 11:07:05 AM
Since I have about a dozen Motenio's with the RFM12b module, which is going away, and the RFM12b can't communicate with the RFM69, my thought is to have two networks. One with RFM12b's for the legacy devices, and one with RFM69.

Like most people here, I too am using a Raspberry Pi for the gateway to communicate. The problem with my idea is that there is only one RS-232 port on the Raspbi.

I was wondering if anyone has taken a Motenio-USB with a RFM69 and set up a second gateway / network using a USB port on the Raspbi as a second serial port. Then if a Motenio with a RFM12b wants to communicate to a Motenio with a RFM69, it does so via the raspbi through the python script.

This way my legacy RFM12b Motenio's are still useful. Thoughts anyone?
Title: Re: Can RFM69 communicate with RFM12b?
Post by: Felix on December 12, 2013, 11:24:22 AM
RFM12B is not really going away, at least not YET. But how much faith can we have? HopeRF might discontinue anytime without owing anyone an explanation. And that's completely fair.

Of course that's not to say people should throw away their RFM12B based projects. There's ways to still use those radios and bridge them together etc.

For an example on how to bridge the two see this excellent post by kolumkilli: http://lowpowerlab.com/forum/index.php/topic,204.0.html

Another thing that comes to mind is to piggy back a RFM12B-Moteino-Gateway on top of a RFM69-Moteino-Gateway, and bridge them through a software serial port. I know this is not ideal and all that but I have not seen any issues with software serial in my own share of use. I'm sure it can be abused and made to fail since it's not a hardware UART, but I'm sure the same is true to an extent about a true UART.

So there you go .. 2 options to start with. I'm sure there's other ways.
Title: Re: Can RFM69 communicate with RFM12b?
Post by: jbeale on December 12, 2013, 02:44:14 PM
The problem with my idea is that there is only one RS-232 port on the Raspbi.
The R-Pi can easily be outfitted with several serial ports via USB-serial adaptors. These cost under $2 shipped.

http://www.ebay.com/itm/USB-PL2303HX-To-RS232-TTL-Auto-Converter-Adapter-Controller-Module-for-Arduino-/360792330927
Title: Re: Can RFM69 communicate with RFM12b?
Post by: timw on December 12, 2013, 06:35:41 PM
It is possible to get the RFM69 and RFM12Bs to talk to each other. You have to tweak the RFM12B code a bit so it matches up with the CRC algorithm of the RFM69, and modify the payload structure (which is different in the RFM69 library), but otherwise they're good to go. I have a mixed network in my home using both.

I modified the original library code which can be found on GitHub:

https://github.com/aanon4/RFM12B
https://github.com/aanon4/RFM69
Title: Re: Can RFM69 communicate with RFM12b?
Post by: Felix on December 12, 2013, 07:10:12 PM
Thanks for sharing - wow if that's true and you got them to talk I have to try that tonight!
Title: Re: Can RFM69 communicate with RFM12b?
Post by: Felix on December 13, 2013, 07:48:05 PM
Have tried your modded libs but I can't seem to have any data go across from RFM12B to RFM69. What frequency are the radios you tested?
I got a RFM69-915Mhz listening using the Gateway example in your modfied RFM69 library and a RFM12b-915Mhz sending with the Send example in your RFM12B library.
Title: Re: Can RFM69 communicate with RFM12b?
Post by: timw on December 14, 2013, 02:29:23 AM
I have your 433 parts, so I can't try the 915 versions. On the 433 pieces I had to tweak the frequencies because the default for the RFM12B was 434 and RFM69 433 (or possibly the other way round - I forget offhand). Also, I'm not using encryption.

I will test these with your send/receive demo sketches to make sure I didnt miss anything. I actually run a star network at home, with a raw RFM69 board attached to a Raspberry Pi as the controller, and have an adaptor library which hides the radio I'm using on each sensor node.
Title: Re: Can RFM69 communicate with RFM12b?
Post by: Felix on December 14, 2013, 06:34:20 PM
If you have a working example where a RFM12B can talk to a RFM69 (along with the libs and settings) that would be great.
Title: Re: Can RFM69 communicate with RFM12b?
Post by: timw on December 17, 2013, 12:41:27 AM
Apparently I hardwired the bitrate in the RFM69 library, so you need to set the RFM12B bitrate as follows:

  radio.Initialize(NODEID, RF12_433MHZ, NETWORKID, 0, 0x7F);

You also need to disable encryption on both ends (they use different algorithms and I've not rewritten the RFM12B version because I don't use encryption at home). They should then talk to each other (currently testing the RFM69 running Struct_send and RFM12B running Receive). Not very intelligible on the console ouput, but should demonstrate them working okay.

Note: I updated my RFM12B fork on GitHut to set the default bitrate to be the same for both RFM12B and RFM69, and I now print a console message if you try to use encryption on the RFM12B.
Title: It WORKS!
Post by: Felix on December 17, 2013, 09:16:58 PM
Yikes, it does work, RFM12B can talk to RFM69!!!

Just reloaded both libs from your github repo (https://github.com/aanon4/RFM12B & https://github.com/aanon4/RFM69) and I used the Struct_receive example for RFM69 and Struct_send example for RFM12B. So RFM12B can send data to RFM69, and I can even read the RSSI of the signal on the RFM69 end. Sweeet!

Which means those of us who have RFM12B nodes can still use them if getting new RFM69 nodes!
The only drawback at the moment is that the encryption on the two platforms is not in synch. The RFM69 has hardware 128bit AES encryption, and the RFM12B has software XXTEA encryption (https://en.wikipedia.org/wiki/XXTEA). This software encryption could easily be ported/duplicated on the RFM69 side.

Great work timw, thanks for sharing it!
Title: Re: Can RFM69 communicate with RFM12B? [YES!]
Post by: MikesTechBlog on December 18, 2013, 01:00:13 AM
Thank you timw! - And of course thank you to Felix for coming up with this whole scheme in the first place.
Title: Re: Can RFM69 communicate with RFM12B? [YES!]
Post by: panosnl on February 07, 2014, 04:59:51 AM
I am currently migrating from RFM12 to RFM69 and with the above libraries got the RFM12 to talk to the RFM69.
Thanks for all the efforts from `Felix and Timw for making this possible!

However the modified RFM12 Library seems to have broken the receive examples that uses pointers:

*radio.DataLen gives:
Code: [Select]
..\libraries\RFM12B_mod/RFM12B.h: In function 'void loop()':
..\libraries\RFM12B_mod/RFM12B.h:202: error: 'volatile uint8_t* RFM12B::DataLen' is private Test_2way_gateway:41: error: within this context
..\libraries\RFM12B_mod/RFM12B.h:201: error: 'volatile uint8_t* RFM12B::Data' is private Test_2way_gateway:42: error: within this context

and
theData = *(Payload*)radio.Data;  gives:
Code: [Select]
d:\Program Files (x86)\Arduino\libraries\RFM12B_mod/RFM12B.h: In function 'void loop()':
d:\Program Files (x86)\Arduino\libraries\RFM12B_mod/RFM12B.h:201: error: 'volatile uint8_t* RFM12B::Data' is private
RFM12B_Struct_gateway:82: error: within this context

When I replaced the modded RFM12 libraries with the original libraries the code compiles OK.

For the DataLen I could use GetDataLen() but for getting data into the struct I don't know how to avoid pointers.
Any suggestions? I like the RFM12 also to be able to listen to at least the RFM12
Title: Re: Can RFM69 communicate with RFM12B? [YES!]
Post by: panosnl on February 07, 2014, 06:45:30 AM

I got the original code and my pointers working now.

I changed the RFM12B.h library from line200:

Code: [Select]
..
#if defined(RF69_COMPAT)
  volatile uint8_t* Data;
  volatile uint8_t* DataLen;
#endif
 
public:
    //constructor
..

so the the Data and DataLen are now defined as public:

Code: [Select]
..
public:

#if defined(RF69_COMPAT)
  volatile uint8_t* Data;
  volatile uint8_t* DataLen;
#endif
 
    //constructor
..
Title: Re: Can RFM69 communicate with RFM12B? [YES!]
Post by: uChip on February 08, 2014, 11:17:33 AM
So now we have two forks of both RFM12B and RFM69 libs.  Is there any interest in bringing Timw's compatibility mods back into the LowPowerLab repo?

I'm now Watching all four forks, but as my local github app does not allow two identically named repos (in the same directory) and as the Arduino IDE does not allow two identically named libraries, maintenance is somewhat awkward.  And as panosnl's post would indicate, ongoing maintenance is going to be needed.

Thoughts?
Title: Re: Can RFM69 communicate with RFM12B? [YES!]
Post by: uChip on February 09, 2014, 03:59:10 PM
I was able to duplicate Felix's test using Struct_receive and RF12_Struct_node, however the node side reports no ACKs received.

Looking at Tim's mods to the RFM12B library I think that maybe the definitions for ACK and Ask for ACK are reversed. 

In SendStart():
Code: [Select]
  rf12_hdr3 = (sendACK ? 0x40 : 0) | (requestACK ? 0x80 : 0);


I am comparing them to the LPL packet definition document which I read as saying that bit 7 (0x80) defines a packet as an ACK and bit6 (0x40) is the ASK for ACK flag. 

I double checked his by looking at the RFM69 library source.  In the interrupt handler I see the following. (code is the same in both Tim's and LPL's libraries).

Code: [Select]

    ACK_RECEIVED = CTLbyte & 0x80; //extract ACK-requested flag
    ACK_REQUESTED = CTLbyte & 0x40; //extract ACK-received flag


The code appears to follow the documentation however the comments are reversed.

Later, in Tim's RFM12B ACKReceived() I see the following.

Code: [Select]

#if !defined(RF69_COMPAT)
          (rf12_hdr3 & 0x40) &&
          !(rf12_hdr3 & 0x80);
#else
          (rf12_hdr1 & RF12_HDR_ACKCTLMASK) &&
          !(rf12_hdr2 & RF12_HDR_ACKCTLMASK);
#endif


It looks to me like the if-clause and the else-clause are reversed.

I tried editing these to wire the bits up correctly, but I just caused more errors and still no ACKs.  I will keep looking but if folks could confirm or refute my interpretation above that would be helpful.

Thanks,
  - Chip
Title: Re: Can RFM69 communicate with RFM12B? [YES!]
Post by: uChip on February 09, 2014, 11:58:37 PM
I have fiddled with this some more this afternoon and have learned a lot.  Hopefully I'm also making changes that are helpful.  :)

First off, I had made the changes suggested by panosnl above.  Sorry but those changes cause problems.  Timw has it correct.  The reason why he made those variables private is that they change meaning in compatibility mode.  Instead, change the sketch not the library.  Specifically, in RFM12B_Struct_node.ino use the accessor functions.  Do not access the variables directly.

  In Loop()
  Change this:
Code: [Select]
      Serial.print('[');Serial.print(radio.GetSender(), DEC);Serial.print("] ");
      for (byte i = 0; i < *radio.DataLen; i++)
        Serial.print((char)radio.Data[i]);
  to this:
Code: [Select]
      Serial.print('[');Serial.print(radio.GetSender(), DEC);Serial.print("] ");
      for (byte i = 0; i < *radio.GetDataLen(); i++)
        Serial.print((char)radio.GetData()[i]);

Now we can make changes to the library.  Here are the changes to address the issues I noticed before, plus I found one more.

in RFM12B.h
Change this:
Code: [Select]
// shorthands to simplify sending out the proper ACK when requested
#define RF12_WANTS_ACK ((rf12_hdr2 & RF12_HDR_ACKCTLMASK) && !(rf12_hdr1 & RF12_HDR_ACKCTLMASK))
to this:
Code: [Select]
// shorthands to simplify sending out the proper ACK when requested
#if !defined(RF69_COMPAT)
#define RF12_WANTS_ACK ((rf12_hdr2 & RF12_HDR_ACKCTLMASK) && !(rf12_hdr1 & RF12_HDR_ACKCTLMASK))
#else
#define RF12_WANTS_ACK ((rf12_hdr3 & 0x40) && !(rf12_hdr3 & 0x80))
#endif

In RFM12B.cpp
  In ACKReceived()
  Change this:
Code: [Select]
#if !defined(RF69_COMPAT)
          (rf12_hdr3 & 0x40) &&
          !(rf12_hdr3 & 0x80);
#else
          (rf12_hdr1 & RF12_HDR_ACKCTLMASK) &&
          !(rf12_hdr2 & RF12_HDR_ACKCTLMASK);
#endif
  to this:
Code: [Select]
#if !defined(RF69_COMPAT)
          (rf12_hdr1 & RF12_HDR_ACKCTLMASK) &&
          !(rf12_hdr2 & RF12_HDR_ACKCTLMASK);
#else
          (rf12_hdr3 & 0x80) &&
          !(rf12_hdr3 & 0x40);
#endif

In RFM12B.cpp
  In SendStart()
  Change this:
Code: [Select]
  rf12_hdr3 = (sendACK ? 0x40 : 0) | (requestACK ? 0x80 : 0);
  to this:
Code: [Select]
  rf12_hdr3 = (sendACK ? 0x80 : 0) | (requestACK ? 0x40 : 0);

With these changes the logic seems correct, however most ACK messages are still lost.  This is because the other side (Struct_receive.ino) does several Serial.print()s before sending the ACK.  This delays when the ACK is sent and the RFM12B_Struct_node side times out.  I don't know if everyone sees this problem or if it's something unique to my environment.  If I change the define for the timeout from 30mS to 150mS about 95% of the ACKs make it in time.

  Change this:
Code: [Select]
#define ACK_TIME    30  // # of ms to wait for an ack
  To this:
Code: [Select]
#define ACK_TIME    150  // # of ms to wait for an ack

I would still like to see Tim's fork merged back into the LPL mainstream as the two have already diverged a little.

Oh, and for what it's worth, I really like the restructuring done in the RFM69 library.  It's much easier to read and understand.
Thanks,
  - Chip
Title: Re: Can RFM69 communicate with RFM12B? [YES!]
Post by: uChip on February 10, 2014, 01:30:08 AM
Found one more on the RFM69 side.

In RFM69.cpp
  In sendWithRetry()
  Change this:
Code: [Select]
    while (millis()-sentTime<retryWaitTime)
    {
      if (ACKReceived(toAddress))
      {
        //Serial.print(" ~ms:");Serial.print(millis()-sentTime);
        return true;
      }
    }
  to this:
Code: [Select]
    do
    {
      if (ACKReceived(toAddress))
      {
        //Serial.print(" ~ms:");Serial.print(millis()-sentTime);
        return true;
      }
    } while (millis()-sentTime<retryWaitTime);

Always want to check the ACKReceived() at least once.

Then in Struct_receive.ino
  In Loop()
  Change this:
Code: [Select]
        if (radio.sendWithRetry(theNodeID, "ACK TEST", 8, 0))  // 0 = only 1 attempt, no retries

  to this:
Code: [Select]
        if (radio.sendWithRetry(theNodeID, "ACK TEST", 8, 0, 50))  // 0 = only 1 attempt, no retries; wait up to 50mS for the ACK


Looks like this ACK is consistently taking 40mS on my machine.  Making me wonder if my machine is slow for some reason.
Title: Re: Can RFM69 communicate with RFM12B? [YES!]
Post by: uChip on February 10, 2014, 12:07:21 PM
As I said, maintenance is awkward.  Also error prone.

In my suggested changes above:
This:
Code: [Select]
for (byte i = 0; i < *radio.GetDataLen(); i++)
should be this:
Code: [Select]
for (byte i = 0; i < radio.GetDataLen(); i++)

Sorry folks,
  - Chip
Title: Re: Can RFM69 communicate with RFM12B? [YES!]
Post by: fgomes on February 17, 2014, 01:38:29 PM
What a coincidence, I was just starting addressing these issues (access to protected variables, ack processing mismatch) when I found this thread and the libraries corrected (https://github.com/aanon4), haven't tested them yet, maybe tonight :-)
One curiosity is that the ack also is not working between two RFM12B nodes when I don't define the compatibility mode, I saw the ack being requested, the gateway sending it, but the node always missing it. The nodes work well with code based on the JeeLib.
Since I have some RFM69 and some RFM12B this compatibility mode is interesting to me, do you have tested the communication between two RFM12B nodes using the compatibility mode? If this also works I will start using only this mode.

Fernando
Title: Re: Can RFM69 communicate with RFM12B? [YES!]
Post by: fgomes on February 18, 2014, 10:01:34 AM
Just an update of the problems I found with the current lib version (always using RF69_COMPAT mode):
In the RFM12B_Struct_node example, there is still the bug *radio.GetDataLen(), it should be replaced by radio.GetDataLen()
In the RFM12B_Struct_Gateway the *radio.DataLen should be replaced by radio.GetDataLen(), and the *(Payload*)radio.Data should be replaced by *(Payload*)radio.GetData()
Do you want me to propose the changes in the GitHub project directly?
I have a setup with two nodes with the RFM12B (JeeNodes) and I have also noticed a frequent failure in the acknowledges, somehow reduced if I wait a bit more than the standard 30ms for the acknowledge, but even waiting more it fails a lot. Also the normal messages also fail from time to time, not so bad as the acks, but I think that they are failing at a rate of 5% or more. I've tried to put some debug to identify the failures in the acknowledges and noticed that part of them fail because of wrong CRC and other part by not receiving the message (ReceiveComplete doesn't return true during the wait for ACK), about 50% for each case. These situations shouldn't occur when the two nodes are 10cm away from each other, so to introduce an additional test scenario I put the RFM12B_Struct_node in another room, about 10m away from the gateway with a brick wall between them, and the result is more or less the same, so it seems it isn't a noise / RF power limitation but some implementation issue. I'll have to use a sniffer to try to dig more into this.
Using the same two nodes with the original code for the JeeNodes the communication results are much better. Any ideas of what could be the problem?

Fernando
Title: Re: Can RFM69 communicate with RFM12B? [YES!]
Post by: uChip on February 18, 2014, 11:06:50 AM
The first problem you mention is my mistake in the post above.  That one and the other changes to the examples sketches to use the accessor functions have already been sent to Timw as a pull request.  No response from Tim yet.

I have tested most of the example sketches with two RFM12Bs.  Once the above changes are made they all seem to work, but they all have the problem that you mention.  I found the same issue with ACKs but thought it was something unique to my system.  I can get most ACKs to go through if I increase the ACK timeout to about 150 to 200 mS.  Even there some small percentage of ACKs are lost.

  - Chip
Title: Re: Can RFM69 communicate with RFM12B? [YES!]
Post by: fgomes on February 20, 2014, 09:32:54 AM
Thanks for your reply, I'm continuing to make some tests with the RFM12B library in the RF69_COMPAT mode, and found two things that I need to clarify:

In the function RFM12B::SendStart there is a increment of 3 in the rf12_len, and in the GetDataLen function the rf12_len is decremented by 3 (to keep the original size of the payload). So the message that goes to the air has a payload length that is 3 byte bigger than the real payload, is this a need for the RFM69 module?

I'm sending messages periodically and printing the received bytes inside ReceiveComplete to try to figure out why I'm loosing some messages between two nodes that are side by side. What I found is that the messages that are lost have always the same byte changed, the last CRC byte.

Good message:
64 17 1 6F 40 2 0 0 30 42 1 0 0 A0 41 1 0 0 A9 41 0 0 0 0 0 59 98
Corrupted message:
64 17 1 6F 40 2 0 0 30 42 1 0 0 A0 41 1 0 0 A9 41 0 0 0 0 0 59 99

Good message:
64 17 1 6F 40 2 0 0 28 42 1 0 0 A8 41 1 0 0 AE 41 0 0 0 0 0 C2 64
Corrupted message:
64 17 1 6F 40 2 0 0 28 42 1 0 0 A8 41 1 0 0 AE 41 0 0 0 0 0 C2 65

Good message:
64 17 1 6F 40 2 0 0 28 42 1 0 0 A8 41 1 0 80 AC 41 0 0 0 0 0 5F 7
Corrupted message:
64 17 1 6F 40 2 0 0 28 42 1 0 0 A8 41 1 0 80 AC 41 0 0 0 0 0 5F 6

It is always the last byte (second CRC byte) that gets corrupted, and always the same bit changed in the byte, B0 changes from 0 to 1, or from 1 to 0, always the same bit in the same byte. The CRC in these cases is always 2E 0D instead of 1D 0F, and the wrong CRC value is the same even for different messages. In average I get a failure rate of about 4% (18 corrupted messages in 500) for two nodes that sit side by side (10 cm away from each other).

Any idea of why could this happen?

Fernando

Title: Re: Can RFM69 communicate with RFM12B? [YES!]
Post by: uChip on February 20, 2014, 10:33:36 PM
I can tackle the first question.  The length field of the original RFM12B does not include the header bytes for DestID and SourceID.  In the RFM69 compat mode both these (now called DestID and SenderID) are after the PayloadLen byte plus there is the new CTL byte for defining ACK and ASKforACK.  Altogether that makes the length field three bytes longer than it was before.  The GetDataLen function retrieves the PayloadLen byte and then reduces it by three because that returns the length of the data, not the length of the entire payload.  Felix has a nice drawing of the packet structure in his documentation for each of RFM12B and RFM69.  You might want to give those a look and compare them side-by-side. 

  - Chip