Sensor Data-LoRa

I would like to send DHT_11 sensor data to KPN network (since I have already got my ABP keys) throughout my SODAQ ONE board. So, I am actually got stuck coding the right function in order to send the sensor data.

My code is based on your “simple LoRa” sketch, besides, I added the DHT libraries as well as I reading sensor data functions located within the “void loop” function. I think I should change the last part:

   String packet = "SODAQ" ;
   sendPacket(packet);

May I get some help/solution, please?

This is my entire code:

#include "Arduino.h"
#include <Sodaq_RN2483.h>
#include <DHT.h>

#define DHTPIN 2
#define DHTTYPE DHT11 //Define the sensor we are using

DHT dht(DHTPIN,DHTTYPE);  //Initialize the device

#define debugSerial SERIAL_PORT_MONITOR

#if defined(ARDUINO_AVR_SODAQ_MBILI)
#define loraSerial Serial1
#define BEE_VCC 20

#elif defined(ARDUINO_SODAQ_AUTONOMO) || defined(ARDUINO_SODAQ_ONE) || defined(ARDUINO_SODAQ_ONE_BETA)
#define loraSerial Serial1

#elif defined(ARDUINO_SODAQ_EXPLORER)
#define loraSerial Serial2

#else
// please select a sodaq board
debugSerial.println("Please select a sodaq board!!");
#endif

// ABP
const uint8_t devAddr[4] = { 0x14, 0x20, 0x61, 0xCF };
const uint8_t appSKey[16] = { 0xf3, 0x09, 0x04, 0x16, 0x97, 0x30, 0x1e, 0x87, 0x22, 0x8e, 0x7c, 0xba, 0xb2, 0x0c, 0x36, 0xc8 };
const uint8_t nwkSKey[16] = { 0xf1, 0x73, 0xb9, 0xd3, 0xee, 0xc3, 0xf6, 0x47, 0x02, 0xef, 0xc5, 0x90, 0x0b, 0x5a, 0x26, 0xd3  };

/*// OTAA
uint8_t DevEUI[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
uint8_t AppEUI[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
uint8_t AppKey[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };*/

void setupLoRaABP(){  
  if (LoRaBee.initABP(loraSerial, devAddr, appSKey, nwkSKey, false))
  {
    debugSerial.println("Communication to LoRaBEE successful.");
  }
  else
  {
    debugSerial.println("Communication to LoRaBEE failed!");
  }
}

/*void setupLoRaOTAA(){
  if (LoRaBee.initOTA(loraSerial, DevEUI, AppEUI, AppKey, false))
  {
    debugSerial.println("Communication to LoRaBEE successful.");
  }
  else
  {
    debugSerial.println("OTAA Setup failed!");
  }
}*/

void setup() {
  //Power up the LoRaBEE
  #if defined(ARDUINO_AVR_SODAQ_MBILI) || defined(ARDUINO_SODAQ_AUTONOMO)
  pinMode(BEE_VCC, OUTPUT);
  digitalWrite(BEE_VCC, HIGH);
  #endif
  delay(3000);

  while ((!SerialUSB) && (millis() < 10000)){
    // Wait 10 seconds for the Serial Monitor
  }

  //Set baud rate
  debugSerial.begin(57600);
  loraSerial.begin(LoRaBee.getDefaultBaudRate());

  // Debug output from LoRaBee
  // LoRaBee.setDiag(debugSerial); // optional

  dht.begin(); // Set up the sensor (start the device)
  //connect to the LoRa Network
  setupLoRa();
}

void setupLoRa(){
  // ABP
  setupLoRaABP();
  // OTAA
//  setupLoRaOTAA();
  LoRaBee.setSpreadingFactor(9);
}

void sendPacket(String packet){
  switch (LoRaBee.send(1, (uint8_t*)packet.c_str(), packet.length()))
    {
    case NoError:
      debugSerial.println("Successful transmission.");
      break;
    case NoResponse:
      debugSerial.println("There was no response from the device.");
      setupLoRa();
      break;
    case Timeout:
      debugSerial.println("Connection timed-out. Check your serial connection to the device! Sleeping for 20sec.");
      delay(20000);
      break;
    case PayloadSizeError:
      debugSerial.println("The size of the payload is greater than allowed. Transmission failed!");
      break;
    case InternalError:
      debugSerial.println("Oh No! This shouldn't happen. Something is really wrong! Try restarting the device!\r\nThe network connection will reset.");
      setupLoRa();
      break;
    case Busy:
      debugSerial.println("The device is busy. Sleeping for 10 extra seconds.");
      delay(10000);
      break;
    case NetworkFatalError:
      debugSerial.println("There is a non-recoverable error with the network connection. You should re-connect.\r\nThe network connection will reset.");
      setupLoRa();
      break;
    case NotConnected:
      debugSerial.println("The device is not connected to the network. Please connect to the network before attempting to send data.\r\nThe network connection will reset.");
      setupLoRa();
      break;
    case NoAcknowledgment:
      debugSerial.println("There was no acknowledgment sent back!");
      // When you this message you are probaly out of range of the network.
      break;
    default:
      break;
    }
}

void loop() {

  //Sensor values
 float h = dht.readHumidity();
 float t = dht.readTemperature();

 //check if returns are valid, if they are NaN (not a number) then something went wrong
 if (isnan(t) || isnan(h))
 {
  SerialUSB.println("Failed to read from DHT");
 }
 else{
  SerialUSB.println("Humidity: ");
  SerialUSB.println(h);
  SerialUSB.println(" %\t");
  SerialUSB.println("Temperature: ");
  SerialUSB.println(t);
  SerialUSB.println(" %\t");
    }
  
 
  String packet = "SODAQ";
  sendPacket(packet);

  delay(5000);
}

Hi,

You can use:
String packet = String(t) + ", " + String(h);

You can also look at this example:
http://support.sodaq.com/sodaq-one/lorabee/

Regards,
Jan

Hi,

I think this is the format you did mean previously. Should I use data variable rather than “packet”?

  //Create a String type data record in csv format
  //TempSHT21, TempBMP, PressureBMP, HumiditySHT21
  String data = String(SHT2x.GetTemperature())  + ", ";
  data += String(bmp.readTemperature()) + ", ";
  data += String(bmp.readPressure() / 100)  + ", ";
  data += String(SHT2x.GetHumidity());
  debugSerial.println(data);

Is this format designed to include more than a value, is that right?

Thank you

It is working perfectly Jan. I can check the sensor data within Hookbin end-point. However, as I told you in the previous days, I would like to be able to see these data monitorised within a platform for instance “ThingSpeak”, but a ‘0’ value is received constantly. As you said (If I am not wrong), it happens because the code is sending HEX code rather than ASCII…? If so, how can I convert it?

#include "Arduino.h"
#include <Sodaq_RN2483.h>
#include "DHT.h"

#define DHTPIN 2 // Pin connect sensor

#define DHTTYPE DHT11 // Define sensor we are using

DHT dht(DHTPIN,DHTTYPE); // Initialize the device

#define debugSerial SERIAL_PORT_MONITOR

#if defined(ARDUINO_AVR_SODAQ_MBILI)
#define loraSerial Serial1
#define BEE_VCC 20

#elif defined(ARDUINO_SODAQ_AUTONOMO) || defined(ARDUINO_SODAQ_ONE) || defined(ARDUINO_SODAQ_ONE_BETA)
#define loraSerial Serial1

#elif defined(ARDUINO_SODAQ_EXPLORER)
#define loraSerial Serial2

#else
// please select a sodaq board
debugSerial.println("Please select a sodaq board!!");
#endif

// ABP
const uint8_t devAddr[4] = { };
const uint8_t appSKey[16] = {  };
const uint8_t nwkSKey[16] = {  };

// OTAA
uint8_t DevEUI[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
uint8_t AppEUI[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
uint8_t AppKey[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };

void setupLoRaABP(){  
  if (LoRaBee.initABP(loraSerial, devAddr, appSKey, nwkSKey, false))
  {
    debugSerial.println("Communication to LoRaBEE successful.");
  }
  else
  {
    debugSerial.println("Communication to LoRaBEE failed!");
  }
}

void setupLoRaOTAA(){
  if (LoRaBee.initOTA(loraSerial, DevEUI, AppEUI, AppKey, false))
  {
    debugSerial.println("Communication to LoRaBEE successful.");
  }
  else
  {
    debugSerial.println("OTAA Setup failed!");
  }
}

void setup() {
  //Power up the LoRaBEE
  #if defined(ARDUINO_AVR_SODAQ_MBILI) || defined(ARDUINO_SODAQ_AUTONOMO)
  pinMode(BEE_VCC, OUTPUT);
  digitalWrite(BEE_VCC, HIGH);
  #endif
  delay(3000);

  while ((!SerialUSB) && (millis() < 10000)){
    // Wait 10 seconds for the Serial Monitor
  }

  //Set baud rate
  debugSerial.begin(57600);
  loraSerial.begin(LoRaBee.getDefaultBaudRate());

  // Debug output from LoRaBee
  // LoRaBee.setDiag(debugSerial); // optional

  //connect to the LoRa Network
  setupLoRa();
}

void setupLoRa(){
  // ABP
  setupLoRaABP();
  // OTAA
 // setupLoRaOTAA();
  LoRaBee.setSpreadingFactor(9);

  dht.begin(); //start the device
}

void sendPacket(String packet){
  switch (LoRaBee.send(1, (uint8_t*)packet.c_str(), packet.length()))
    {
    case NoError:
      debugSerial.println("Successful transmission.");
      break;
    case NoResponse:
      debugSerial.println("There was no response from the device.");
      setupLoRa();
      break;
    case Timeout:
      debugSerial.println("Connection timed-out. Check your serial connection to the device! Sleeping for 20sec.");
      delay(20000);
      break;
    case PayloadSizeError:
      debugSerial.println("The size of the payload is greater than allowed. Transmission failed!");
      break;
    case InternalError:
      debugSerial.println("Oh No! This shouldn't happen. Something is really wrong! Try restarting the device!\r\nThe network connection will reset.");
      setupLoRa();
      break;
    case Busy:
      debugSerial.println("The device is busy. Sleeping for 10 extra seconds.");
      delay(10000);
      break;
    case NetworkFatalError:
      debugSerial.println("There is a non-recoverable error with the network connection. You should re-connect.\r\nThe network connection will reset.");
      setupLoRa();
      break;
    case NotConnected:
      debugSerial.println("The device is not connected to the network. Please connect to the network before attempting to send data.\r\nThe network connection will reset.");
      setupLoRa();
      break;
    case NoAcknowledgment:
      debugSerial.println("There was no acknowledgment sent back!");
      // When you this message you are probaly out of range of the network.
      break;
    default:
      break;
    }
}

void loop() {

  //HumidityDHT1, TempDHT11 
  String packet  = String(dht.readHumidity())  + ", ";
  packet += String(dht.readTemperature());
  debugSerial.println(packet);

  sendPacket(packet);

  delay(5000);
}

Many Thanks!

Hi,

KPN is posting an JSON or XML to the destination URL.
ThingSpeak is expecting an GET request.

I believe the only way to solve this it to have an server in the middle what will handle to incoming data from KPN, decode the HEX data and create a GET for ThingSpeak with the correct payload.

Regards,
Jan

All right. I have been discussing this with your colleague Gabriel these days…
Do you know which sort of servers could make the steps you indicate above?

Thanks

Another question is If what I want is write data into Thingspeak automatically, I mean not manually, then GET link should be the following one?
https://api.thingspeak.com/update?api_key=XXXXXXXXXXXXXXXX
(as the values would be coming from the sensor/LoRa automatically…?)

Rather than;

https://api.thingspeak.com/update?api_key=XXXXXXXXXXXXXXXX&field1=12&field2=43
(where the values are indicated ‘12’ and ‘43’…?)

I hope I have explained myself cleary…

Thanks

Hi,

Any server with a valid SSL certificate. (KPN only sends data when this is valid)
You can use any language the server can handle, for you maybe the easiest will be php.

Maybe your office can help you to write an script.

Regards,
Jan

I have found Corlysis server:

https://corlysis.com/

Corlysis uses InfluxDB for data storing database, so I have to upload my data to InfluxDB database (I supose KPN might send data as well) and then I would monitorise it into Grafana, which is a tool for visualization. So, maybe I wouldn’t need ThingSpeak.

Regarding the ‘Getting Started’ tutorial they provide, I should download a script library from Github
https://www.youtube.com/watch?v=8hdGZv1T_gg
However, as you mentioned before, I don’t know which steps should I take with the scripts…
May I get some idea, please?
Thanks

I have been told that InfluxDB is already installed once you create a server into Corlysis…

I was wondering whether another point to keep in mind is the fact that I don’t use a Gateway? I am using my Sodaq ONE board to KPN with no Gateway (KPN is the gateway) Does not it affect?