example using Radiohead library
UNO transmitter using a LoRa shield
// RH_RF95 - UNO with Dragino LoRa shield - transmit a structure
// -*- 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)
struct __attribute__((packed)) BME280 {
byte StructureID; // identifies the structure type
byte NodeID; // ID of transmitting node
int16_t seq; // sequence number
float temperature;
float pressure;
float altitude;
float humidity;
} bme280 = { 1, 1, 0, 23.0, 1000.0, 100.0, .5 };
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);
int BME280ok = 1;
void setup() {
Wire.setClock(400000);
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) delay(10);
BME280ok = 0; // indicate failed
} else 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() {
if (BME280ok) { // if BME280 connected read data
bme280.temperature = bme.readTemperature();
bme280.pressure = bme.readPressure() / 100.0F;
bme280.altitude = bme.readAltitude(SEALEVELPRESSURE_HPA);
bme280.humidity = bme.readHumidity();
} else { // if not connected generate data
bme280.temperature += 1.0;
bme280.pressure += 10.0;
bme280.altitude -= 3.0;
bme280.humidity += 1.0;
}
Serial.println("Sending BME280 data to to rf95_server");
Serial.print("seq ");
Serial.print(++bme280.seq);
Serial.print(" Temperature = ");
Serial.print(bme280.temperature);
Serial.print("*C");
Serial.print(" Pressure = ");
Serial.print(bme280.pressure);
Serial.print("hPa");
Serial.print(" Approx. Altitude = ");
Serial.print(bme280.altitude);
Serial.print("m");
Serial.print(" Humidity = ");
Serial.print(bme280.humidity);
Serial.println("%");
rf95.send((byte *)&bme280, sizeof(bme280));
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(3000);
}
receiver using a Feather 32u4
// RH_RF95 - Adafruit Feather 32u4 LoRa - receive a structure
// -*- mode: C++ -*-
// Example sketch showing how to create a simple messaging client (receiver)
// 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_TX
#include <SPI.h>
#include <RH_RF95.h>
struct __attribute__((packed)) BME280 {
byte StructureID; // identifies the structure type
byte NodeID; // ID of transmitting node
int16_t seq; // sequence number
float temperature;
float pressure;
float altitude;
float humidity;
} bme280;
/* 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);
// Blinky on receipt
#define LED 13
void setup() {
pinMode(LED, OUTPUT);
pinMode(RFM95_RST, OUTPUT);
digitalWrite(RFM95_RST, HIGH);
while (!Serial)
;
Serial.begin(115200);
delay(100);
Serial.println("Feather 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(bme280);
if (rf95.recv((byte *)&bme280, &len)) {
digitalWrite(LED, HIGH);
RH_RF95::printBuffer("Received: ", (byte *)&bme280, len);
if(len != sizeof(bme280)) {
Serial.println("***** packet wrong length! *****");
return;
}
Serial.print("RSSI: ");
Serial.print(rf95.lastRssi(), DEC);
Serial.print(" seq ");
Serial.print(bme280.seq);
Serial.print(" Temperature = ");
Serial.print(bme280.temperature);
Serial.print("*C ");
// Convert temperature to Fahrenheit
Serial.print(1.8 * bme280.temperature + 32);
Serial.print("*F");
Serial.print(" Pressure = ");
Serial.print(bme280.pressure);
Serial.print("hPa");
Serial.print(" Approx. Altitude = ");
Serial.print(bme280.altitude);
Serial.print("m");
Serial.print(" Humidity = ");
Serial.print(bme280.humidity);
Serial.println("%");
delay(10);
static int16_t seqExpected = 0, seqErrors = 0;
if (bme280.seq != seqExpected) { // check for sequence error!
Serial.print(" ***** seq number error expected ");
Serial.print(seqExpected);
Serial.print(" received ");
Serial.print(bme280.seq);
Serial.print(" seq errors ");
Serial.println(++seqErrors);
seqExpected = bme280.seq;
}
seqExpected++; // next sequence nunber expected
// Send a reply
delay(200); // may or may not be needed
uint8_t data[] = "receive OK";
rf95.send(data, sizeof(data));
rf95.waitPacketSent();
Serial.println("Sent a reply");
digitalWrite(LED, LOW);
} else {
Serial.println("Receive failed");
}
}
}
results
transmitter
Uno LoRa shield BME280 TX Test!
BME280 sensor, found!
LoRa radio init OK!
Set Freq to: 868.00
Sending BME280 data to to rf95_server
seq 1 Temperature = 21.27*C Pressure = 1019.87hPa Approx. Altitude = -54.98m Humidity = 44.49%
Waiting for packet to complete...
Waiting for reply...
Got reply: receive OK
RSSI: -98
Sending BME280 data to to rf95_server
seq 2 Temperature = 21.28*C Pressure = 1019.87hPa Approx. Altitude = -55.01m Humidity = 44.37%
Waiting for packet to complete...
Waiting for reply...
Got reply: receive OK
RSSI: -98
Sending BME280 data to to rf95_server
seq 3 Temperature = 21.29*C Pressure = 1019.91hPa Approx. Altitude = -55.27m Humidity = 44.38%
Waiting for packet to complete...
Waiting for reply...
Got reply: receive OK
RSSI: -98
Sending BME280 data to to rf95_server
seq 4 Temperature = 21.28*C Pressure = 1019.92hPa Approx. Altitude = -55.35m Humidity = 44.27%
Waiting for packet to complete...
Waiting for reply...
Got reply: receive OK
receiver
Feather LoRa RX Test!
LoRa radio init OK!
Set Freq to: 868.00
Received:
1 1 1 0 71 3D A8 41 56 F8 7E 44 BA 37 5C C2
0 E2 3A 42
RSSI: -106 seq 1 Temperature = 21.03*C 69.85*F Pressure = 1019.88hPa Approx. Altitude = -55.05m Humidity = 46.72%
***** seq number error expected 40 received 1 seq errors 18
Sent a reply
Received:
1 1 2 0 0 0 AA 41 AD F7 7E 44 25 E1 5B C2
0 0 35 42
RSSI: -106 seq 2 Temperature = 21.25*C 70.25*F Pressure = 1019.87hPa Approx. Altitude = -54.97m Humidity = 45.25%
Sent a reply
Received:
1 1 3 0 7B 14 AA 41 3A FA 7E 44 F 36 5D C2
0 3C 33 42
RSSI: -106 seq 3 Temperature = 21.26*C 70.27*F Pressure = 1019.91hPa Approx. Altitude = -55.30m Humidity = 44.81%
Sent a reply
Received:
1 1 4 0 71 3D AA 41 74 F7 7E 44 16 C6 5B C2
0 4F 32 42
RSSI: -106 seq 4 Temperature = 21.28*C 70.30*F Pressure = 1019.87hPa Approx. Altitude = -54.94m Humidity = 44.58%
Sent a reply
Received:
1 1 5 0 71 3D AA 41 C F9 7E 44 21 99 5C C2
0 CA 31 42
RSSI: -106 seq 5 Temperature = 21.28*C 70.30*F Pressure = 1019.89hPa Approx. Altitude = -55.15m Humidity = 44.45%
Sent a reply
on the initial communication a sequence number error is displayed as the sequence numbers synchronise