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

One more thing, does it have to be compiled in Dev or will it work in Build?

RFM69-Particle library and examples you can use the web Build (but you can do in Dev if you want).
It is RadioHead that requires Dev. Crossing fingers you get it working tonight!

I tried the examples from the forum message post 18 with no luck. Now one thing is that I’m using a sparkfun photon redboard which uses the p1, but I understood it was essentially the same. Is this a wrong assumption?

Hey bloukingfisher, it helps if you wire the radio to the right pins on the redboard. The Sparkfun Photon Redboard has two sets of analog pins that are duplicated, but only to be compatible with arduino shields and the one set isn’t actually connected to the photon chip…doh!! Getting Hello Worlds with ACK sent…sorry for waking this thread up, but thanks for humouring me.

1 Like

Happy you got it working! That’s what my lesson has been and why I said if you have 2 Photons first make sure you get it working within the same system to eliminate hardware/wiring, etc. Share with the topic if you discover other tips/improvements.

Yes, that would have been a good plan, to eliminate other factors. I did at one point try reversing roles by having the Moteino act as the receiver and the photon as the transmitter, but obviously with the rfm96hcw not connected it never would have worked in a million years.

My plan for this is to make the photon a gateway and also an MQTT agent so that it will convert all my sensor data to MQTT payloads to feed into a Mosquito Server. It’s also going to have a BME280 to measure the indoor temp/humidity and barometric pressure for my weewx weather station so it’s going to be a very busy photon, good thing it wont be running on batteries. The moteino is actually replacing the P1 that was in my weather station because that guy is on battery with a solar panel, and I want more realtime monitoring with rain and wind, so the lower power moteino made more sense here especially since it wont be running wifi.

I’ll probably start a new thread with my build, but I will certainly reference this one as it was very helpful.

When using ATC on the gateway side, does the setPowerlevel do nothing? I noticed that if I try different settings in the code, my gateway continues to send at max power which is 31. I know conceptually it makes sense because you want the gateway to not fluctuate, so you would want it to be pinned to the floor and then have your nodes work out what power they need to send to the gateway, but I just want to confirm that with you.

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.)

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.

@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

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.

@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

@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

@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

@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

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”);}

@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.

1 Like

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

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

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