first commit
This commit is contained in:
@@ -0,0 +1,308 @@
|
||||
/*******************************************************************************************************
|
||||
Programs for Arduino - Copyright of the author Stuart Robinson - 03/02/20
|
||||
|
||||
This program is supplied as is, it is up to the user of the program to decide if the program is
|
||||
suitable for the intended purpose and free from errors.
|
||||
*******************************************************************************************************/
|
||||
|
||||
/*******************************************************************************************************
|
||||
Program Operation - The program transmits a LoRa packet without using a processor buffer, the LoRa
|
||||
devices internal buffer is filled directly with variables.
|
||||
|
||||
The sensor used is a BME280. The pressure, humidity, and temperature are read and transmitted. There
|
||||
is also a 16bit value of battery mV (simulated) and and a 8 bit status value at the packet end.
|
||||
|
||||
Although the LoRa packet transmitted and received has its own internal CRC error checking, you could
|
||||
still receive packets of the same length from another source. If this valid packet were to be used
|
||||
to recover the sensor values, you could be reading rubbish. To reduce the risk of this, when the packet
|
||||
is transmitted the CRC value of the actual sensor data is calculated and sent out with the packet.
|
||||
This CRC value is read by the receiver and used to check that the received CRC matches the supposed
|
||||
sensor data in the packet. As an additional check there is some addressing information at the beginning
|
||||
of the packet which is also checked for validity. Thus we can be relatively confident when reading the
|
||||
received packet that its genuine and from this transmitter. The packet is built and sent in the
|
||||
sendSensorPacket() function, there is a 'highlighted section' where the actual sensor data is added to
|
||||
the packet.
|
||||
|
||||
Between readings the LoRa device, BME280 sensor, and Atmel microcontroller are put to sleep in units of
|
||||
8 seconds using the Atmel processor internal watchdog.
|
||||
|
||||
The pin definitions, LoRa frequency and LoRa modem settings are in the Settings.h file.
|
||||
|
||||
The program also has the option of using a logic pin to control the power to the lora and SD card
|
||||
devices, which can save power in sleep mode. If the hardware is fitted to your board these devices are
|
||||
powered on by setting the VCCPOWER pin low. If your board does not have this feature set VCCPOWER to -1.
|
||||
|
||||
There is also an option of using a logic pin to turn the resistor divider used to read battery voltage on
|
||||
and off. This reduces current used in sleep mode. To use the feature set the define for pin BATVREADON
|
||||
in 'Settings.h' to the pin used. If not using the feature set the pin number to -1.
|
||||
|
||||
Serial monitor baud rate is set at 9600.
|
||||
*******************************************************************************************************/
|
||||
|
||||
#include <SPI.h>
|
||||
#include <SX127XLT.h>
|
||||
#include "Settings.h"
|
||||
#include <ProgramLT_Definitions.h>
|
||||
|
||||
SX127XLT LT;
|
||||
|
||||
#include <Seeed_BME280.h> //get library here; https://github.com/Seeed-Studio/Grove_BME280
|
||||
BME280 bme280; //create an instance of the BME280 senosor
|
||||
#include <Wire.h>
|
||||
|
||||
uint32_t TXpacketCount;
|
||||
uint8_t TXPacketL;
|
||||
|
||||
float temperature; //the BME280 temperature value
|
||||
float pressure; //the BME280 pressure value
|
||||
uint16_t humidity; //the BME280 humididty value
|
||||
uint16_t voltage; //the battery voltage value
|
||||
uint8_t statusbyte; //a status byte, not currently used
|
||||
uint16_t CRCvalue; //the CRC value of the packet data up to this point
|
||||
uint8_t packetlength; //the packet length that was sent, checked against length received
|
||||
|
||||
|
||||
#define uS_TO_S_FACTOR 1000000 //Conversion factor for micro seconds to seconds
|
||||
|
||||
void loop()
|
||||
{
|
||||
TXpacketCount++;
|
||||
Serial.print(TXpacketCount); //print the numbers of sends
|
||||
Serial.print(F(" Sending > "));
|
||||
|
||||
readSensors(); //read the sensor values
|
||||
printSensorValues(); //print the sensor values
|
||||
|
||||
if (sendSensorPacket())
|
||||
{
|
||||
Serial.println(F("SentOK"));
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.print(F("Send Error - IRQreg,"));
|
||||
Serial.println(LT.readIrqStatus(), HEX);
|
||||
}
|
||||
|
||||
Serial.print(F("Sleeping zzzz"));
|
||||
Serial.flush(); //make sure all serial output has gone
|
||||
|
||||
//now put the sensor, LoRa device and processor to sleep
|
||||
sleepBME280(); //sleep the BME280
|
||||
|
||||
digitalWrite(VCCPOWER, HIGH); //VCCOUT off. lora device off
|
||||
esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
|
||||
esp_deep_sleep_start();
|
||||
|
||||
//wait a bit ................
|
||||
Serial.println(F("Why are we here, ESP32 should re-start on wakeup ?")); //the processor has woken up ?
|
||||
Serial.println();
|
||||
normalBME280(); //BME280 sensor to normal mode
|
||||
}
|
||||
|
||||
|
||||
uint8_t sendSensorPacket()
|
||||
{
|
||||
//The SX12XX buffer is filled with variables of a known type and in a known sequence. Make sure the
|
||||
//receiver uses the same variable types and sequence to read variables out of the receive buffer.
|
||||
uint8_t len;
|
||||
|
||||
LT.startWriteSXBuffer(0); //start the write packet to buffer process
|
||||
|
||||
LT.writeUint8(Sensor1); //this byte defines the packet type
|
||||
LT.writeUint8('B'); //this byte identifies the destination node of the packet
|
||||
LT.writeUint8(1); //this byte identifies the source node of the packet
|
||||
|
||||
/************************************************************************
|
||||
Highlighted section - this is where the actual sensor data is added to the packet
|
||||
************************************************************************/
|
||||
LT.writeFloat(temperature); //add the BME280 temperature
|
||||
LT.writeFloat(pressure); //add the BME280 pressure
|
||||
LT.writeUint16(humidity); //add the BME280 humididty
|
||||
LT.writeUint16(voltage); //add the battery voltage
|
||||
LT.writeUint8(statusbyte); //add the status byte
|
||||
/************************************************************************/
|
||||
|
||||
len = LT.endWriteSXBuffer(); //close the packet, get the length of data to be sent
|
||||
|
||||
addPacketErrorCheck(len); //add the additional CRC error checking to the packet end
|
||||
|
||||
//now transmit the packet, set a timeout of 5000mS, wait for it to complete sending
|
||||
digitalWrite(LED1, HIGH); //turn on LED as an indicator
|
||||
TXPacketL = LT.transmitSXBuffer(0, (len + 2), 5000, TXpower, WAIT_TX);
|
||||
digitalWrite(LED1, LOW); //turn off indicator LED
|
||||
|
||||
return TXPacketL; //TXPacketL will be 0 if there was an error sending
|
||||
}
|
||||
|
||||
|
||||
void addPacketErrorCheck(uint8_t len)
|
||||
{
|
||||
//calculate the CRC of packet sensor data
|
||||
CRCvalue = LT.CRCCCITTSX(3, (len - 1), 0xFFFF);
|
||||
|
||||
Serial.print(F("Calculated CRC value "));
|
||||
Serial.println(CRCvalue, HEX);
|
||||
|
||||
LT.startWriteSXBuffer(len); //start the write packet again at location of CRC, past end of sensor data
|
||||
LT.writeUint16(CRCvalue); //add the actual CRC value
|
||||
LT.endWriteSXBuffer(); //close the packet
|
||||
}
|
||||
|
||||
|
||||
void readSensors()
|
||||
{
|
||||
//read the sensor values into the global variables
|
||||
temperature = bme280.getTemperature();
|
||||
pressure = bme280.getPressure();
|
||||
humidity = bme280.getHumidity();
|
||||
|
||||
if (BATVREADON >= 0)
|
||||
{
|
||||
voltage = readBatteryVoltage(); //read resistor divider across battery
|
||||
}
|
||||
else
|
||||
{
|
||||
voltage = 9999; //set a default value
|
||||
}
|
||||
statusbyte = 0x55; //manually set this for now, its a test
|
||||
}
|
||||
|
||||
|
||||
void printSensorValues()
|
||||
{
|
||||
Serial.print(F("Temperature,"));
|
||||
Serial.print(temperature, 1);
|
||||
Serial.print(F("c,Pressure,"));
|
||||
Serial.print(pressure, 0);
|
||||
Serial.print(F("Pa,Humidity,"));
|
||||
Serial.print(humidity);
|
||||
Serial.print(F("%,Voltage,"));
|
||||
Serial.print(voltage);
|
||||
Serial.print(F("mV,Status,"));
|
||||
Serial.print(statusbyte, HEX);
|
||||
Serial.print(F(" "));
|
||||
Serial.flush();
|
||||
}
|
||||
|
||||
|
||||
void sleepBME280()
|
||||
{
|
||||
//write this register value to BME280 to put it to sleep
|
||||
writeBME280reg(BME280_REGISTER_CONTROL, B01111100);
|
||||
}
|
||||
|
||||
|
||||
void normalBME280()
|
||||
{
|
||||
//write this register value to BME280 to put it to read mode
|
||||
writeBME280reg(BME280_REGISTER_CONTROL, B01111111);
|
||||
}
|
||||
|
||||
|
||||
void writeBME280reg(byte reg, byte regvalue)
|
||||
{
|
||||
//write a register value to the BME280
|
||||
Wire.beginTransmission((uint8_t) BME280_ADDRESS);
|
||||
Wire.write((uint8_t)reg);
|
||||
Wire.write((uint8_t)regvalue);
|
||||
Wire.endTransmission();
|
||||
}
|
||||
|
||||
|
||||
uint16_t readBatteryVoltage()
|
||||
{
|
||||
uint16_t temp;
|
||||
uint16_t volts = 0;
|
||||
byte index;
|
||||
|
||||
if (BATVREADON >= 0)
|
||||
{
|
||||
digitalWrite(BATVREADON, HIGH); //turn on MOSFET connecting resitor divider in circuit
|
||||
}
|
||||
|
||||
temp = analogRead(BATTERYAD);
|
||||
|
||||
for (index = 0; index <= 4; index++) //sample AD 5 times
|
||||
{
|
||||
temp = analogRead(BATTERYAD);
|
||||
volts = volts + temp;
|
||||
}
|
||||
volts = ((volts / 5) * ADMultiplier);
|
||||
|
||||
if (BATVREADON >= 0)
|
||||
{
|
||||
digitalWrite(BATVREADON, LOW); //turn off MOSFET connecting resitor divider in circuit
|
||||
}
|
||||
|
||||
return volts;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void led_Flash(uint16_t flashes, uint16_t delaymS)
|
||||
{
|
||||
uint16_t index;
|
||||
for (index = 1; index <= flashes; index++)
|
||||
{
|
||||
digitalWrite(LED1, HIGH);
|
||||
delay(delaymS);
|
||||
digitalWrite(LED1, LOW);
|
||||
delay(delaymS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
pinMode(LED1, OUTPUT); //for PCB LED
|
||||
led_Flash(2, 125);
|
||||
|
||||
if (VCCPOWER >= 0)
|
||||
{
|
||||
pinMode(VCCPOWER, OUTPUT); //For controlling power to external devices
|
||||
digitalWrite(VCCPOWER, LOW); //VCCOUT on. lora device on
|
||||
}
|
||||
|
||||
if (BATVREADON >= 0)
|
||||
{
|
||||
pinMode(BATVREADON, OUTPUT);
|
||||
}
|
||||
|
||||
Serial.begin(9600);
|
||||
Serial.println();
|
||||
Serial.println(F("Reset"));
|
||||
|
||||
SPI.begin();
|
||||
|
||||
if (LT.begin(NSS, NRESET, DIO0, DIO1, DIO2, LORA_DEVICE))
|
||||
{
|
||||
Serial.println(F("lora Device pins initialised"));
|
||||
led_Flash(2, 125);
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println(F("Device error"));
|
||||
while (1)
|
||||
{
|
||||
led_Flash(50, 50); //long fast speed flash indicates LoRa device error
|
||||
}
|
||||
}
|
||||
|
||||
LT.setupLoRa(Frequency, Offset, SpreadingFactor, Bandwidth, CodeRate, Optimisation);
|
||||
Serial.println(F("Setup lora device"));
|
||||
|
||||
if (!bme280.init())
|
||||
{
|
||||
Serial.println("BME280 Device error!");
|
||||
led_Flash(100, 15); //long very fast speed flash indicates BME280 device error
|
||||
}
|
||||
|
||||
Serial.println(F("Initialised BME280"));
|
||||
|
||||
Serial.println();
|
||||
Serial.println(F("Transmitter ready"));
|
||||
Serial.println();
|
||||
|
||||
readSensors(); //do an initial sensor read
|
||||
}
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
/*******************************************************************************************************
|
||||
Programs for Arduino - Copyright of the author Stuart Robinson - 03/02/20
|
||||
|
||||
This program is supplied as is, it is up to the user of the program to decide if the program is
|
||||
suitable for the intended purpose and free from errors.
|
||||
*******************************************************************************************************/
|
||||
|
||||
//******* Setup hardware pin definitions here ! ***************
|
||||
|
||||
//These are the pin definitions for one of the Tracker boards, the ESP32_Micro_Node, be sure to change
|
||||
//them to match your own setup. You will also need to connect up the pins for the SPI bus, which on the
|
||||
//ESP32_Micro_Node are SCK on pin 18, MISO on pin 19 and MOSI on pin 23. Some pins such as DIO1, DIO2 and
|
||||
//BUZZER may not be in used by this sketch so they do not need to be connected and should be set to -1.
|
||||
|
||||
#define NSS 5 //select pin on LoRa device
|
||||
#define SCK 18 //SCK on SPI3
|
||||
#define MISO 19 //MISO on SPI3
|
||||
#define MOSI 23 //MOSI on SPI3
|
||||
|
||||
#define NRESET 27 //reset pin on LoRa device
|
||||
#define LED1 2 //on board LED, high for on
|
||||
#define DIO0 35 //DIO0 pin on LoRa device, used for RX and TX done
|
||||
#define DIO1 -1 //DIO1 pin on LoRa device, normally not used so set to -1
|
||||
#define DIO2 -1 //DIO2 pin on LoRa device, normally not used so set to -1
|
||||
#define BUZZER -1 //pin for buzzer, set to -1 if not used
|
||||
#define VCCPOWER 14 //pin controls power to external devices
|
||||
#define BATTERYAD 36 //pin for reading supply voltage
|
||||
#define BATVREADON 25 //when high turns on the resistor divider to measure voltage, -1 if not used
|
||||
#define ADMultiplier 11.65 //Multiplier for conversion of AD reading to mV
|
||||
|
||||
#define LORA_DEVICE DEVICE_SX1278 //this is the device we are using
|
||||
|
||||
//******* Setup LoRa Test Parameters Here ! ***************
|
||||
|
||||
//LoRa Modem Parameters
|
||||
const uint32_t Frequency = 434000000; //frequency of transmissions
|
||||
const uint32_t Offset = 0; //offset frequency for calibration purposes
|
||||
|
||||
const uint8_t Bandwidth = LORA_BW_125; //LoRa bandwidth
|
||||
const uint8_t SpreadingFactor = LORA_SF7; //LoRa spreading factor
|
||||
const uint8_t CodeRate = LORA_CR_4_5; //LoRa coding rate
|
||||
const uint8_t Optimisation = LDRO_AUTO; //low data rate optimisation setting
|
||||
|
||||
const int8_t TXpower = 14; //LoRa transmit power in dBm
|
||||
|
||||
#define BME280_ADDRESS 0x76 //I2C bus address of BME280
|
||||
#define BME280_REGISTER_CONTROL 0xF4 //BME280 register number for power control
|
||||
|
||||
const uint16_t TIME_TO_SLEEP = 16; //Time ESP32 will go to sleep (in seconds)
|
||||
@@ -0,0 +1,358 @@
|
||||
/*******************************************************************************************************
|
||||
Programs for Arduino - Copyright of the author Stuart Robinson - 21/01/20
|
||||
|
||||
This program is supplied as is, it is up to the user of the program to decide if the program is
|
||||
suitable for the intended purpose and free from errors.
|
||||
*******************************************************************************************************/
|
||||
|
||||
/*******************************************************************************************************
|
||||
Program Operation - The program receives a LoRa packet without using a processor buffer, the LoRa devices
|
||||
internal buffer is read direct for the received sensor data.
|
||||
|
||||
The sensor used in the matching '17_Sensor_Transmiter' program is a BME280 and the pressure, humidity,
|
||||
and temperature are being and received. There is also a 16bit value of battery mV and and a 8 bit status
|
||||
value at the end of the packet.
|
||||
|
||||
When a packet is received its printed and assuming the packet is validated, the sensor results are printed
|
||||
to the serial monitor and screen.
|
||||
|
||||
For the sensor data to be accepted as valid the folowing need to match;
|
||||
|
||||
The 16bit CRC on the received sensor data must match the CRC value transmitted with the packet.
|
||||
The packet must start with a byte that matches the packet type sent, 'Sensor1'
|
||||
The RXdestination byte in the packet must match this node ID of this receiver node, defined by 'This_Node'
|
||||
|
||||
In total thats 16 + 8 + 8 = 32bits of checking, so a 1:4294967296 chance (approx) that an invalid
|
||||
packet is acted on and erroneous values displayed.
|
||||
|
||||
The pin definitions, LoRa frequency and LoRa modem settings are in the Settings.h file.
|
||||
|
||||
Serial monitor baud rate is set at 9600.
|
||||
*******************************************************************************************************/
|
||||
|
||||
#include <SPI.h>
|
||||
#include <SX127XLT.h>
|
||||
#include "Settings.h"
|
||||
#include <ProgramLT_Definitions.h>
|
||||
|
||||
SX127XLT LT;
|
||||
|
||||
#include <U8x8lib.h> //get library here > https://github.com/olikraus/u8g2
|
||||
U8X8_SSD1306_128X64_NONAME_HW_I2C disp(U8X8_PIN_NONE); //use this line for standard 0.96" SSD1306
|
||||
//U8X8_SH1106_128X64_NONAME_HW_I2C disp(U8X8_PIN_NONE); //use this line for 1.3" OLED often sold as 1.3" SSD1306
|
||||
|
||||
uint32_t RXpacketCount; //count of all packets received
|
||||
uint32_t ValidPackets; //count of packets received with valid data
|
||||
uint32_t RXpacketErrors; //count of all packets with errors received
|
||||
bool packetisgood;
|
||||
|
||||
uint8_t RXPacketL; //length of received packet
|
||||
int8_t PacketRSSI; //RSSI of received packet
|
||||
int8_t PacketSNR; //signal to noise ratio of received packet
|
||||
|
||||
uint8_t RXPacketType;
|
||||
uint8_t RXDestination;
|
||||
uint8_t RXSource;
|
||||
float temperature; //the BME280 temperature value
|
||||
float pressure; //the BME280 pressure value
|
||||
uint16_t humidity; //the BME280 humididty value
|
||||
uint16_t voltage; //the battery voltage value
|
||||
uint8_t statusbyte; //a status byte, not currently used
|
||||
uint16_t TXCRCvalue; //the CRC value of the packet data as transmitted
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
RXPacketL = LT.receiveSXBuffer(0, 0, WAIT_RX); //returns 0 if packet error of some sort, no timeout set
|
||||
|
||||
digitalWrite(LED1, HIGH); //something has happened
|
||||
|
||||
PacketRSSI = LT.readPacketRSSI();
|
||||
PacketSNR = LT.readPacketSNR();
|
||||
|
||||
if (RXPacketL == 0)
|
||||
{
|
||||
packet_is_Error();
|
||||
}
|
||||
else
|
||||
{
|
||||
packet_Received_OK(); //its a valid packet LoRa wise, but it might not be a packet we want
|
||||
}
|
||||
|
||||
digitalWrite(LED1, LOW);
|
||||
Serial.println();
|
||||
//SPI.endTransaction();
|
||||
}
|
||||
|
||||
|
||||
void packet_Received_OK()
|
||||
{
|
||||
//a LoRa packet has been received, which has passed the internal LoRa checks, including CRC, but it could be from
|
||||
//an unknown source, so we need to check that its actually a sensor packet we are expecting, and has valid sensor data
|
||||
|
||||
uint8_t len;
|
||||
uint8_t contenterrors; //keep a count of errors found in packet
|
||||
|
||||
RXpacketCount++;
|
||||
Serial.print(RXpacketCount);
|
||||
Serial.print(F(",PacketsReceived,"));
|
||||
|
||||
LT.startReadSXBuffer(0);
|
||||
RXPacketType = LT.readUint8();
|
||||
RXDestination = LT.readUint8();
|
||||
RXSource = LT.readUint8();
|
||||
|
||||
/************************************************************************
|
||||
Highlighted section - this is where the actual sensor data is read from
|
||||
the packet
|
||||
************************************************************************/
|
||||
temperature = LT.readFloat(); //the BME280 temperature value
|
||||
pressure = LT.readFloat(); //the BME280 pressure value
|
||||
humidity = LT.readUint16(); //the BME280 humididty value
|
||||
voltage = LT.readUint16(); //the battery voltage value
|
||||
statusbyte = LT.readUint8(); //a status byte, not currently used
|
||||
/************************************************************************/
|
||||
|
||||
len = LT.endReadSXBuffer(); //note len is bytes read from packet, may be different to actual packet length
|
||||
|
||||
printreceptionDetails(); //print details of reception, RSSI etc
|
||||
Serial.println();
|
||||
|
||||
contenterrors = checkPacketValid(len); //pass length of packet to check routine
|
||||
|
||||
if (contenterrors == 0)
|
||||
{
|
||||
Serial.println(F(" Packet is good"));
|
||||
ValidPackets++;
|
||||
printSensorValues(); //print the sensor values
|
||||
Serial.println();
|
||||
printPacketCounts(); //print count of valid packets and errors
|
||||
displayscreen1();
|
||||
Serial.println();
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println(F(" Packet is not valid"));
|
||||
RXpacketErrors++;
|
||||
disp.clearLine(7);
|
||||
disp.setCursor(0, 7);
|
||||
disp.print(F("Errors "));
|
||||
disp.print(RXpacketErrors);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint8_t checkPacketValid(uint8_t len)
|
||||
{
|
||||
//this function checks if the packet is valid and will be displayed
|
||||
|
||||
uint8_t errors = 0;
|
||||
|
||||
if (RXPacketType != Sensor1) //is it a Sensor1 type packet
|
||||
{
|
||||
errors++;
|
||||
}
|
||||
|
||||
if (RXDestination != This_Node) //was the packet sent to this receiver node ?
|
||||
{
|
||||
errors++;
|
||||
}
|
||||
|
||||
if (!checkCRCvalue(len)) //is the sent CRC value of sensor data valid ?
|
||||
{
|
||||
errors++;
|
||||
}
|
||||
|
||||
Serial.println();
|
||||
Serial.print(F("Error Check Count = "));
|
||||
Serial.print(errors);
|
||||
return errors;
|
||||
}
|
||||
|
||||
|
||||
bool checkCRCvalue(uint8_t len)
|
||||
{
|
||||
uint16_t CRCSensorData;
|
||||
//uint8_t msb, lsb;
|
||||
|
||||
CRCSensorData = LT.CRCCCITTSX(3, (len-1), 0xFFFF); //calculate the CRC of packet sensor data
|
||||
|
||||
Serial.print(F("(CRC of Received sensor data "));
|
||||
Serial.print(CRCSensorData, HEX);
|
||||
Serial.print(F(")" ));
|
||||
|
||||
//SPI.endTransaction();
|
||||
|
||||
TXCRCvalue = ((LT.getByteSXBuffer(17) << 8) + (LT.getByteSXBuffer(16)));
|
||||
|
||||
Serial.print(F("(CRC transmitted "));
|
||||
Serial.print(TXCRCvalue, HEX);
|
||||
Serial.print(F(")" ));
|
||||
|
||||
if (TXCRCvalue != CRCSensorData)
|
||||
{
|
||||
Serial.print(F(" Sensor Data Not Valid"));
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.print(F(" Sensor Data is Valid"));
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void printSensorValues()
|
||||
{
|
||||
Serial.print(F("Temperature,"));
|
||||
Serial.print(temperature, 1);
|
||||
Serial.print(F("c,Pressure,"));
|
||||
Serial.print(pressure, 0);
|
||||
Serial.print(F("Pa,Humidity,"));
|
||||
Serial.print(humidity);
|
||||
Serial.print(F("%,Voltage,"));
|
||||
Serial.print(voltage);
|
||||
Serial.print(F("mV,Status,"));
|
||||
Serial.print(statusbyte, HEX);
|
||||
Serial.print(F(",CRC,"));
|
||||
Serial.print(TXCRCvalue, HEX);
|
||||
Serial.flush();
|
||||
}
|
||||
|
||||
|
||||
void printreceptionDetails()
|
||||
{
|
||||
Serial.print(F("RSSI"));
|
||||
Serial.print(PacketRSSI);
|
||||
Serial.print(F("dBm,SNR,"));
|
||||
Serial.print(PacketSNR);
|
||||
Serial.print(F("dB,Length,"));
|
||||
Serial.print(LT.readRXPacketL());
|
||||
}
|
||||
|
||||
|
||||
void printPacketCounts()
|
||||
{
|
||||
Serial.print(F("ValidPackets,"));
|
||||
Serial.print(ValidPackets);
|
||||
Serial.print(F(",Errors,"));
|
||||
Serial.print(RXpacketErrors);
|
||||
}
|
||||
|
||||
|
||||
void packet_is_Error()
|
||||
{
|
||||
uint16_t IRQStatus;
|
||||
|
||||
RXpacketErrors++;
|
||||
IRQStatus = LT.readIrqStatus();
|
||||
|
||||
if (IRQStatus & IRQ_RX_TIMEOUT)
|
||||
{
|
||||
Serial.print(F("RXTimeout "));
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.print(F("PacketError "));
|
||||
printreceptionDetails();
|
||||
Serial.print(F(",IRQreg,"));
|
||||
Serial.print(IRQStatus, HEX);
|
||||
LT.printIrqStatus();
|
||||
Serial.println();
|
||||
disp.clearLine(7);
|
||||
disp.setCursor(0, 7);
|
||||
disp.print(F("Errors "));
|
||||
disp.print(RXpacketErrors);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void displayscreen1()
|
||||
{
|
||||
//show sensor data on display
|
||||
disp.clearLine(0);
|
||||
disp.setCursor(0, 0);
|
||||
disp.print(F("Sensor "));
|
||||
disp.print(RXSource);
|
||||
disp.clearLine(1);
|
||||
disp.setCursor(0, 1);
|
||||
disp.print(temperature, 1);
|
||||
disp.print(F("c"));
|
||||
disp.clearLine(2);
|
||||
disp.setCursor(0, 2);
|
||||
disp.print(pressure, 0);
|
||||
disp.print(F("Pa"));
|
||||
disp.clearLine(3);
|
||||
disp.setCursor(0, 3);
|
||||
disp.print(humidity);
|
||||
disp.print(F("%"));
|
||||
disp.clearLine(4);
|
||||
disp.setCursor(0, 4);
|
||||
disp.print(voltage);
|
||||
disp.print(F("mV"));
|
||||
disp.clearLine(6);
|
||||
disp.setCursor(0, 6);
|
||||
disp.print(F("ValidPkts "));
|
||||
disp.print(ValidPackets);
|
||||
disp.setCursor(0, 7);
|
||||
disp.print(F("Errors "));
|
||||
disp.print(RXpacketErrors);
|
||||
}
|
||||
|
||||
|
||||
void led_Flash(uint16_t flashes, uint16_t delaymS)
|
||||
{
|
||||
uint16_t index;
|
||||
|
||||
for (index = 1; index <= flashes; index++)
|
||||
{
|
||||
digitalWrite(LED1, HIGH);
|
||||
delay(delaymS);
|
||||
digitalWrite(LED1, LOW);
|
||||
delay(delaymS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
pinMode(VCCPOWER, OUTPUT); //this pin switches power for external devices, lora and SD card
|
||||
digitalWrite(VCCPOWER, LOW); //turn power on
|
||||
|
||||
pinMode(LED1, OUTPUT);
|
||||
led_Flash(2, 125);
|
||||
|
||||
Serial.begin(9600);
|
||||
|
||||
disp.begin();
|
||||
disp.setFont(u8x8_font_chroma48medium8_r);
|
||||
|
||||
disp.clear();
|
||||
disp.setCursor(0, 0);
|
||||
disp.print(F("Check LoRa"));
|
||||
disp.setCursor(0, 1);
|
||||
|
||||
SPI.begin();
|
||||
|
||||
if (LT.begin(NSS, NRESET, DIO0, DIO1, DIO2, LORA_DEVICE))
|
||||
{
|
||||
disp.print(F("LoRa OK"));
|
||||
led_Flash(2, 125);
|
||||
}
|
||||
else
|
||||
{
|
||||
disp.print(F("Device error"));
|
||||
Serial.println(F("Device error"));
|
||||
while (1)
|
||||
{
|
||||
led_Flash(50, 50); //long fast speed flash indicates device error
|
||||
}
|
||||
}
|
||||
|
||||
LT.setupLoRa(Frequency, Offset, SpreadingFactor, Bandwidth, CodeRate, Optimisation);
|
||||
|
||||
Serial.println(F("Receiver ready"));
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
/*******************************************************************************************************
|
||||
Programs for Arduino - Copyright of the author Stuart Robinson - 17/12/19
|
||||
|
||||
This program is supplied as is, it is up to the user of the program to decide if the program is
|
||||
suitable for the intended purpose and free from errors.
|
||||
*******************************************************************************************************/
|
||||
|
||||
|
||||
//******* Setup hardware pin definitions here ! ***************
|
||||
|
||||
//These are the pin definitions for one of the Tracker boards, the ESP32_Micro_Node, be sure to change
|
||||
//them to match your own setup. You will also need to connect up the pins for the SPI bus, which on the
|
||||
//ESP32_Micro_Node are SCK on pin 18, MISO on pin 19 and MOSI on pin 23. Some pins such as DIO1, DIO2 and
|
||||
//BUZZER may not be in used by this sketch so they do not need to be connected and should be set to -1.
|
||||
|
||||
#define NSS 5 //select pin on LoRa device
|
||||
#define SCK 18 //SCK on SPI3
|
||||
#define MISO 19 //MISO on SPI3
|
||||
#define MOSI 23 //MOSI on SPI3
|
||||
|
||||
#define NRESET 27 //reset pin on LoRa device
|
||||
#define LED1 2 //on board LED, high for on
|
||||
#define DIO0 35 //DIO0 pin on LoRa device, used for RX and TX done
|
||||
#define DIO1 -1 //DIO1 pin on LoRa device, normally not used so set to -1
|
||||
#define DIO2 -1 //DIO2 pin on LoRa device, normally not used so set to -1
|
||||
#define BUZZER -1 //pin for buzzer, set to -1 if not used
|
||||
#define VCCPOWER 14 //pin controls power to external devices
|
||||
#define LORA_DEVICE DEVICE_SX1278 //this is the device we are using
|
||||
|
||||
|
||||
//*************** Setup LoRa Test Parameters Here ! ***************
|
||||
|
||||
//LoRa Modem Parameters
|
||||
const uint32_t Frequency = 434000000; //frequency of transmissions
|
||||
const uint32_t Offset = 0; //offset frequency for calibration purposes
|
||||
|
||||
const uint8_t Bandwidth = LORA_BW_125; //LoRa bandwidth
|
||||
const uint8_t SpreadingFactor = LORA_SF7; //LoRa spreading factor
|
||||
const uint8_t CodeRate = LORA_CR_4_5; //LoRa coding rate
|
||||
const uint8_t Optimisation = LDRO_AUTO; //low data rate optimisation setting
|
||||
|
||||
const int8_t TXpower = 2; //LoRa TX power
|
||||
|
||||
#define packet_delay 1000 //mS delay between packets
|
||||
#define This_Node 'B' //this is the node that the remote sensors send data to
|
||||
|
||||
//**************** Setup Display Parameters Here ****************
|
||||
|
||||
//const uint8_t dispfont = u8x8_font_chroma48medium8_r; //display font from u8g2 library
|
||||
Reference in New Issue
Block a user