RFM95 LoRa very low RSSI

I have been using these modules, one wired directly to a rp2040 feather, and the other wired to a Raspberry Pi Pico W. The RSSI usually hovers around -110 to -120 when the boards are about 20cm apart, and the signal cuts out when they are over 2 meters apart. I have tried using wire antennas (cut to the right size), and larger RP-SMA antennas, which have little to no impact. My only ideas are that either my code has an error, or I have damaged one or both modules.

Code for the ground station:

// Feather9x_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 Feather9x_TX

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

#define RFM95_CS   8
#define RFM95_INT  7
#define RFM95_RST  9

// 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);

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

  Serial.begin(115200);
  while (!Serial) delay(1);
  delay(100);

  Serial.println("Feather 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");
    Serial.println("Uncomment '#define SERIAL_DEBUG' in RH_RF95.cpp for detailed debug info");
    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(20, 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_BUILTIN, HIGH);
      RH_RF95::printBuffer("Received: ", buf, len);
      Serial.print("Got: ");
      Serial.println((char*)buf);
       Serial.print("RSSI: ");
      Serial.println(rf95.lastRssi(), DEC);
      /*
      // Send a reply
      uint8_t data[] = "And hello back to you";
      rf95.send(data, sizeof(data));
      rf95.waitPacketSent();
      Serial.println("Sent a reply");
      digitalWrite(LED_BUILTIN, LOW);
      */
    } else {
      Serial.println("Receive failed");
    }
  }
}

Code for the transmitter:

type or paste code here
#include <SPI.h>
#include <RH_RF95.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BNO08x.h>
#include <Adafruit_BMP3XX.h>
#include <Adafruit_NeoPixel.h>
#include <SingleFileDrive.h>
#include <LittleFS.h>




#define RFM95_CS   8
#define RFM95_INT  7
#define RFM95_RST  9
#define RF95_FREQ 915.0
#define TIMEOUT 1000


Adafruit_BNO08x bno; // MPU
RH_RF95 rf95(RFM95_CS, RFM95_INT); // RADIO

sh2_SensorValue_t sensorValue;
bool debug = false;
bool printable = true;
File f;

void setupBNO(){
  while(!bno.begin_I2C()){
    Serial.println("Failed to find BNO085");
    delay(200);
  }

  Serial.println("BNO085 Found");
  for (int n = 0; n < bno.prodIds.numEntries; n++) {
    Serial.print("Part ");
    Serial.print(bno.prodIds.entry[n].swPartNumber);
    Serial.print(": Version :");
    Serial.print(bno.prodIds.entry[n].swVersionMajor);
    Serial.print(".");
    Serial.print(bno.prodIds.entry[n].swVersionMinor);
    Serial.print(".");
    Serial.print(bno.prodIds.entry[n].swVersionPatch);
    Serial.print(" Build ");
    Serial.println(bno.prodIds.entry[n].swBuildNumber);
  }
  Serial.println("Enabling sensors");
  if (!bno.enableReport(SH2_ACCELEROMETER)) {
    Serial.println("Could not enable accelerometer");
  }
  if (!bno.enableReport(SH2_GYROSCOPE_CALIBRATED)) {
    Serial.println("Could not enable gyroscope");
  }
  if (!bno.enableReport(SH2_MAGNETIC_FIELD_CALIBRATED)) {
    Serial.println("Could not enable magnetic field calibrated");
  }
  
}

void headerFile() {
  f = LittleFS.open("data.csv", "a");
  f.printf("millis,a_x,a_y,a_z,g_x,g_y,g_z,m_x,m_y,m_z\n");
  f.close();
}
void plug(uint32_t i){
  (void) i;
  printable = false;
}
void unplug(uint32_t i){
  (void) i;
  printable = true;
}
void deleteFile(uint32_t i){
  (void) i;
  LittleFS.remove("data.csv");
  headerFile();
}



void setupFile(){
  LittleFS.begin();

  singleFileDrive.onPlug(plug);
  singleFileDrive.onUnplug(unplug);
  singleFileDrive.onDelete(deleteFile);
  singleFileDrive.begin("data.csv", "flight.csv");

  headerFile();
}




void setupRadio(){
  pinMode(RFM95_RST, OUTPUT);
  digitalWrite(RFM95_RST, HIGH);

  Serial.begin(115200);
  while (!Serial) delay(1);
  delay(100);

  Serial.println("Feather LoRa TX Test!");
  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);
  // 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(20, false);
}






void setup() {
  pinMode(4, INPUT);
  Serial.begin();
  for(int i = 0; i < TIMEOUT; i+=10){
    if(Serial){
      Serial.println("Connected to PC, enabling debug mode");
      debug = true;
      break;
    }
    delay(10);
  }
  setupBNO();
  setupFile();
  setupRadio();


  delay(100);
}

int buttonState = LOW;
void loop() {
  // GET DATA




  /*
  if(debug){
    if(digitalRead(4) != buttonState){
      if(buttonState == HIGH){
        buttonState = LOW;
        printable = !printable;
        Serial.println(printable?"Enabled flash storage emulation":"Disabled flash storage emulation");
      }
      else{
        buttonState = HIGH;
      }
    }
  }
  if (! bno.getSensorEvent(&sensorValue)) {
    return;
  }
  if(printable){
    
    if (f) {
      //noInterrupts();
      Serial.println("writing");
      f.printf("%lu,%f,%f,%f,%f,%f,%f,%f,%f,%f\n", millis(), 
                        sensorValue.un.accelerometer.x, sensorValue.un.accelerometer.y, sensorValue.un.accelerometer.z,
                        sensorValue.un.gyroscope.x, sensorValue.un.gyroscope.y, sensorValue.un.gyroscope.z,
                        sensorValue.un.magneticField.x, sensorValue.un.magneticField.y, sensorValue.un.magneticField.z);
      
      Serial.println("write");
      //interrupts();
    }else{
      f = LittleFS.open("data.csv", "a");
    }
  }else{
    if(f){
      f.close();
    }
  }
  Serial.print(".");
  
  */






  Serial.println("Transmitting..."); // Send a message 

  char radiopacket[20] = "Hello World #      ";
  
  Serial.println("Sending...");
  delay(10);
  rf95.send((uint8_t *)(&sensorValue.un.gyroscope.x), 4);

  Serial.println("Waiting for packet to complete...");
  delay(10);
  rf95.waitPacketSent();
  /*
  // Now wait for a reply
  uint8_t buf[RH_RF95_MAX_MESSAGE_LEN];
  uint8_t len = sizeof(buf);

  Serial.println("Waiting for reply...");
  if (rf95.waitAvailableTimeout(1000)) {
    // Should be a reply message for us now
    if (rf95.recv(buf, &len)) {
      Serial.print("Got reply: ");
      Serial.println((char*)buf);
      Serial.print("RSSI: ");
      Serial.println(rf95.lastRssi(), DEC);
    } else {
      Serial.println("Receive failed");
    }
  } else {
    Serial.println("No reply, is there a listener around?");
  }
  delay(100);
  */
}

Those are indeed unusable RSSI values.

If you have even once tried to transmit without an antenna attached, or with a poor antenna connection (bad solder joint or connector), it seems likely that the RF power amplifier in the module has been damaged.

Unplugging the antenna from the transmitter changes the signal from -110 to -132, while unplugging it from the ground station does not change it. Interestingly, the RSSI value changes when I touch the wire/antenna to the ground pad, not the antenna pad. I did check and I haven't bridged the two connections. I believe this suggests that the ground station module is damaged in some way.

Hi, @elongationyeet

What are you using as a power supply to the Lora units.
Have you measured the supply voltage to them when transmitting.

Can you post some images of your project?
So we can see your component layout.

Can you please post a copy of your circuit, a picture of a hand drawn circuit in jpg, png?
Hand drawn and photographed is perfectly acceptable.
Please include ALL hardware, power supplies, component names and pin labels.

Thanks.. Tom... :smiley: :+1: :coffee: :australia:

This could make sense. The module that I think is faulty I used several years ago, probably for hours without an antenna plugged in. I didn't even know that these modules could be damaged when using it without an antenna


This is the ground station, the transmitter is just the adafruit featherwing wired directly into the rp2040 feather. The janky antenna connector was a last ditch effort to try and improve the signal at all, originally it had just a wire.

possibly it is the photograph but is the black wire connected to GND -it looks like it is connected to GP28

I was able to get a new radio board. If I transmit from one of the old boards, and receive from the new one, the RSSI is about -48. The other way around the RSSI is about -90. Would this suggest that the receiver on the old boards have been damaged?

That is usually all you need for a LoRa transceiver, for up to 100 km or so, line of sight (7.8 cm for 915 MHz).

The antenna connector is certainly a hack job, and no antenna is shown. From the photo it is not clear whether the connector is correctly wired.

Normally that is the case.

However most LoRa modules have an RF switch device, between the SX127X itself
and the antenna to swap the antenna connection between TX and RX.

Not sure myself how immune to damage the RF switch device is if used in TX mode with no antenna.

I have used LoRa a fair bit in the last 10 years and seen quite a few module failures due to cock ups by myself, as in no antenna connected. But I do recall one module that went very low RSSI .....

This would mean that the brand new board, that hasn't been run without the antenna, is the only one that is damaged, while the boards that have been transmitting without the antennas are fine.