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