RFM95x LoRa Arduino and Pi

CircuitPython on hardware including Adafruit's boards, and CircuitPython libraries using Blinka on host computers.

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
lzemail
 
Posts: 52
Joined: Tue May 29, 2012 5:00 pm

RFM95x LoRa Arduino and Pi

Post by lzemail »

Goal: Pi transmits and Arduino Uno receives via two RFM95x (https://www.adafruit.com/product/3072)
Problem: When Pi transmits, Arduino doesn't show any received data (via serial monitor)
(The reverse direction, i.e. Arduino as sender, Pi as receiver, works.)

Hardware and software setup/config per various Adafruit tutorials/examples.

1. Running rfm95x_check.py code on Pi, the output shows
RFM9x: Detected
RFM9x: Detected
RFM9x: Detected

rfm95x_check.py code

Code: Select all

import time
import busio
from digitalio import DigitalInOut, Direction, Pull
import board
import adafruit_rfm9x

CS = DigitalInOut(board.CE1)
RESET = DigitalInOut(board.D25)
spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO)

while True:
        try:
            rfm9x = adafruit_rfm9x.RFM9x(spi, CS, RESET, 915.0)
            print('RFM9x: Detected')
        except RuntimeError as error:
            print('RFM9x Error: ', error)

time.sleep(1)
2. Python code (transmit) on Pi

Code: Select all

import time
import busio
from digitalio import DigitalInOut, Direction, Pull
import digitalio
import board
import adafruit_rfm9x

CS = DigitalInOut(board.CE1)
RESET = DigitalInOut(board.D25)
spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO)
rfm9x = adafruit_rfm9x.RFM9x(spi, CS, RESET, 915.0)
rfm9x.tx_power = 23

LED = digitalio.DigitalInOut(board.D18)
LED.direction = digitalio.Direction.OUTPUT

rfm9x.send(bytes("Hello world!\r\n", "utf-8"))
print("Sent Hello World message!")
3. Code on Arduino (receive)

Code: Select all

// Arduino9x_RX
// -*- mode: C++ -*-
// Example sketch showing how to create a simple messaging client (receiver)
// with the RH_RF95 class. RH_RF95 class does not provide for addressing or
// reliability, so you should only use RH_RF95 if you do not need the higher
// level messaging abilities.
// It is designed to work with the other example Arduino9x_TX

#include <SPI.h>
#include <RH_RF95.h>

#define RFM95_CS 4  
#define RFM95_RST 2 
#define RFM95_INT 3  //G0 

// Change to 434.0 or other frequency, must match RX's freq!
#define RF95_FREQ 915.0

// Singleton instance of the radio driver
RH_RF95 rf95(RFM95_CS, RFM95_INT);

// Blinky on receipt
#define LED 13

void setup() 
{
  pinMode(LED, OUTPUT);     
  pinMode(RFM95_RST, OUTPUT);
  digitalWrite(RFM95_RST, HIGH);

  while (!Serial);
  //Serial.begin(9600);
  Serial.begin(115200);
  delay(100);

  Serial.println("Arduino LoRa RX Test!");
  
  // manual reset
  digitalWrite(RFM95_RST, LOW);
  delay(10);
  digitalWrite(RFM95_RST, HIGH);
  delay(10);

  while (!rf95.init()) {
    Serial.println("LoRa radio init failed");
    while (1);
  }
  Serial.println("LoRa radio init OK!");

  // Defaults after init are 434.0MHz, modulation GFSK_Rb250Fd250, +13dbM
  if (!rf95.setFrequency(RF95_FREQ)) {
    Serial.println("setFrequency failed");
    while (1);
  }
  Serial.print("Set Freq to: "); Serial.println(RF95_FREQ);

  // Defaults after init are 434.0MHz, 13dBm, Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on

  // The default transmitter power is 13dBm, using PA_BOOST.
  // If you are using RFM95/96/97/98 modules which uses the PA_BOOST transmitter pin, then 
  // you can set transmitter powers from 5 to 23 dBm:
  rf95.setTxPower(23, false); 
}

void loop()
{
  if (rf95.available())
  {
    // Should be a message for us now   
    uint8_t buf[RH_RF95_MAX_MESSAGE_LEN];
    uint8_t len = sizeof(buf);
    
    if (rf95.recv(buf, &len))
    {
      digitalWrite(LED, HIGH);
      RH_RF95::printBuffer("Received: ", buf, len);
      Serial.print("Got: ");
      Serial.println((char*)buf);
      Serial.print("RSSI: ");
      Serial.println(rf95.lastRssi(), DEC);
      
      digitalWrite(LED, LOW);
    }
    else
    {
      Serial.println("Receive failed");
    }
  }
}
4. No error messages showing on either side.
After uploading the above Arduino code, Arduino serial monitor shows
16:21:22.938 -> Arduino LoRa RX Test!
16:21:23.085 -> LoRa radio init OK!
16:21:23.085 -> Set Freq to: 915.00


Then, after running the above Python code on Pi, the Pi side shows
Sent Hello World message!

Arduino side doesn't show the message "Hello World!"

6. RFM95x board's G0 is not connected to anything on the Pi side.

What did I do wrong?
Any help would be appreciated. Thanks.

User avatar
blnkjns
 
Posts: 963
Joined: Fri Oct 02, 2020 3:33 am

Re: RFM95x LoRa Arduino and Pi

Post by blnkjns »

With LoRa you don't send peer-to-peer. You probably have your Pi set up as LoraWAN hub, so it can receive and transmit to nodes. The UNO is way underpowered to function as hub, it can only be a node.

User avatar
jerryn
 
Posts: 1868
Joined: Sat Sep 14, 2013 9:05 am

Re: RFM95x LoRa Arduino and Pi

Post by jerryn »

The code above is not using LoraWAN and should work. I have run similar configuratons many times, though not with an UNO.
The Pi is only sending the message once and it may be that the Uno is missing it.
I have not used an UNO with the RFM9x boards but if it is transmitting successfully, it should also be able to receive,
Try setting up a repeating loop on the Pi to send the message every 5 seconds or so and see if it gets received.

Later today, I should be able to reproduce your setup and will try it myself.

User avatar
lzemail
 
Posts: 52
Joined: Tue May 29, 2012 5:00 pm

Re: RFM95x LoRa Arduino and Pi

Post by lzemail »

Thanks for the responses.

blnkjns, no hub setup, Pi transmits, Uno receives, one to one.

jerryn, I added the Pi transmission in a loop (I hope I did it correctly), I still don't see the message on the Uno side. The Pi side shows the following (about one message every 5 seconds until I terminate the Python code)
Sent Hello World message!
Sent Hello World message!
Sent Hello World message!
Sent Hello World message!
Sent Hello World message!
Sent Hello World message!

The modified Python code is

Code: Select all

import time
import busio
from digitalio import DigitalInOut, Direction, Pull
import digitalio
import board
import adafruit_rfm9x

CS = DigitalInOut(board.CE1)
RESET = DigitalInOut(board.D25)
spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO)
rfm9x = adafruit_rfm9x.RFM9x(spi, CS, RESET, 915.0)
rfm9x.tx_power = 23

LED = digitalio.DigitalInOut(board.D18)
LED.direction = digitalio.Direction.OUTPUT



while True:
    rfm9x.send(bytes("Hello world!\r\n", "utf-8"))
    print("Sent Hello World message!")
    time.sleep(5)
jerryn, I am looking forward to your test result, thanks for your time.

User avatar
jerryn
 
Posts: 1868
Joined: Sat Sep 14, 2013 9:05 am

Re: RFM95x LoRa Arduino and Pi

Post by jerryn »

OK -- I found the problem.
The Pi (Circuitpython) library defaults to disabling the CRC on the transmitted packet
add

Code: Select all

rfm9x.enable_crc=True
after the
rfm9x.tx_power=23

as part of the configuration sequence

It works for me with an UNO after that.

User avatar
jerryn
 
Posts: 1868
Joined: Sat Sep 14, 2013 9:05 am

Re: RFM95x LoRa Arduino and Pi

Post by jerryn »

I made a sime chage to your Arduino program to add a "null terninator" to the received packet. THe Pi does not send a null terminated string so the Arduino print of buf runs on past the end of the message and print garbage.
here is the modified program for the Arduino

Code: Select all

// Arduino9x_RX
// -*- mode: C++ -*-
// Example sketch showing how to create a simple messaging client (receiver)
// with the RH_RF95 class. RH_RF95 class does not provide for addressing or
// reliability, so you should only use RH_RF95 if you do not need the higher
// level messaging abilities.
// It is designed to work with the other example Arduino9x_TX

#include <SPI.h>
#include <RH_RF95.h>

#define RFM95_CS 4 
#define RFM95_RST 2
#define RFM95_INT 3  //G0

// Change to 434.0 or other frequency, must match RX's freq!
#define RF95_FREQ 915.0

// Singleton instance of the radio driver
RH_RF95 rf95(RFM95_CS, RFM95_INT);

// Blinky on receipt
#define LED 13

void setup()
{
  pinMode(LED, OUTPUT);     
  pinMode(RFM95_RST, OUTPUT);
  digitalWrite(RFM95_RST, HIGH);

  while (!Serial);
  //Serial.begin(9600);
  Serial.begin(115200);
  delay(100);

  Serial.println("Arduino LoRa RX Test!");
 
  // manual reset
  digitalWrite(RFM95_RST, LOW);
  delay(10);
  digitalWrite(RFM95_RST, HIGH);
  delay(10);

  while (!rf95.init()) {
    Serial.println("LoRa radio init failed");
    while (1);
  }
  Serial.println("LoRa radio init OK!");

  // Defaults after init are 434.0MHz, modulation GFSK_Rb250Fd250, +13dbM
  if (!rf95.setFrequency(RF95_FREQ)) {
    Serial.println("setFrequency failed");
    while (1);
  }
  Serial.print("Set Freq to: "); Serial.println(RF95_FREQ);

  // Defaults after init are 434.0MHz, 13dBm, Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on

  // The default transmitter power is 13dBm, using PA_BOOST.
  // If you are using RFM95/96/97/98 modules which uses the PA_BOOST transmitter pin, then
  // you can set transmitter powers from 5 to 23 dBm:
  rf95.setTxPower(23, false);
}

void loop()
{
  if (rf95.available())
  {
    // Should be a message for us now   
    uint8_t buf[RH_RF95_MAX_MESSAGE_LEN];
    uint8_t len = sizeof(buf);
   
    if (rf95.recv(buf, &len))
    {
      digitalWrite(LED, HIGH);
      RH_RF95::printBuffer("Received: ", buf, len);
      Serial.print("Got: ");
      buf[len]=0;
      Serial.println((char*)buf);
      Serial.print("RSSI: ");
      Serial.println(rf95.lastRssi(), DEC);
     
      digitalWrite(LED, LOW);
    }
    else
    {
      Serial.println("Receive failed");
    }
  }
}
and here is the Pi side with the CRC enabled,

Code: Select all

import time
import busio
from digitalio import DigitalInOut, Direction, Pull
import digitalio
import board
import adafruit_rfm9x

CS = DigitalInOut(board.CE1)
RESET = DigitalInOut(board.D25)
spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO)
rfm9x = adafruit_rfm9x.RFM9x(spi, CS, RESET, 915.0)
rfm9x.tx_power = 23
rfm9x.enable_crc=True

LED = digitalio.DigitalInOut(board.D18)
LED.direction = digitalio.Direction.OUTPUT



while True:
    rfm9x.send(bytes("Hello world!\r\n", "utf-8"))
    print("Sent Hello World message!")
    time.sleep(5)



User avatar
lzemail
 
Posts: 52
Joined: Tue May 29, 2012 5:00 pm

Re: RFM95x LoRa Arduino and Pi

Post by lzemail »

jerryn, Thank you very much. Followed your instructions, it works now. The Uno serial monitor now shows the received "Hello World" message in addition to RSSI info, etc.

11:54:22.552 -> Got: Hello world!

Without your help, I would have never figured it out myself.
I am trying to learn about the CRC. Does the CRC parameter you corrected prevent Pi from sending or prevent Uno from receiving or both or something else?
Thanks again.

User avatar
jerryn
 
Posts: 1868
Joined: Sat Sep 14, 2013 9:05 am

Re: RFM95x LoRa Arduino and Pi

Post by jerryn »

The CRC (Cyclic Redundancy Check) is a sort of "checksum" appended to the packet. It is optional and Arduino has it enabled by default but CircuitPython has it disabled by default.
It has to be set the same on both ends or the received packet will be rejected. That is what was happening. It was transmitting OK, but the Arduino was ignoring the packet without the proper CRC appended.
A note should be added or the default for CircuitPython should probably be changed. I will raise this with the Circuitpyhton team.

Good luck with your projects!

User avatar
lzemail
 
Posts: 52
Joined: Tue May 29, 2012 5:00 pm

Re: RFM95x LoRa Arduino and Pi

Post by lzemail »

jerryn, Understood. Thank you very much.

User avatar
jerryn
 
Posts: 1868
Joined: Sat Sep 14, 2013 9:05 am

Re: RFM95x LoRa Arduino and Pi

Post by jerryn »

FYI - the CircuitPython Library has been updated to enable the CRC by default.
https://github.com/adafruit/Adafruit_Ci ... /tag/2.2.0
It will be avail be in the next "bundle" release tonight.

User avatar
lzemail
 
Posts: 52
Joined: Tue May 29, 2012 5:00 pm

Re: RFM95x LoRa Arduino and Pi

Post by lzemail »

jerryn, thank you for the update.

Locked
Please be positive and constructive with your questions and comments.

Return to “Adafruit CircuitPython”