Photon LoRaWAN node?


#2

Yes I have done this already. I’ll share my code when I get a chance. I used the RFM95w modules.


#3

@RWB: interested by a tutorial on LoRaWan and particle if you get around it !
Cheers


#4

Here is my code for connecting an RFM95w Radio module to the Photon and then running the Radio Head Reliable Datagram Server and Client code on 2 separate Photon + RFM95w devices.

You can download the library and examples here: https://www.dropbox.com/sh/n3nrrkdkdlzp44o/AADgPVpiVZbS00wBB9LYv4hLa?dl=0

Then just open that folder using Particle DEV as shown below:

The Photon to RFM95W chip pin connection diagram is below:

I just used one of these Adafruit breakouts:

Amazon and Digikey have some in stock, Adafruit is currently sold out.

In good conditions, you can get 1-mile range with simple wire antennas in a suburban environment.

The other thread were we figured out how to make the Radio Head library work on the Photon is here: Particle Photon / Electron + RFN95W Long Range Radio


RH_RF95 cannot compile
How to communicate between Electrons wirelessly using either Bluetooth or nRF24L01+?
LoRa with Electron v Arduino Mini
How to make RFM69 work on Photon? [SOLVED - new library RFM69-Particle]
#5

@RWB What I have find out that the codes are for point-to-point lora communication kind of client-server communication. By “Photon LoRaWAN node” I meant which can communicate with lorawan server (udp) packet e.g thethingsnetwork lorawan server. I am trying with the same as arduino code and IBM LMIC library code. Btw. not any luck yet. If you have any idea or point me to the right direction. Thank you :slight_smile:


#6

Hello,

Thank you for sharing your code. I’m trying something similar using the same Breakout board, and I get an error about a missing stm32f4xx.h library. Was this something you ran into?


#7

@dpasiliao Yea, Particle changed their library structure and it would not compile for me now also.

I make a bunch of changes to the #include < File > and changed them to #include “file” to indicate that the files were outside of the .ino file directory.

I removed the STM32 folder since it was not needed anyway.

The modified library is here, it compiles just fine now:

Let me know how it goes for you :slight_smile:


RadioHead library error (stm32f4xx.h not found)
#8

It compiles perfectly. Thank you!

Would you happen to know how to specify which pins I’ve used for RST, G0, and CS? I’m going by Adafruit’s guide on their LoRA breakout and their sample code has each pin identified. Is this necessary?

Also, I’m using an electron for this. It still successfully compiles but I’m still troubleshooting to get it to communicate.


#9

@dpasiliao

Great!

Here are the pin connections between the Photon/Electron and RFM95/96 modules

If you hook up the same as shown above then the library code should work since I have already made the changes needed for it to work with the Photon, the Electron should be the exact same settings.

Let me know how it goes.

I have this working on a Photon but never tried it on an Electron but there is no reason it shouldn’t work with the Electron.


#10

What do the NSS and DIO0 refer to? CS and G0?


#11

@dpasiliao

What RFM95 board do you have? The Adafruit breakout?

Here is the schematic for the Adafruit breakout with the RFM95w radio.

NSS is CS it looks like and that connects to the A2 on the Photon.

DIO0 is the Interrupt line coming from the RFM95w radio chip and that connects to D2 on the Photon.


#12

I’m using the Adafruit breakout. I’ve now switched to a Photon to test it out, and it won’t seem to enter the if statement in the loop so I’m thinking it could be a problem with the transmitter. I’m using a Feather with LoRa as the transmitter and the Photon as the receiver.


#13

Try both example codes on your Photon setup.


#14

Follow this post for both units Particle Photon / Electron + RFN95W Long Range Radio


#15

I get a lot of “sendToWait failed”.

Here’s the code I have on the Photon as a client:

SYSTEM_MODE(SEMI_AUTOMATIC);

#define CLIENT_ADDRESS 1
#define SERVER_ADDRESS 2

const int ledPin = D7;     // D7 has an LED

// Singleton instance of the radio driver
RH_RF95 driver (A2, D2);  //(A2,D2)-->you don't nee set this
//RH_RF95 rf95(5, 2); // 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()
{
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW);


  Serial.begin(9600);

  if (!manager.init())
  Serial.println("init failed");
  driver.setTxPower(23, false);
  driver.setFrequency(915.0);  // hay que setear frecuencia para los rfm96 915
  delay(5000);
  Serial.println("..this is the Photon as Client Radio");
}

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

uint32_t packetnum = 0;  // packet counter, we increment per xmission

void loop()
{

  Serial.println("Sending to Server Base Station");
  // Send a message to manager_server basestation.

  char radiopacket[20] = "Hello World #      ";
  itoa(packetnum++, radiopacket+13, 10);
  Serial.print("Transmitting > "); Serial.println(radiopacket);
  radiopacket[19] = 0;
  Serial.println("");

  if (manager.sendtoWait((uint8_t *)radiopacket, sizeof(radiopacket), SERVER_ADDRESS))
  {
    // Now wait for a reply from the server base station.
    uint8_t len = sizeof(buf);
    uint8_t from;

    Serial.println("Waiting for reply..."); delay(10);

    if (manager.recvfromAckTimeout(buf, &len, 2000, &from))
    {
      //Flash D7 LED on Photon if Received Reply
      digitalWrite(ledPin, HIGH);
      delay(500);
      digitalWrite(ledPin, LOW);

      Serial.print("Got reply from Server Base Station 0x");
      Serial.print(from, HEX);
      Serial.print(": ");
      Serial.println((char*)buf);
      Serial.print("RSSI: ");
      Serial.println(driver.lastRssi(), DEC);

      Serial.println();
      Serial.println();

    }
    else
    {

      Serial.println("No reply from Server Base Station?");

      //Flash D7 LED on Photon if No Reply From Server Base Station.
      digitalWrite(ledPin, HIGH);
      delay(200);
      digitalWrite(ledPin, LOW);
      delay(200);
      digitalWrite(ledPin, HIGH);
      delay(200);
      digitalWrite(ledPin, LOW);
    }
  }
  else{
    Serial.println("sendtoWait failed");
    digitalWrite(ledPin, HIGH); //Flash D7 LED on Photon if SendtoWait Failed
    delay(150);
    digitalWrite(ledPin, LOW);
    delay(150);
    digitalWrite(ledPin, HIGH);
    delay(150);
    digitalWrite(ledPin, LOW);
    delay(150);
    digitalWrite(ledPin, HIGH);
    delay(150);
    digitalWrite(ledPin, LOW);
    delay(150);
    digitalWrite(ledPin, HIGH);
    delay(150);
    digitalWrite(ledPin, LOW);
    }

  delay(5000);
}

and the code I have on the Feather as a server:

#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(8, 7);
//RH_RF95 driver(5, 2); // 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);

void setup() 
{

  Serial.begin(9600);
  while (!Serial) ; // Wait for serial port to be available
  if (!manager.init())
    Serial.println("init failed");
  
  driver.setTxPower(23, false);
  driver.setFrequency(915.0);
}

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())
  {
    // 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");
    }
  }
}

Am I missing something?


#16

The code I’m running on the Adafruit Feather is different than yours.

Mine is below:

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

/* for feather32u4 */
#define RFM95_CS 8
#define RFM95_RST 4
#define RFM95_INT 7

#define CLIENT_ADDRESS 1
#define SERVER_ADDRESS 2

// Singleton instance of the radio driver
RH_RF95 rf95(RFM95_CS, RFM95_INT);
//RH_RF95 driver(5, 2); // Rocket Scream Mini Ultra Pro with the RFM95W

#define RF95_FREQ 915.0

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

// Blinky on receipt
#define LED 13

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

  Serial.begin(9600);
  delay(100);
  //while (!Serial) ; // Wait for serial port to be available

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

  if (!manager.init())
    Serial.println("init failed"); 
   rf95.setTxPower(10, false);
   rf95.setFrequency(915.0);
  Serial.println("..this is the Adafuit Feather LoRa as server +RFM95 @915mhz");
  
  // 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:
   //driver.setTxPower(23, false);
  
  // You can optionally require this module to wait until Channel Activity
  // Detection shows no activity on the channel before transmitting by setting
  // the CAD timeout to non-zero:
  // driver.setCADTimeout(10000);
}

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())
  {
    // 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);
      Serial.print("RSSI: ");
      Serial.println(rf95.lastRssi(), DEC);
      Serial.println();
      digitalWrite(LED, HIGH); //Flash LED 2 times to indicate received message. 
      delay(250);
      digitalWrite(LED, LOW);
      delay(250);
      digitalWrite(LED, HIGH);
      delay(250);
      digitalWrite(LED, LOW);
      delay(250);
      
      // Send a reply back to the originator client
      if (!manager.sendtoWait(data, sizeof(data), from))
        Serial.println("sendtoWait failed");
        
        
    }
  }
}

The next important thing that you need to change is the spreading factor code on the Adafruit library in these files on the lines mentioned below:

Have a look at RH_RF95.cpp line 120-136 and RH_RF95.h line 579-597.

In the RH_RF95.cpp file line 120-136 in the Adafruit library make sure it matches what I have in the Photon library your using:

  // No Sync Words in LORA mode.

  // setModemConfig(Bw500Cr45Sf128);   // 1: Bw = 500kHz,   Cr = 4/5, Sf7  = 128  chips/symbol,CRC on --> I gott a delay of: RSSI= 33, 105 ms sending this --> Hello World!!
  // setModemConfig(Bw125Cr45Sf128);   // 2: Bw = 125kHz,   Cr = 4/5, Sf7  = 128  chips/symbol,CRC on --> I gott a delay of: RSSI= 36, 230 ms sending this --> Hello World!!
   /// setModemConfig(Bw125Cr48Sf4096);  // 3; Bw = 125kHz,   Cr = 4/8, Sf12 = 4096 chips/symbol,CRC on Slow+long range --->>> delay I got of 2176ms (DO NOT WORK NOW) sending this --> Hello World!(1923m con el GPS tracker 5dbm) last used on 02/04/2017
  // setModemConfig(Bw31_25Cr48Sf512); // 4: Bw = 31.25kHz, Cr = 4/8, Sf9  = 512  chips/symbol,CRC on --> I gott a delay of: RSSI= 39, 2990 ms sending this --> Hello World!! (872m con el GPS tracker 5dbm)
  // setModemConfig(BW41_7Cr45Sf512);  // 5: Bw = 41.7kHz,  Cr = 4/5, Sf9  = 512  chips/symbol,CRC on --> I gott a delay of: RSSI= 39, 1816 ms sending this --> Hello World!!
  // setModemConfig(BW62_5Cr45Sf1024); // 6: Bw = 62.5kHz,  Cr = 4/5, Sf10 = 1024 chips/symbol,CRC on Slow+long range--->>>               delay I got of 1652ms ( NOW DO NOT WORK!!)sending this --> Hello World!
  // setModemConfig(BW62_5Cr45Sf512);  // 7: Bw = 62.5kHz,  Cr = 4/5, Sf9  = 512  chips/symbol,CRC on --> I gott a delay of: RSSI= 40, 1816 ms sending this --> Hello World!! (665m con el gps tracker 5dbm)
  // setModemConfig(BW256_7Cr45sf128); // 8: Bw = 256 kHz,  Cr = 4/5, Sf7  = 128  chips/symbol,CRC on --> I gott a delay of: RSSI= 35, 145 ms sending this --> Hello World!!
  // setModemConfig(BW125_7Cr45sf128); // 9: Bw = 125 kHz,  Cr = 4/5, Sf7  = 128  chips/symbol,CRC on --> I gott a delay of: RSSI= 39, 219 ms sending this --> Hello World!!
  // setModemConfig(BW62_57Cr45sf128); // 10: Bw = 62.5kHz, Cr = 4/5, Sf7  = 128  chips/symbol,CRC on --> I gott a delay of: RSSI= 36, 376 ms sending this --> Hello World!!
    setModemConfig(BW125CR46SF9);     // 11: BW = 125 Khz, Cr = 4/6, SF9  = 512  chips/symbol,CRC on --> I gott a delay of: RSSI= 36, 647 ms sending this --> Hello World!
  // setModemConfig(BW62_5CR45SF9);    // 12: Bw = 62.5khz, Cr = 4/5, Sf8  = 256  chips/symbol,CRC on --> I gott a delay of: RSSI= 36, 688 ms sending this --> Hello World!
  // setModemConfig(BW62_5CR46SF10);   // 13: Bw = 62.5khz, Cr = 4/6, Sf10 = 1024 chips/symbol,CRC on --> I gott a delay of: RSSI= 40, 2595 ms sending this --> Hello World!
  // setModemConfig(BW62_5CR45SF11);   // 14: Bw = 62.5khz, Cr = 4/5, Sf11 = 2048 chips/symbol,CRC on --> DO NOT WORK sending this --> Hello World!
  // setModemConfig(BW125CR45SF11);    // 15: Bw = 125 khz, Cr = 4/5, Sf11 = 2048 chips/symbol,CRC on--> DO NOT WORK sending this --> Hello World!
  // setModemConfig(BW125CR45SF10);    // 16: Bw = 125khz,  Cr = 4/5, Sf10 = 1024 chips/symbol,CRC on--> DO NOT WORK sending this --> Hello World!
  // setModemConfig(BW31_25CR45SF9);    // 17: Bw = 31.25khz, Cr = 4/5, Sf8  = 256 chips/symbol,CRC on--> I gott a delay of: RSSI= 39, 1313 ms sending this --> Hello World! (858m con el GPS tracker 5dbm)
   //setModemConfig(BW41_7CR45SF9);     // 18: Bw = 41.7khz,  Cr = 4/5, Sf8  = 256 chips/symbol, CRC on.

And in the RH_RF95.h line 579-597 in the Adafruit library make sure it matches what we are using in the Photon library below:

    typedef enum
    {
	 Bw125Cr45Sf128 = 0,	   ///1: Bw = 125 kHz,   Cr = 4/5, Sf  = 128chips/symbol, CRC on. Default medium range
	 Bw500Cr45Sf128,	       ///2: Bw = 500 kHz,   Cr = 4/5, Sf  = 128chips/symbol, CRC on. Fast+short range
	 Bw31_25Cr48Sf512,	       ///3: Bw = 31.25 kHz, Cr = 4/8, Sf  = 512chips/symbol, CRC on. Slow+long range
	 Bw125Cr48Sf4096,          ///4: Bw = 125 kHz,   Cr = 4/8, Sf  = 4096chips/symbol, CRC on. Slow+long range
	 BW41_7Cr45Sf512,          ///5: Bw = 41.7 kHz,  Cr = 4/5, Sf  = 512chips/symbol, CRC on
	 BW62_5Cr45Sf1024,         ///6: Bw = 62.5 kHz,  Cr = 4/5, Sf  = 1024 chips/symbol, CRC on
	 BW62_5Cr45Sf512,          ///7: Bw = 62.5 kHz,  Cr = 4/5, Sf  = 512 chips/symbol, CRC on
	 BW256_7Cr45sf128,         ///8: Bw = 256 kHz,   Cr = 4/5, Sf7 = 128chips/symbol, CRC on
	 BW125_7Cr45sf128,         ///9: Bw = 125 kHz,   Cr = 4/5, Sf7 = chips/symbol, CRC on
	 BW62_57Cr45sf128,         ///10: Bw = 62.5 kHz, Cr = 4/5, Sf7 = chips/symbol, CRC on
	 BW125CR46SF9,             ///11: Bw = 125 kHz,  Cr = 4/6, Sf9 = chips/symbol, CRC on
	 BW62_5CR45SF9,            ///12: Bw = 62.5 khz, Cr = 4/5, Sf8 = 256   chips/symbol, CRC on.
	 BW62_5CR46SF10,           ///13: Bw = 62.5 khz, Cr = 4/6, Sf10 = 1024 chips/symbol, CRC on.
	 BW62_5CR45SF11,           ///14: Bw = 62.5 khz, Cr = 4/5, Sf11 = 2048 chips/symbol, CRC on.
	 BW125CR45SF11,            ///15: Bw = 125 khz,  Cr = 4/5, Sf11 = 2048 chips/symbol, CRC on.
	 BW125CR45SF10,            ///16: Bw = 125 khz,  Cr = 4/5, Sf10 = 1024 chips/symbol, CRC on.
	 BW31_25CR45SF9,           ///17: Bw = 31.25khz, Cr = 4/5, Sf8  = 256  chips/symbol, CRC on.
	 BW41_7CR45SF9,            ///18: Bw = 41.7khz,  Cr = 4/5, Sf8  = 256  chips/symbol, CRC on
    } ModemConfigChoice;

They need to match what were using in the Photon Radio Head library to get longer range communication working with the Reliable Datagram library code.

It didn’t work for me until I change this.

I learned about it here:


#17

Did ya ever get this working?


#18

Sorry, I’ve been away. I’m going to try it out when I get back this week and let you know how it works out. Thanks for all the help!


#19

@RWB I’ve got myself 2 RFM95w transceivers along with 2 Photon Cores. I wanted to make something along the lines of a solar-powered remote client that would communicate with the server photon using LoRa. Went through a lot of forums, found your posts, tried out what you posted above and everything works perfectly. Thank you so much!


#20

Sweet! Glad I could help you out!

What kind of data are you sending? What’s the setup if you don’t mind talking about it?


#21

The client is in deep sleep most of the time, waking every 30 minutes to take measurements (temperature, humidity, ambient light, LPG, TVOCs), which it then sends to the sever. Since the data is just a bunch of numbers I think the radio transceiver should have no problem communicating it. I am managing power for the client with Photon Battery Shield, which is connected to a 400mAh LiPo and a 3.5W solar panel. So far power doesn’t seem to be an issue, although I will need to see if the sleep cycle has to be tweaked to accommodate the power the transceiver uses.

Server photon receives data and passes it onto some cloud service (haven’t decided which one). Recently I’ve been working with Ionic, so it could be interesting coming up with some mobile UI for displaying the data.

It is a work in progress, any thoughts are appreciated :slight_smile: