multiple node lora tutorial

Multiple LORA clients with a Server communication

In this tutorial, I will show you how I make communication between many LoRa clients to a LoRa server.

In the video, I try to just send data to the server and that’s doesn’t work as we expected. Too much data that didn’t send successfully. And they are not organized or sequenced as we want.

So in this tutorial, I try to send data from 4 clients to a LoRa server with request and answer concept. So the clients only send data when it’s requested. All data will only be sent when it’s requested. So here’s the server sketch :

/*Multiple LoRa Communication
  example code by miliohm.com */

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

RH_RF95 rf95;
int led = 13;
unsigned long int millisBefore;

int turn = 1;
boolean statusRepeater = 0;

void setup()
{
  pinMode(led, OUTPUT);
  Serial.begin(9600);
  while (!Serial) ; // Wait for serial port to be available
  if (!rf95.init())
    Serial.println("init failed");
  Serial.println("Starting...");
}

void loop()
{
  if (statusRepeater == 0) {
    if (millis() - millisBefore < 1000) { 
      if (turn == 1) {
        Serial.println("Send Request 1");
        SendRequest("C1"); 
        waitForAnswer();
        turn = 2;
      }
      waitForAnswer();
    } else if ((millis() - millisBefore > 1000) && (millis() - millisBefore < 2000)) { //jika waktu kurang dari 4 detik
      if (turn == 2) {
        Serial.println("Send Request 2");
        SendRequest("G2");
        waitForAnswer();
        turn = 3;
      }
    } else if (millis() - millisBefore > 6000) {
      if (turn == 3) {
        Serial.println("Send Request 3");
        SendRequest("G3");
        waitForAnswer();
        SendRequest("G1");
        waitForAnswer();
        millisBefore = millis();
        turn = 1;
      }
    }
  }
}

void waitForAnswer() { //fungsi tunggu jawaban dari node
  // Now wait for a reply
  uint8_t buf[RH_RF95_MAX_MESSAGE_LEN];
  uint8_t len = sizeof(buf);
  if (rf95.waitAvailableTimeout(500))
  {
    if (rf95.recv(buf, &len))
    {
      Serial.print("Received at Server: ");
      Serial.println((char*)buf);
      String dataTotal = (char*)buf;
      Serial.println(dataTotal);
    }
    else
    {
      Serial.println("recv failed");
    }
  }
}

void SendRequest(String request) { //fungsi untuk Send request dengan variable parameter request
  String dataTotal = request;
  int dataLength = dataTotal.length(); dataLength ++;
  uint8_t total[dataLength];
  dataTotal.toCharArray(total, dataLength);
  rf95.send(total, dataLength);
  rf95.waitPacketSent();
}

And here’s the client’s code,

First client :

/*Multiple LoRa Communication
  example code by miliohm.com */

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

RH_RF95 rf95;

void setup()
{
  Serial.begin(9600);
  while (!Serial) ; // Wait for serial port to be available
  if (!rf95.init())
    Serial.println("init failed");
  rf95.setFrequency(433.0);
}

void loop()
{
  uint8_t buf[RH_RF95_MAX_MESSAGE_LEN];
  uint8_t len = sizeof(buf);
  if (rf95.waitAvailableTimeout(3000))
  {
    // Should be a reply message for us now
    if (rf95.recv(buf, &len))
    {
      int dataLength;
      String Request = (char*)buf;
      Serial.println(Request);
      if (Request == "C1") {
        Serial.print("Client 1 Got Request, Answering Server...");
        String data = "Hello";
        uint8_t total[dataLength]; //variable for data to send
        data.toCharArray(total, dataLength); //change type data from string ke uint8_t
        Serial.println(data);
        rf95.send(total, dataLength); //send data
        rf95.waitPacketSent();
      }
    }
  }
  else
  {
    Serial.println("No reply, is rf95_server running?");
  }
  delay(400);
}

Second Client

/*Multiple LoRa Communication
  example code by miliohm.com */

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

RH_RF95 rf95;

void setup()
{
  Serial.begin(9600);
  while (!Serial) ; // Wait for serial port to be available
  if (!rf95.init())
    Serial.println("init failed");
  rf95.setFrequency(433.0);
}

void loop()
{
  uint8_t buf[RH_RF95_MAX_MESSAGE_LEN];
  uint8_t len = sizeof(buf);
  if (rf95.waitAvailableTimeout(3000))
  {
    // Should be a reply message for us now
    if (rf95.recv(buf, &len))
    {
      int dataLength;
      String Request = (char*)buf;
      if (Request == "C2") {
        Serial.print("Client 2 Got Request, Answering Server...");
        String data = "I'm Lora";
        int dataLength = data.length();dataLength++;
        uint8_t total[dataLength]; //variable for data to send
        data.toCharArray(total, dataLength); //change type data from string ke uint8_t
        Serial.println(data);
        rf95.send(total, dataLength); //send data
        rf95.waitPacketSent();
      }
    }
  }
  else
  {
    Serial.println("No reply, is rf95_server running?");
  }
  delay(400);
}

Third Client,

/*Multiple LoRa Communication
  example code by miliohm.com */

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

RH_RF95 rf95;

void setup()
{
  Serial.begin(9600);
  while (!Serial) ; // Wait for serial port to be available
  if (!rf95.init())
    Serial.println("init failed");
  rf95.setFrequency(433.0);
}

void loop()
{
  uint8_t buf[RH_RF95_MAX_MESSAGE_LEN];
  uint8_t len = sizeof(buf);
  if (rf95.waitAvailableTimeout(3000))
  {
    // Should be a reply message for us now
    if (rf95.recv(buf, &len))
    {
      int dataLength;
      String Request = (char*)buf;
      if (Request == "C3") {
        Serial.print("Client 3 Got Request, Answering Server...");
        String data = "Greeting";
        int dataLength = data.length(); dataLength++;
        uint8_t total[dataLength]; //variable for data to send
        data.toCharArray(total, dataLength); //change type data from string ke uint8_t
        Serial.println(data);
        rf95.send(total, dataLength); //send data
        rf95.waitPacketSent();
      }
    }
  }
  else
  {
    Serial.println("No reply, is rf95_server running?");
  }
  delay(400);
}

Fourth Client,

/*Multiple LoRa Communication
  example code by miliohm.com */

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

RH_RF95 rf95;

void setup()
{
  Serial.begin(9600);
  while (!Serial) ; // Wait for serial port to be available
  if (!rf95.init())
    Serial.println("init failed");
  rf95.setFrequency(433.0);
}

void loop()
{
  uint8_t buf[RH_RF95_MAX_MESSAGE_LEN];
  uint8_t len = sizeof(buf);
  if (rf95.waitAvailableTimeout(3000))
  {
    // Should be a reply message for us now
    if (rf95.recv(buf, &len))
    {
      int dataLength;
      String Request = (char*)buf;
      if (Request == "C4") {
        Serial.print("Client 4 Got Request, Answering Server...");
        String data = "From miliohm.com";
        int dataLength = data.length();dataLength++;
        uint8_t total[dataLength]; //variable for data to send
        data.toCharArray(total, dataLength); //change type data from string ke uint8_t
        Serial.println(data);
        rf95.send(total, dataLength); //send data
        rf95.waitPacketSent();
      }
    }
  }
  else
  {
    Serial.println("No reply, is rf95_server running?");
  }
  delay(400);
}