LoRa Pains.... RadioHead Library

Hey guys,

So I have the fallowing two set ups-

Arduino MEGA with Adafruit RFM95 915Mhz LoRa Radio
LoRa INT → 3
LoRa CS → 53
LoRa RST → 2
LoRa SPI pins on the MEGA’s 50,51,52, respectively

Adafruit M0 w/ WiFi and RFM95 915Mhz LoRa Radio Wing
A → RST
B → CS
D → IRQ
Adafruit LoRa Radio FeatherWing - RFM95W 900 MHz [RadioFruit] : ID 3231 : $19.95 : Adafruit Industries, Unique & fun DIY electronics and kits - LoRa radio

Computer running Ubuntu, Arduino 1.8.5 with RadioHead 1.62

So my issue is I run the examples from the library, and I set 53 as a output on the MEGA and set the CS as well as reset pins on both. They just don’t work, all that gets sent to me over serial is it telling me it was able to set the frequency. Code below

MEGA-

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

#define CLIENT_ADDRESS 1
#define SERVER_ADDRESS 2
#define RF95_FREQ 915.0

// Singleton instance of the radio driver
RH_RF95 driver(53, 3);
//RH_RF95 rf95(53, 3); // Rocket Scream Mini Ultra Pro with the RFM95W

// Class to manage message delivery and receipt, using the driver declared above
RHReliableDatagram manager(driver, CLIENT_ADDRESS);

// Need this on Arduino Zero with SerialUSB port (eg RocketScream Mini Ultra Pro)
//#define Serial SerialUSB

void setup() 
{
  // Rocket Scream Mini Ultra Pro with the RFM95W only:
  // Ensure serial flash is not interfering with radio communication on SPI bus
  pinMode(53, OUTPUT);
  pinMode(2, OUTPUT);
  
  digitalWrite(2, HIGH);
  

  Serial.begin(9600);
  delay(100);
  //while (!Serial) ; // Wait for serial port to be available
  digitalWrite(2, LOW);
  delay(10);
  digitalWrite(2, HIGH);
  delay(10);
  if (!manager.init())
    Serial.println("init failed");
  // 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:
  if (!driver.setFrequency(RF95_FREQ)) {
    Serial.println("setFrequency failed");
    while (1);
  }
  Serial.print("Set Freq to: "); Serial.println(RF95_FREQ);
  driver.setTxPower(5, false);
  
}

uint8_t data[] = "Hello World!";
// Dont put this on the stack:
uint8_t buf[RH_RF95_MAX_MESSAGE_LEN];

void loop()
{
  Serial.println("Sending to rf95_reliable_datagram_server");
    
  // Send a message to manager_server
  if (manager.sendtoWait(data, sizeof(data), SERVER_ADDRESS))
  {
    // Now wait for a reply from the server
    uint8_t len = sizeof(buf);
    uint8_t from;   
    if (manager.recvfromAckTimeout(buf, &len, 2000, &from))
    {
      Serial.print("got reply from : 0x");
      Serial.print(from, HEX);
      Serial.print(": ");
      Serial.println((char*)buf);
    }
    else
    {
      Serial.println("No reply, is rf95_reliable_datagram_server running?");
    }
  }
  else
    Serial.println("sendtoWait failed");
  delay(500);
}

Feather-

// rf95_reliable_datagram_server.pde
// -*- mode: C++ -*-
// Example sketch showing how to create a simple addressed, reliable messaging server
// with the RHReliableDatagram class, using the RH_RF95 driver to control a RF95 radio.
// It is designed to work with the other example rf95_reliable_datagram_client
// Tested with Anarduino MiniWirelessLoRa, Rocket Scream Mini Ultra Pro with the RFM95W 

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

#define CLIENT_ADDRESS 1
#define SERVER_ADDRESS 2

// Singleton instance of the radio driver
//RH_RF95 driver;
RH_RF95 driver(10, 6); // Rocket Scream Mini Ultra Pro with the RFM95W

// Class to manage message delivery and receipt, using the driver declared above
RHReliableDatagram manager(driver, SERVER_ADDRESS);

// Need this on Arduino Zero with SerialUSB port (eg RocketScream Mini Ultra Pro)
//#define Serial SerialUSB

void setup() 
{
  // Rocket Scream Mini Ultra Pro with the RFM95W only:
  // Ensure serial flash is not interfering with radio communication on SPI bus
  pinMode(2, OUTPUT);
  digitalWrite(2, HIGH);

  Serial.begin(9600);
  delay(100);

  Serial.println("Feather LoRa RX Test!");
  
  // manual reset
  digitalWrite(2, LOW);
  delay(10);
  digitalWrite(2, HIGH);
  delay(10);
  while (!Serial) ; // Wait for serial port to be available
  if (!manager.init())
    Serial.println("init failed");
  // Defaults after init are 434.0MHz, 13dBm, Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on
  if (!driver.setFrequency(915.0)) {
    Serial.println("setFrequency failed");
    while (1);
  }
  Serial.print("Set Freq to: "); Serial.println("915Mhz");
  driver.setTxPower(5, false);
}

uint8_t data[] = "And hello back to you";
// Dont put this on the stack:
uint8_t buf[RH_RF95_MAX_MESSAGE_LEN];

void loop()
{
  if (manager.available())
  {
    Serial.println("Manager available");
    // Wait for a message addressed to us from the client
    uint8_t len = sizeof(buf);
    uint8_t from;
    if (manager.recvfromAck(buf, &len, &from))
    {
      Serial.print("got request from : 0x");
      Serial.print(from, HEX);
      Serial.print(": ");
      Serial.println((char*)buf);

      // Send a reply back to the originator client
      if (!manager.sendtoWait(data, sizeof(data), from))
        Serial.println("sendtoWait failed");
    }
  }
}

It’s extremely frustrating and using the rf95_client and rf95_server modified similarly doesn’t work either. Is there any error someone sees or anyone else have a solution?

Thanks

I’d start with the TX program. You’re not seeing any of the error messages in the loop() function? If not, it would seem the code isn’t returning from one of the calls to manager methods. Perhaps add some debug prints to find out which call is failing.

It's hung trying to see if manager is available

Annakin4:
It's hung trying to see if manager is available

The call to manager.available() is in the RX code. As I mentioned, the TX code is the logical place to start. No use debugging the RX until you're sure the TX is sending something.

Another thought:
On the Adafruit M0 both the WiFi module and the RF95 will be using SPI. You should make sure that both RadioHead and the WiFi library disable their respective CS pins when not talking to their module. Folks at the Adafruit forums may be able to help you with that.

Assuming WiFi and RF95 do play well together on the SPI, you might try reversing the roles of your boards. Load the M0 with the Client code and see if you can at least confirm that it's sending packets.

Hi,

I am woring with a Mini Ultra Pro V1 card, my main porpouse is to send data using a sensor DHT22 to TTN cloud. So far I am able to send “Hello, World” using the code below , however I want to send this message repeataly, the only way I can send it again to TTN and see the payload for “Hello, world” is performing a reset on the card, . The code is as follows:

#include <lmic.h>
#include <hal/hal.h>
#include <SPI.h>
#define CFG_eu868 1
#define CFG_sx1276_radio 1
const int relayPin = 2;
unsigned int relayState = LOW;
long offTime = 11000;
long onTime = 1000;
unsigned long previousMillis=0;

// LoRaWAN NwkSKey, network session key
// This is the default Semtech key, which is used by the early prototype TTN
// network.
static const PROGMEM u1_t NWKSKEY[16] = { 0x3D, 0xD5, 0x44, 0x2D, 0xD7, 0xD6, 0x67, 0x2F, 0x6E, 0x71, 0x38, 0x79, 0x55, 0xC1, 0x62, 0xF5 };

// LoRaWAN AppSKey, application session key
// This is the default Semtech key, which is used by the early prototype TTN
// network.
static const u1_t PROGMEM APPSKEY[16] = { 0xF3, 0x5E, 0xB6, 0x1D, 0x4F, 0x81, 0x8D, 0xC4, 0xD8, 0xFF, 0x9F, 0xE2, 0xA8, 0xB0, 0x39, 0x4D };

// LoRaWAN end-device address (DevAddr)
static const u4_t DEVADDR = 0x26011BA5 ; // ← Change this address for every node!

// These callbacks are only used in over-the-air activation, so they are
// left empty here (we cannot leave them out completely unless
// DISABLE_JOIN is set in config.h, otherwise the linker will complain).
void os_getArtEui (u1_t* buf) { }
void os_getDevEui (u1_t* buf) { }
void os_getDevKey (u1_t* buf) { }

static uint8_t mydata = “Hello, world!”;
static osjob_t sendjob;

// Schedule TX every this many seconds (might become longer due to duty
// cycle limitations).
const unsigned TX_INTERVAL = 10;

// Pin mapping
const lmic_pinmap lmic_pins = {
.nss = 5,
.rxtx = LMIC_UNUSED_PIN,
.rst = 3,
.dio = {2, 6, LMIC_UNUSED_PIN},
};

void onEvent (ev_t ev) {
Serial.print(os_getTime());
Serial.print(": ");
switch(ev) {
case EV_SCAN_TIMEOUT:
Serial.println(F(“EV_SCAN_TIMEOUT”));
break;
case EV_BEACON_FOUND:
Serial.println(F(“EV_BEACON_FOUND”));
break;
case EV_BEACON_MISSED:
Serial.println(F(“EV_BEACON_MISSED”));
break;
case EV_BEACON_TRACKED:
Serial.println(F(“EV_BEACON_TRACKED”));
break;
case EV_JOINING:
Serial.println(F(“EV_JOINING”));
break;
case EV_JOINED:
Serial.println(F(“EV_JOINED”));
break;
case EV_RFU1:
Serial.println(F(“EV_RFU1”));
break;
case EV_JOIN_FAILED:
Serial.println(F(“EV_JOIN_FAILED”));
break;
case EV_REJOIN_FAILED:
Serial.println(F(“EV_REJOIN_FAILED”));
break;
case EV_TXCOMPLETE:
Serial.println(F(“EV_TXCOMPLETE (includes waiting for RX windows)”));
if (LMIC.txrxFlags & TXRX_ACK)
Serial.println(F(“Received ack”));
if (LMIC.dataLen) {
Serial.println(F(“Received “));
Serial.println(LMIC.dataLen);
Serial.println(F(” bytes of payload”));
}
// Schedule next transmission
os_setTimedCallback(&sendjob, os_getTime()+sec2osticks(TX_INTERVAL), do_send);
break;
case EV_LOST_TSYNC:
Serial.println(F(“EV_LOST_TSYNC”));
break;
case EV_RESET:
Serial.println(F(“EV_RESET”));
break;
case EV_RXCOMPLETE:
// data received in ping slot
Serial.println(F(“EV_RXCOMPLETE”));
break;
case EV_LINK_DEAD:
Serial.println(F(“EV_LINK_DEAD”));
break;
case EV_LINK_ALIVE:
Serial.println(F(“EV_LINK_ALIVE”));
break;
default:
Serial.println(F(“Unknown event”));
break;
}
}

void do_send(osjob_t* j){
// Check if there is not a current TX/RX job running
if (LMIC.opmode & OP_TXRXPEND) {
Serial.println(F(“OP_TXRXPEND, not sending”));
} else {
// Prepare upstream data transmission at the next possible time.
LMIC_setTxData2(1, mydata, sizeof(mydata)-1, 0);
Serial.println(F(“Packet queued”));
}
// Next TX is scheduled after TX_COMPLETE event.
}

void setup() {
Serial.begin(115200);
Serial.println(F(“Starting”));

#ifdef VCC_ENABLE
// For Pinoccio Scout boards
pinMode(VCC_ENABLE, OUTPUT);
digitalWrite(VCC_ENABLE, HIGH);
delay(1000);
pinMode(relayPin, OUTPUT);
relayState = LOW;
digitalWrite(relayPin, LOW);
#endif

// LMIC init
os_init();
// Reset the MAC state. Session and pending data transfers will be discarded.
LMIC_reset();

// Set static session parameters. Instead of dynamically establishing a session
// by joining the network, precomputed session parameters are be provided.
#ifdef PROGMEM
// On AVR, these values are stored in flash and only copied to RAM
// once. Copy them to a temporary buffer here, LMIC_setSession will
// copy them into a buffer of its own again.
uint8_t appskey[sizeof(APPSKEY)];
uint8_t nwkskey[sizeof(NWKSKEY)];
memcpy_P(appskey, APPSKEY, sizeof(APPSKEY));
memcpy_P(nwkskey, NWKSKEY, sizeof(NWKSKEY));
LMIC_setSession (0x1, DEVADDR, nwkskey, appskey);
#else
// If not running an AVR with PROGMEM, just use the arrays directly
LMIC_setSession (0x1, DEVADDR, NWKSKEY, APPSKEY);
#endif

#if defined(CFG_eu868)
// Set up the channels used by the Things Network, which corresponds
// to the defaults of most gateways. Without this, only three base
// channels from the LoRaWAN specification are used, which certainly
// works, so it is good for debugging, but can overload those
// frequencies, so be sure to configure the full frequency range of
// your network here (unless your network autoconfigures them).
// Setting up channels should happen after LMIC_setSession, as that
// configures the minimal channel set.
// NA-US channels 0-71 are configured automatically
LMIC_setupChannel(0, 868100000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(1, 868300000, DR_RANGE_MAP(DR_SF12, DR_SF7B), BAND_CENTI); // g-band
LMIC_setupChannel(2, 868500000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(3, 867100000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(4, 867300000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(5, 867500000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(6, 867700000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(7, 867900000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(8, 868800000, DR_RANGE_MAP(DR_FSK, DR_FSK), BAND_MILLI); // g2-band
// TTN defines an additional channel at 869.525Mhz using SF9 for class B
// devices’ ping slots. LMIC does not have an easy way to define set this
// frequency and support for class B is spotty and untested, so this
// frequency is not configured here.
#elif defined(CFG_us915)
// NA-US channels 0-71 are configured automatically
// but only one group of 8 should (a subband) should be active
// TTN recommends the second sub band, 1 in a zero based count.
// gateway-conf/US-global_conf.json at master · TheThingsNetwork/gateway-conf · GitHub
LMIC_selectSubBand(1);
#endif

// Disable link check validation
LMIC_setLinkCheckMode(0);

// TTN uses SF9 for its RX2 window.
LMIC.dn2Dr = DR_SF9;

// Set data rate and transmit power for uplink (note: txpow seems to be ignored by the library)
LMIC_setDrTxpow(DR_SF7,14);

// Start job
do_send(&sendjob);
}

void loop() {
// put your main code here, to run repeatedly:

os_runloop_once();

}

Can you please help me to verify if I can make some changes to send the message repeatedly instead of performing a reset everytime I send a newone?

Thanks in advance for your support.

Regards

Its not normally a good idea to tag onto the end of an old and un-related thread.

This thread was about the RadioHead library, are you using that library ?