How to make RFM69 work on Photon? [SOLVED - new library RFM69-Particle]


#48

Yes, the ATC enabled on the Gateway enables it to work with Nodes in order for the Nodes to adjust their power level.

This kind of assumes that nodes operate on battery and primarily transmits data to the gateway. So it saves battery and and is friendlier to the spectrum for other devices. And that the Gateway primarily receives (other than acks and basic TX) and that it is on wall power.

I can’t see why you couldn’t customize it to work both directions but may mean digging into the library code.
There could be a logic conflict when both are turning down power that you’d need to address with a time limit or other device (e.g. both dropped to power level 7. Node transmits but fails to receive an ACK (because Gateway’s transmission at 7 doesn’t reach), and keeps dialing up power all the way to 31 but still fails to receive an ACK because the ACK doesn’t reach it. So either the Gateway needs to TX a test message now and then, or after a set time of not receiving a message dial up the power. You can see you’re running into classical messenger problems.)


#49

Ok that’s what I thought, just wanted to confirm. Makes sense that the gateway will transmit ACK’s at max power to ensure even the farthest nodes get confirmation of sends and of course the gateway is on mains power so that’s not an issue.

Thanks for all your help.


#50

@bloukingfisher after a bit of a delay I am back at this. I have aquired some RFM69 modules
https://www.aliexpress.com/item/RFM69HW-433Mhz-RFM12B-HopeRF-Wireless-Transceiver-RFM69HW-433S2-for-Remote-HM-Free-Shipping/32802346626.html?spm=a2g0s.9042311.0.0.2TZClG
I want to be sure I am going to get started on the right track. Per your suggestion I am going to try to communicate using a pair of photons with the RFM69’s attached of course. I am going to use your examples that you provided on your github
https://github.com/bloukingfisher/RFM69-Particle/tree/master/firmware/examples
So, when I paste the hello-photon-rx-rfm69.ino in to the particle IDE, then include the RFM69-PARTICLE in to the sketch. Now, when I click on compile it complains /rfm69.cpp:90:43: ‘WiFi’ was not declared in this scope. So, I am sure that it is something simple that I have overlooked. Guess I have been reading too much today, my head hurts!
Thanks in advance for your help


#51

It’s compiling fine for me @jackpot - are you using the web IDE? Go to libraries > RFM69-Particle > down the left click “hello-photon-rx-rfm69.ino” and select “Use this example” > Verify.

Compiles with no errors.


#52

@bloukingfisher Thank you for your reply. I did finally get a compile and am not really sure what was going on. But on to the next step. I have flashed both Photons and edited the code to reflect my RFM69HW for RX

and TX

TX serial prints out;
.Sending Hello Photon 1
OK, sent without retrying

RX serial prints out

Which according to your earlier troubleshooting in this post means it is listening but not RX anything. I am using an 82mm antenna found on the web here
https://talk.jeelabs.net/topic/12
for 868MHZ board, 1/4 wave. I have edited both TX and RX to reflect the correct frequency as well. Any suggestions on what to try next are appreciated.
Thanks


#53

@jackpot Can you eliminate that it is a hardware/wiring problem? Maybe swap the RX and TX code on the two Photons and see if your original RX says it is TX’ing? Or physically swap the radios around to check that there is not a bad connection (those little boards are not easy for prototyping connections).

How are you powering it? USB should be fine, but have the units fairly close (within a foot or two) and dial back the transmission power say to 5 or less. Since you’re using the HW version it will consume more power and I’ve had issues before on the non-HW version that things start failing above certain power levels.

You can also test setting the HW setting to FALSE that will not employ the additional power amplification registers in the module. Once you get it transmitting successfully you can start increasing power settings or testing power setup/caps, etc.

EDIT: Note the HW requires up to 120mA during transmission, thus the need to dial down the transmit power


#54

@bloukingfisher

Have done this already. Results are the same. Old RX now has TX code flashed, reports in serail monitor
.Sending Hello Photon 1
OK, sent without retrying
and old TX now has RX code flashed and reports serial monitor

I have checked the connections several times however I will try this suggestion next.

Yes, USB

Noted, will do

I have tried this before as well with similar results. I will try the suggestions you have mentioned and report back with my findings. Thank you again for your help


#55

@jackpot try this on your TX side. Curious to see if you see sent or failed:

void loop() {

  Serial.print("."); //THis gives us a neat visual indication of time between messages received

  char radiopacket[20] = "Hello Photon #";
  itoa(packetnum++, radiopacket+13, 10);
  Serial.print("Sending "); Serial.println(radiopacket);
  
  //send the message
  
    
    // Uncomment below and comment out above if you want to send with retry (which will look for an ACK message or resends)
    if (radio.sendWithRetry(RECEIVER, radiopacket, strlen(radiopacket))) { //target node Id, message as string or byte array, message length
     Serial.println("OK, sent with retry");
    }
    else
    {
      Serial.println("Failed to send");  
    }
    
    //send message to Particle console if not using serial
    String TXMessage = "[NODE: " + String(NODEID) + "]  " + String(radiopacket) + " ";
    Particle.publish("Message transmitted",TXMessage,360,PRIVATE);    
    radio.receiveDone(); //put radio in RX mode

  delay(2000);  //wait 2 seconds between transmits


} //end loop

#56

And replace this in your setup function to check if the radio is actually initializing:

// Initialize radio
//radio.initialize(FREQUENCY,NODEID,NETWORKID);
delay(10000); //give time for user to connect serial monitor if necessary
if (!radio.initialize(FREQUENCY,NODEID,NETWORKID))
{Serial.println(“init failed”);}
else
{Serial.println(“init OK”);}


#57

@bloukingfisher Your second suggestion solved the issue. Must have a bad board is all I can figure. When I switched out the radios, I found that the second Photon was not TX correctly. What I had failed to notice (even with my cheaters on) was that my Photon was dropping the cloud connection, changing from breathing cyan to breathing green. So, I made up a new RFM and attached and it works perfect.

So, I apprecaite the coaching and aplogize for missing this. Thank you VERY much again for your help. Now to see if I can get it to work on Electron.


#58

I hadnt seen your reply before I sent you my last message. But I did go ahead and try this

//send the message
    //radio.send(RECEIVER, radiopacket, strlen(radiopacket));//target node Id, message as string or byte array, message length
    //Serial.println("OK, sent without retrying"); //Why send without retrying? If the RX is down for some reason, the TX will remain in a state of high power
    //which can drain your battery or overwhelm your power source. 

    // Uncomment below and comment out above if you want to send with retry (which will look for an ACK message or resends)
    /if (radio.sendWithRetry(RECEIVER, radiopacket, strlen(radiopacket))) { //target node Id, message as string or byte array, message length
     Serial.println("OK, sent with retry");

It was working fine and then all of a sudden, nothing. I have changed code on the boards still nothing. I guess I am going to make up another RFM and try that for now. Then I will move back to what you have asked me to do.
Thanks

EDIT
I am now back to where I was before. Strange that one of the RFM69 would just stop working in the middile of things. Even more strange is that while I was messing around with settings before, I thought I would leave the frequency set to 915mhz just for giggles. The boards are marked 868 but they appear to be working on 915. Guess its not the first time something was marked incorrectly


#59

With the changes added,

void setup() 
{
 
    Serial.begin(115200); // Open serial monitor at 115200 baud to see ping results.
    Particle.publish("RFM69 TX Startup setup","Completed",360,PRIVATE);
    Particle.publish("WiFi signal",String(WiFi.RSSI()),360,PRIVATE);
    Serial.println("RFM69 Based Transmitter");
  
    // Hard Reset the RFM module - Optional
  pinMode(RFM69_RST, OUTPUT);
  digitalWrite(RFM69_RST, HIGH);
  delay(100);
  digitalWrite(RFM69_RST, LOW);
  delay(100);
  
   // Initialize radio
//radio.initialize(FREQUENCY,NODEID,NETWORKID);
delay(10000); //give time for user to connect serial monitor if necessary
if (!radio.initialize(FREQUENCY,NODEID,NETWORKID))
{Serial.println("init failed");}
else
{Serial.println("init OK");}
  
  // To improve distance set a lower bit rate. Most libraries use 55.55 kbps as default
  // See https://lowpowerlab.com/forum/moteino/rfm69hw-bit-rate-settings/msg1979/#msg1979
  // Here we will set it to 9.6 kbps instead 
  radio.writeReg(0x03,0x0D); //set bit rate to 9k6
  radio.writeReg(0x04,0x05);
  
  radio.setPowerLevel(5); // power output ranges from 0 (5dBm) to 31 (20dBm)
                          // Note at 20dBm the radio sources up to 130 mA! 
                         // Selecting a power level between 10 and 15 will use ~30-44 mA which is generally more compatible with Photon power sources
                        // As reference, power level of 10 transmits successfully at least 300 feet with 0% packet loss right through a home, sufficient for most use
    
  radio.encrypt(ENCRYPTKEY);
  
  Serial.print("\nListening at ");
  Serial.print(FREQUENCY==RF69_433MHZ ? 433 : FREQUENCY==RF69_868MHZ ? 868 : 915);
  Serial.println(" MHz");
}


//=========================MAIN LOOP===========================================
void loop() {

  Serial.print("."); //THis gives us a neat visual indication of time between messages received

  char radiopacket[20] = "Hello Photon #";
  itoa(packetnum++, radiopacket+13, 10);
  Serial.print("Sending "); Serial.println(radiopacket);
  
  //send the message
  
    
    // Uncomment below and comment out above if you want to send with retry (which will look for an ACK message or resends)
    if (radio.sendWithRetry(RECEIVER, radiopacket, strlen(radiopacket))) { //target node Id, message as string or byte array, message length
     Serial.println("OK, sent with retry");
    }
    else
    {
      Serial.println("Failed to send");  
    }
    
    //send message to Particle console if not using serial
    String TXMessage = "[NODE: " + String(NODEID) + "]  " + String(radiopacket) + " ";
    Particle.publish("Message transmitted",TXMessage,360,PRIVATE);    
    radio.receiveDone(); //put radio in RX mode

  delay(2000);  //wait 2 seconds between transmits


} //end loop

I am seeing mostly Failed to send. There is at least one instance where it sent OK, sent with retry on the TX side

RX serial looks like this


#60

I’m getting a little confused. So you came right, but then something went wrong again?

From the above output, looks like the RX is getting all the messages even though TX says send failed? Note, that was probably not the best message for “Fail” - it really means that “did not receive an ACK” - which implies TX may have failed but not necessarily though as TX could succeed but fail to receive or process an ACK.

So it looks like the RX is receiving everything? And it also returns an ACK so the TX should know that the message went through.

Sparkfun has a great guide that should help you too.

Wait, I have a suspicion. The ACK is sent, but not fast enough. Look at the code on the RX side. Move the code that checks for Hello and sends an ACK up to run immediately after a message is received, then follow with printing serial and publishing to console.

Like such:

void loop() {

Serial.print("."); //THis gives us a neat visual indication of time between messages received

  //check if something was received (could be an interrupt from the radio)
  if (radio.receiveDone())
  {
    //check if received message contains Hello
    if (strstr((char *)radio.DATA, "Hello"))
    {
      //check if sender wanted an ACK
      if (radio.ACKRequested())
      {
        radio.sendACK();
        Serial.println(" - ACK sent");
      }
      else {Serial.println(" - No ACK sent");}
    }  
    
    //print message received to serial
    Serial.println(" ");
    Serial.print('[');Serial.print(radio.SENDERID);Serial.print("] ");
    Serial.print((char*)radio.DATA);
    Serial.print("   [RX_RSSI:");Serial.print(radio.RSSI);Serial.print("]");
    
    //send message to Particle console if not using serial
    String RXMessage = "[" + String(radio.SENDERID) + "]  " + String((char*)radio.DATA) + " [RSSI: " + String(radio.RSSI) + "]";
    Particle.publish("Message received",RXMessage,360,PRIVATE);

  
  }

  radio.receiveDone(); //put radio in RX mode
  
  delay(1000);


} //end loop

#61

Sorry about that. I am trying to keep this all organized. Regardless, I am back working again. [quote=“bloukingfisher, post:60, topic:26497”]
So it looks like the RX is receiving everything? And it also returns an ACK so the TX should know that the message went through
[/quote]

Yes, I would agree. I am confused by Failed to Send on the TX side. What is that telling me? Why am I only getting occasional Ok, send with retry? Again, what is that telling me?

I made the changes to the RX code, flashed it and no real difference that I see. Here is a copy of RX serial and you can see where I reset the TX board

and here is the TX serial

Thanks for the link BTW Ill start reading it


#62

I see. Perplexing.

I would (in addition to reading the link):

  1. Again, swap the RX and TX hardware. It looks like the TX side is having an issue with receiving, but yet sending fine. You want to test and make sure both can units can receive equally well.

  2. Add code to the TX side to print out the RSSI of the ACK that it seems to receive 1/10 times. The RSSI strength should very closely match the RSSI the RX is reporting. But if it is much lower (say RX reports -52 or -86 and TX reports -96 or -110) it’s telling you the TX unit is not receiving the way it should.


#63

Well this is getting a bit above me but here is what I attepted with adding the RSSI portion to the TX code

void loop() {

  Serial.print("."); //THis gives us a neat visual indication of time between messages received

  char radiopacket[20] = "Hello Photon #";
  itoa(packetnum++, radiopacket+13, 10);
  Serial.print("Sending "); Serial.println(radiopacket);
  
  //send the message
  
    
    // Uncomment below and comment out above if you want to send with retry (which will look for an ACK message or resends)
    if (radio.sendWithRetry(RECEIVER, radiopacket, strlen(radiopacket))) { //target node Id, message as string or byte array, message length
     Serial.println("OK, sent with retry");
    }
    else
    {
      Serial.println("Failed to send");  
    }
    
    //send message to Particle console if not using serial
    String TXMessage = "[NODE: " + String(NODEID) + "]  " + String(radiopacket) + " ";
    Particle.publish("Message transmitted",TXMessage,360,PRIVATE);    
    radio.receiveDone(); //put radio in RX mode
    
      //print message received to serial
    Serial.println(" ");
    Serial.print('[');Serial.print(radio.SENDERID);Serial.print("] ");
    Serial.print((char*)radio.DATA);
    Serial.print("   [RX_RSSI:");Serial.print(radio.RSSI);Serial.print("]");
    
    //send message to Particle console if not using serial
    String RXMessage = "[" + String(radio.SENDERID) + "]  " + String((char*)radio.DATA) + " [RSSI: " + String(radio.RSSI) + "]";
    Particle.publish("Message received",RXMessage,360,PRIVATE);


  delay(2000);  //wait 2 seconds between transmits


} //end loop

If that is correct, then my TX board is not RX at all because I am seeing [RX_RSSI:0]


Changed roles on the hardware and the results are the same.
Thank you


#64

OK, with hardware swapped with the same result that minimizes a hardware issue.

Because with failed to send you never received an ACK you also will not have an RSSI, thus the 0. You will need to look for the odd “OK, sent with retry” to see if it reports the RSSI.

Maybe try the example code from the Sparkfun link (with the correct #include for particle libraries), or example code from RadioHead examples. I know the code worked for me (primarily on non-HW versions, although I briefly tested 1 HW unit on the TX side but may not have used sendWithRetry).

Do me a favor if you can - comment out all the particle publish lines from both RX and TX and test again.


#65

Ah, makes sense

Ill do it and let you know]


#66

results are the same. RX_RSSI:-82, TX_RSSI:0


#67

I’m not sure where to go other than starting with the RadioHead or Sparkfun examples.

You can try lastRssi() instead - but still, you need to receive at least one message to obtain the value.