[Solved] Transmitting sensor data with lora shield

Hello, everyone
I am developing a device transmits bme280 (temperature, humidity, pressure sensor)'s data to another arduino using rfm95 lora shield. I am using radiohead library and here is my transmitter code. This code transmits temperature data.

#include <SPI.h>
#include <RH_RF95.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#define SEALEVELPRESSURE_HPA (1013.25)
Adafruit_BME280 bme;

#define RFM95_CS 10
#define RFM95_RST 9
#define RFM95_INT 2

// 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(RFM95_RST, OUTPUT);
  digitalWrite(RFM95_RST, HIGH);

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

  Serial.println("Arduino LoRa TX Test!");

  // manual reset
  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);
  
  // 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(23, false);
  if (!bme.begin(0x76)) {
		Serial.println("Could not find a valid BME280 sensor, check wiring!");
		while (1);
	}
}

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

void loop()
{
  float t = bme.readTemperature();
  String data = String(t);
  int dataLength = data.length(); dataLength++;
  uint8_t total[dataLength];
  Serial.println(data);
  rf95.send(total, dataLength);
  rf95.waitPacketSent();
  delay(1000);
}

and this code is for receiving

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

#define RFM95_CS 10
#define RFM95_RST 9
#define RFM95_INT 2

// 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(RFM95_RST, OUTPUT);
  digitalWrite(RFM95_RST, HIGH);

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

  Serial.println("Arduino 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");
    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(23, 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))
    {
      RH_RF95::printBuffer("Received: ", buf, len);
      Serial.print("Got: ");
      Serial.println((char*)buf);
       Serial.print("RSSI: ");
      Serial.println(rf95.lastRssi(), DEC);
    }
    else
    {
      Serial.println("Receive failed");
    }
  }
}

and in receiver serial monitor,
it just shows these kind of messages
15:40:43.488 -> Received:
15:40:43.488 -> 0 0 1 0 14 D4
15:40:43.521 -> Got:
15:40:43.521 -> RSSI: -25
there's no sensor data here.
Are there any errors in this code?
Thanks for your help

Using examples rf_95_server and rf_95_client from library can you make it work?

can you give a link to the shield data?
never used the RH_RF95 library always used LoRa library
however,

void loop()
{
  float t = bme.readTemperature();
  String data = String(t);
  int dataLength = data.length(); dataLength++;
  uint8_t total[dataLength];
  Serial.println(data);
  rf95.send(total, dataLength);
  rf95.waitPacketSent();
  delay(1000);
}

I cannot see where you copy data into Total

There is no point in using Strings on Arduino, especially with AVR-based Arduinos, where they actually cause program crashes.

This is much simpler:

  float t = bme.readTemperature();
  uint8_t buffer[10];
  dtostrf(t, 6, 1, buffer); //format float with 1 decimal place
  Serial.println(buffer);
  rf95.send(buffer, 1+strlen(buffer)); //send C-string plus terminating zero byte

modification of the transmitter from adafruit-rfm69hcw-and-rfm96-rfm95-rfm98-lora-packet-padio-breakouts to transmit BME280 temperature using a UNO with Dragino LoRa shield (using code suggested by @jremington in post 4)

// UNO with Dragino LoRa shield

// -*- mode: C++ -*-
// Example sketch showing how to create a simple messaging client (transmitter)
// 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_RX

#include <SPI.h>
#include <RH_RF95.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>

#define SEALEVELPRESSURE_HPA (1013.25)

Adafruit_BME280 bme;  // I2C
//Adafruit_BME280 bme(BME_CS); // hardware SPI
//Adafruit_BME280 bme(BME_CS, BME_MOSI, BME_MISO, BME_SCK); // software SPI

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

/* for shield */
#define RFM95_CS 10
#define RFM95_RST 9
#define RFM95_INT 2



/* for ESP w/featherwing 
#define RFM95_CS  2    // "E"
#define RFM95_RST 16   // "D"
#define RFM95_INT 15   // "B"
*/

/* Feather 32u4 w/wing
#define RFM95_RST     11   // "A"
#define RFM95_CS      10   // "B"
#define RFM95_INT     2    // "SDA" (only SDA/SCL/RX/TX have IRQ!)
*/

/* Feather m0 w/wing 
#define RFM95_RST     11   // "A"
#define RFM95_CS      10   // "B"
#define RFM95_INT     6    // "D"
*/

/* Teensy 3.x w/wing 
#define RFM95_RST     9   // "A"
#define RFM95_CS      10   // "B"
#define RFM95_INT     4    // "C"
*/

// Change to 434.0 or other frequency, must match RX's freq!
#define RF95_FREQ 868.0

// Singleton instance of the radio driver
RH_RF95 rf95(RFM95_CS, RFM95_INT);

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

  while (!Serial)
    ;
  Serial.begin(115200);
  delay(100);

  Serial.println("Uno LoRa shield BME280 TX Test!");
  int status = bme.begin(0x76);
  if (!status) {
    Serial.println("Could not find a valid BME280 sensor, check wiring!");
    while (1)
      ;
  }
  Serial.println("BME280 sensor, found!");

  // manual reset
  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);

  // 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(23, false);
}

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

void loop() {
  Serial.println("Sending to rf95_server");
  float t = bme.readTemperature();
  char buffer[50]="temperature ";
  dtostrf(t, 6, 1, &buffer[12]);  //format float with 1 decimal place
  Serial.println(buffer);
  rf95.send(buffer, 1 + strlen(buffer));  //send C-string plus terminating zero byte
  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...");
  delay(10);
  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(1000);
}

the transmitter serial monitor displays

Sending to rf95_server
temperature   24.5
Waiting for packet to complete...
Waiting for reply...
Got reply: And hello back to you
RSSI: -101
Sending to rf95_server
temperature   24.5
Waiting for packet to complete...
Waiting for reply...
Got reply: And hello back to you
RSSI: -102
Sending to rf95_server
temperature   24.5
Waiting for packet to complete...
Waiting for reply...
Got reply: And hello back to you
RSSI: -102

receiver displays (running on an Adafruit feather 32u4)

Received: 
74 65 6D 70 65 72 61 74 75 72 65 20 20 20 32 34
2E 35 0 
Got: temperature   24.5
RSSI: -109
Sent a reply
Received: 
74 65 6D 70 65 72 61 74 75 72 65 20 20 20 32 34
2E 35 0 
Got: temperature   24.5
RSSI: -109
Sent a reply
Received: 
74 65 6D 70 65 72 61 74 75 72 65 20 20 20 32 34
2E 35 0 
Got: temperature   24.5
RSSI: -109
Sent a reply

edit : if you wish to transmit temperature, pressures and humidity put the data into a structure and transmit that, e.g. see decimals-strings-and-lora/1059497 - simpler and more efficient than transmitting text

Yes, I slightly modified the examples and I think I missed few important arguments for the code..

I also tried these kind of codes but I couldn't understand dtostrf so I added a line

 data.toCharArray(total, dataLength);

and it works well!!

This code will also work well thank you!

You can look these things up on the web, where they are clearly explained.

The forum has option to mark the right answer as solution. Don't need to edit title to mark as solved.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.