Init fork from Stuart Robinson's repo
This commit is contained in:
@ -0,0 +1,314 @@
|
||||
/*******************************************************************************************************
|
||||
Programs for Arduino - Copyright of the author Stuart Robinson - 20/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 program is for Atmel Arduinos.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
The Atmel watchdog timer is a viable option for a very low current sensor node. A 'bare bones' ATmega328P
|
||||
with regulator and LoRa device has a sleep current of 6.6uA, add the LoRa devices and BME280 sensor
|
||||
module and the average sleep current only rises to 6.8uA.
|
||||
|
||||
One of these transmitter programs is running on a long term test with a 150mAh battery, to see how long
|
||||
the battery actually lasts.
|
||||
|
||||
Serial monitor baud rate is set at 9600.
|
||||
*******************************************************************************************************/
|
||||
|
||||
#include <SPI.h>
|
||||
#include <SX128XLT.h>
|
||||
#include "Settings.h"
|
||||
#include <ProgramLT_Definitions.h>
|
||||
|
||||
#include <avr/wdt.h> //watchdog timer library for Atmel processors, integral to Arduino IDE
|
||||
#include <LowPower.h> //get the library here; https://github.com/rocketscream/Low-Power
|
||||
|
||||
SX128XLT 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
|
||||
|
||||
|
||||
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
|
||||
LT.setSleep(CONFIGURATION_RETENTION); //sleep LoRa device, keeping register settings in sleep.
|
||||
sleep8seconds(sleeps); //sleep Atmel processor in units of approx 8 seconds
|
||||
|
||||
//wait a bit ................
|
||||
Serial.println(F(" - Awake !!")); //the processor has woken up
|
||||
Serial.println();
|
||||
|
||||
LT.wake();
|
||||
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 sleep8seconds(uint32_t sleeps)
|
||||
{
|
||||
//uses the lowpower library
|
||||
uint32_t index;
|
||||
|
||||
for (index = 1; index <= sleeps; index++)
|
||||
{
|
||||
//sleep 8 seconds
|
||||
LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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()
|
||||
{
|
||||
//relies on 1V1 internal reference and 91K & 11K resistor divider
|
||||
//returns supply in mV @ 10mV per AD bit read
|
||||
uint16_t temp;
|
||||
uint16_t volts = 0;
|
||||
byte index;
|
||||
|
||||
if (BATVREADON >= 0)
|
||||
{
|
||||
digitalWrite(BATVREADON, HIGH); //turn on MOSFET connecting resitor divider in circuit
|
||||
}
|
||||
|
||||
analogReference(INTERNAL1V1);
|
||||
temp = analogRead(BATTERYAD);
|
||||
|
||||
for (index = 0; index <= 4; index++) //sample AD 5 times
|
||||
{
|
||||
temp = analogRead(BATTERYAD);
|
||||
volts = volts + temp;
|
||||
}
|
||||
volts = ((volts / 5) * ADMultiplier) + DIODEMV;
|
||||
|
||||
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);
|
||||
led_Flash(2, 125);
|
||||
|
||||
if (BATVREADON >= 0)
|
||||
{
|
||||
pinMode(BATVREADON, OUTPUT);
|
||||
}
|
||||
|
||||
Serial.begin(9600);
|
||||
|
||||
SPI.begin();
|
||||
|
||||
if (LT.begin(NSS, NRESET, RFBUSY, DIO1, LORA_DEVICE))
|
||||
{
|
||||
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);
|
||||
|
||||
if (!bme280.init())
|
||||
{
|
||||
Serial.println("BME280 Device error!");
|
||||
led_Flash(100, 15); //long very fast speed flash indicates BME280 device error
|
||||
}
|
||||
|
||||
Serial.println(F("Transmitter ready"));
|
||||
Serial.println();
|
||||
|
||||
readSensors(); //do an initial sensor read
|
||||
}
|
||||
@ -0,0 +1,38 @@
|
||||
/*******************************************************************************************************
|
||||
Programs for Arduino - Copyright of the author Stuart Robinson - 29/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 my own boards, the Easy Pro Mini,
|
||||
//be sure to change the definitions to match your own setup.
|
||||
|
||||
#define NSS 10
|
||||
#define RFBUSY 7
|
||||
#define NRESET 9
|
||||
#define LED1 8
|
||||
#define DIO1 3
|
||||
|
||||
#define BATVREADON 8 //when high turns on the resistor divider to measure voltage, -1 if not used
|
||||
#define BATTERYAD A7 //Resitor divider for battery connected here, -1 if not used
|
||||
#define ADMultiplier 10.00 //adjustment to convert AD value read into mV of battery voltage
|
||||
#define DIODEMV 98 //mV voltage drop accross diode @ low idle current
|
||||
|
||||
#define LORA_DEVICE DEVICE_SX1280 //we need to define the device we are using
|
||||
|
||||
//LoRa Modem Parameters
|
||||
const uint32_t Frequency = 2445000000; //frequency of transmissions
|
||||
const int32_t Offset = 0; //offset frequency for calibration purposes
|
||||
const uint8_t Bandwidth = LORA_BW_0400; //LoRa bandwidth
|
||||
const uint8_t SpreadingFactor = LORA_SF7; //LoRa spreading factor
|
||||
const uint8_t CodeRate = LORA_CR_4_5; //LoRa coding rate
|
||||
|
||||
const int8_t TXpower = 10; //Power for transmissions in dBm
|
||||
|
||||
#define BME280_ADDRESS 0x76 //I2C bus address of BME280
|
||||
#define BME280_REGISTER_CONTROL 0xF4 //BME280 register number for power control
|
||||
|
||||
const uint8_t sleeps = 2; //number of 8 second sleeps, gap between transmissions
|
||||
@ -0,0 +1,357 @@
|
||||
/*******************************************************************************************************
|
||||
Programs for Arduino - Copyright of the author Stuart Robinson - 29/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 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 the program starts, the LoRa device is setup to set the DIO1 pin high when a packet is received. 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.
|
||||
|
||||
With a standard Arduino Pro Mini and SSD1306 display the current consumption was 20.25mA with the
|
||||
display and 16.6mA without the display.
|
||||
|
||||
Serial monitor baud rate is set at 9600.
|
||||
*******************************************************************************************************/
|
||||
|
||||
#include <SPI.h>
|
||||
#include <SX128XLT.h>
|
||||
#include "Settings.h"
|
||||
#include <ProgramLT_Definitions.h>
|
||||
|
||||
SX128XLT 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
|
||||
int16_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();
|
||||
}
|
||||
|
||||
|
||||
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();
|
||||
|
||||
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;
|
||||
|
||||
Serial.print(F("len = "));
|
||||
Serial.println(len);
|
||||
|
||||
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(")" ));
|
||||
|
||||
TXCRCvalue = ((LT.getByteSXBuffer(len + 1) << 8) + (LT.getByteSXBuffer(len)));
|
||||
|
||||
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("Temp,"));
|
||||
Serial.print(temperature, 1);
|
||||
Serial.print(F("c,Press,"));
|
||||
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(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, RFBUSY, DIO1, 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);
|
||||
|
||||
Serial.println(F("Receiver ready"));
|
||||
Serial.println();
|
||||
}
|
||||
@ -0,0 +1,38 @@
|
||||
/*******************************************************************************************************
|
||||
Programs for Arduino - Copyright of the author Stuart Robinson - 29/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.
|
||||
*******************************************************************************************************/
|
||||
|
||||
|
||||
//These are the pin definitions for one of my own boards, the Easy Pro Mini,
|
||||
//be sure to change the definitions to match your own setup.
|
||||
|
||||
#define NSS 10
|
||||
#define RFBUSY 7
|
||||
#define NRESET 9
|
||||
#define LED1 8
|
||||
#define DIO1 3
|
||||
|
||||
#define BATVREADON 8 //when high turns on the resistor divider to measure voltage, -1 if not used
|
||||
#define BATTERYAD A7 //Resistor divider for battery connected here, -1 if not used
|
||||
#define ADMultiplier 10.00 //adjustment to convert AD value read into mV of battery voltage
|
||||
#define DIODEMV 98 //mV voltage drop accross diode @ low idle current
|
||||
|
||||
#define LORA_DEVICE DEVICE_SX1280 //we need to define the device we are using
|
||||
|
||||
|
||||
//*************** Setup LoRa Test Parameters Here ! ***************
|
||||
|
||||
//LoRa Modem Parameters
|
||||
const uint32_t Frequency = 2445000000; //frequency of transmissions
|
||||
const int32_t Offset = 0; //offset frequency for calibration purposes
|
||||
const uint8_t Bandwidth = LORA_BW_0400; //LoRa bandwidth
|
||||
const uint8_t SpreadingFactor = LORA_SF7; //LoRa spreading factor
|
||||
const uint8_t CodeRate = LORA_CR_4_5; //LoRa coding rate
|
||||
|
||||
const int8_t TXpower = 10; //Power for transmissions in dBm
|
||||
|
||||
#define packet_delay 1000 //mS delay between packets
|
||||
#define This_Node 'B' //this is the node that the remote sensors send data to
|
||||
Reference in New Issue
Block a user