Init fork from Stuart Robinson's repo
This commit is contained in:
@ -0,0 +1,399 @@
|
||||
/*******************************************************************************************************
|
||||
Programs for Arduino - Copyright of the author Stuart Robinson - 21/03/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 - This program is an example of a basic GPS tracker. The program reads the GPS,
|
||||
waits for an updated fix and transmits location and altitude, number of satellites in view, the HDOP
|
||||
value, the fix time of the GPS and the battery voltage. This transmitter can be also be used to
|
||||
investigate GPS performance. At startup there should be a couple of seconds of recognisable text from
|
||||
the GPS printed to the serial monitor. If you see garbage or funny characters its likley the GPS baud
|
||||
rate is wrong. If the transmitter is turned on from cold, the receiver will pick up the cold fix time,
|
||||
which is an indication of GPS performance. The GPS will be powered on for around 4 seconds before the
|
||||
timing of the fix starts. Outside with a good view of the sky most GPSs should produce a fix in around
|
||||
45 seconds. The number of satellites and HDOP are good indications to how well a GPS is working.
|
||||
|
||||
The program writes direct to the LoRa devices internal buffer, no memory buffer is used.
|
||||
|
||||
The LoRa settings are configured in the Settings.h file.
|
||||
|
||||
The program has the option of using a pin to control the power to the GPS (GPSPOWER), if the GPS module
|
||||
or board being used has this feature. To not use this feature set the define for GPSPOWER in the
|
||||
Settings.h file to '#define GPSPOWER -1'. Also set the GPSONSTATE and GPSOFFSTATE to the appropriate logic
|
||||
levels.
|
||||
|
||||
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 <SX128XLT.h>
|
||||
|
||||
#include "Settings.h"
|
||||
#include <ProgramLT_Definitions.h>
|
||||
|
||||
SX128XLT LT;
|
||||
|
||||
#include <TinyGPS++.h> //get library here > http://arduiniana.org/libraries/tinygpsplus/
|
||||
TinyGPSPlus gps; //create the TinyGPS++ object
|
||||
|
||||
|
||||
#ifdef USE_SOFTSERIAL_GPS
|
||||
#include <SoftwareSerial.h>
|
||||
SoftwareSerial GPSserial(RXpin, TXpin);
|
||||
#else
|
||||
#define GPSserial HardwareSerialPort //hardware serial port (eg Serial1) is configured in the Settings.h file
|
||||
#endif
|
||||
|
||||
|
||||
uint8_t TXStatus = 0; //used to store current status flag bits of Tracker transmitter (TX)
|
||||
uint8_t TXPacketL; //length of LoRa packet (TX)
|
||||
float TXLat; //Latitude from GPS on Tracker transmitter (TX)
|
||||
float TXLon; //Longitude from GPS on Tracker transmitter (TX)
|
||||
float TXAlt; //Altitude from GPS on Tracker transmitter (TX)
|
||||
uint8_t TXSats; //number of GPS satellites seen (TX)
|
||||
uint32_t TXHdop; //HDOP from GPS on Tracker transmitter (TX)
|
||||
uint16_t TXVolts; //Volts (battery) level on Tracker transmitter (TX)
|
||||
uint32_t TXGPSFixTime; //GPS fix time in hot fix mode of GPS on Tracker transmitter (TX)
|
||||
uint32_t TXPacketCount, TXErrorsCount; //keep count of OK packets and send errors
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
|
||||
if (gpsWaitFix(WaitGPSFixSeconds))
|
||||
{
|
||||
sendLocation(TXLat, TXLon, TXAlt, TXHdop, TXGPSFixTime);
|
||||
Serial.println();
|
||||
Serial.print(F("Waiting "));
|
||||
Serial.print(Sleepsecs);
|
||||
Serial.println(F("s"));
|
||||
delay(Sleepsecs * 1000); //this sleep is used to set overall transmission cycle time
|
||||
}
|
||||
else
|
||||
{
|
||||
send_Command(NoFix); //send notification of no GPS fix.
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool gpsWaitFix(uint32_t waitSecs)
|
||||
{
|
||||
//waits a specified number of seconds for a fix, returns true for good fix
|
||||
uint32_t endwaitmS, GPSonTime;
|
||||
bool GPSfix = false;
|
||||
float tempfloat;
|
||||
uint8_t GPSchar;
|
||||
|
||||
GPSonTime = millis();
|
||||
GPSserial.begin(9600); //start GPSserial
|
||||
|
||||
Serial.print(F("Wait GPS Fix "));
|
||||
Serial.print(waitSecs);
|
||||
Serial.println(F("s"));
|
||||
|
||||
endwaitmS = millis() + (waitSecs * 1000);
|
||||
|
||||
while (millis() < endwaitmS)
|
||||
{
|
||||
if (GPSserial.available() > 0)
|
||||
{
|
||||
GPSchar = GPSserial.read();
|
||||
gps.encode(GPSchar);
|
||||
}
|
||||
|
||||
if (gps.location.isUpdated() && gps.altitude.isUpdated())
|
||||
{
|
||||
GPSfix = true;
|
||||
Serial.print(F("Have GPS Fix "));
|
||||
TXGPSFixTime = millis() - GPSonTime;
|
||||
Serial.print(TXGPSFixTime);
|
||||
Serial.println(F("mS"));
|
||||
|
||||
TXLat = gps.location.lat();
|
||||
TXLon = gps.location.lng();
|
||||
TXAlt = gps.altitude.meters();
|
||||
TXSats = gps.satellites.value();
|
||||
TXHdop = gps.hdop.value();
|
||||
tempfloat = ( (float) TXHdop / 100);
|
||||
|
||||
Serial.print(TXLat, 5);
|
||||
Serial.print(F(","));
|
||||
Serial.print(TXLon, 5);
|
||||
Serial.print(F(","));
|
||||
Serial.print(TXAlt, 1);
|
||||
Serial.print(F(","));
|
||||
Serial.print(TXSats);
|
||||
Serial.print(F(","));
|
||||
Serial.print(tempfloat, 2);
|
||||
Serial.println();
|
||||
|
||||
break; //exit while loop reading GPS
|
||||
}
|
||||
}
|
||||
|
||||
//if here then there has either been a fix or no fix and a timeout
|
||||
|
||||
if (GPSfix)
|
||||
{
|
||||
setStatusByte(GPSFix, 1); //set status bit to flag a GPS fix
|
||||
}
|
||||
else
|
||||
{
|
||||
setStatusByte(GPSFix, 0); //set status bit to flag no fix
|
||||
Serial.println();
|
||||
Serial.println(F("Timeout - No GPSFix"));
|
||||
Serial.println();
|
||||
GPSfix = false;
|
||||
}
|
||||
|
||||
GPSserial.end(); //serial RX interrupts interfere with SPI, so stop GPSserial
|
||||
return GPSfix;
|
||||
}
|
||||
|
||||
|
||||
void sendLocation(float Lat, float Lon, float Alt, uint32_t Hdop, uint32_t fixtime)
|
||||
{
|
||||
uint8_t len;
|
||||
uint16_t IRQStatus;
|
||||
|
||||
Serial.print(F("Send Location"));
|
||||
|
||||
TXVolts = readSupplyVoltage(); //get the latest supply\battery volts
|
||||
|
||||
LT.startWriteSXBuffer(0); //initialise buffer write at address 0
|
||||
LT.writeUint8(LocationPacket); //indentify type of packet
|
||||
LT.writeUint8(Broadcast); //who is the packet sent too
|
||||
LT.writeUint8(ThisNode); //tells receiver where is packet from
|
||||
LT.writeFloat(Lat); //add latitude
|
||||
LT.writeFloat(Lon); //add longitude
|
||||
LT.writeFloat(Alt); //add altitude
|
||||
LT.writeUint8(TXSats); //add number of satellites
|
||||
LT.writeUint32(Hdop); //add hdop
|
||||
LT.writeUint8(TXStatus); //add tracker status
|
||||
LT.writeUint32(fixtime); //add GPS fix time in mS
|
||||
LT.writeUint16(TXVolts); //add tracker supply volts
|
||||
LT.writeUint32(millis()); //add uptime in mS
|
||||
len = LT.endWriteSXBuffer(); //close buffer write
|
||||
|
||||
digitalWrite(LED1, HIGH);
|
||||
TXPacketL = LT.transmitSXBuffer(0, len, 10000, TXpower, WAIT_TX);
|
||||
digitalWrite(LED1, LOW);
|
||||
|
||||
if (TXPacketL)
|
||||
{
|
||||
TXPacketCount++;
|
||||
Serial.println(F(" - Done "));
|
||||
Serial.print(F("SentOK,"));
|
||||
Serial.print(TXPacketCount);
|
||||
Serial.print(F(",Errors,"));
|
||||
Serial.println(TXErrorsCount);
|
||||
}
|
||||
else
|
||||
{
|
||||
//if here there was an error transmitting packet
|
||||
TXErrorsCount++;
|
||||
IRQStatus = LT.readIrqStatus(); //read the the interrupt register
|
||||
Serial.print(F(" SendError,"));
|
||||
Serial.print(F("Length,"));
|
||||
Serial.print(TXPacketL); //print transmitted packet length
|
||||
Serial.print(F(",IRQreg,"));
|
||||
Serial.print(IRQStatus, HEX); //print IRQ status
|
||||
LT.printIrqStatus(); //prints the text of which IRQs set
|
||||
Serial.println();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void setStatusByte(uint8_t bitnum, uint8_t bitval)
|
||||
{
|
||||
//program the status byte
|
||||
|
||||
if (bitval == 0)
|
||||
{
|
||||
bitClear(TXStatus, bitnum);
|
||||
}
|
||||
else
|
||||
{
|
||||
bitSet(TXStatus, bitnum);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void led_Flash(uint16_t flashes, uint16_t delaymS)
|
||||
{
|
||||
//flash LED to show tracker is alive
|
||||
uint16_t index;
|
||||
|
||||
for (index = 1; index <= flashes; index++)
|
||||
{
|
||||
digitalWrite(LED1, HIGH);
|
||||
delay(delaymS);
|
||||
digitalWrite(LED1, LOW);
|
||||
delay(delaymS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void send_Command(char cmd)
|
||||
{
|
||||
bool SendOK;
|
||||
uint8_t len;
|
||||
|
||||
Serial.print(F("Send Cmd "));
|
||||
Serial.write(cmd);
|
||||
|
||||
LT.startWriteSXBuffer(0);
|
||||
LT.writeUint8(cmd); //packet addressing used indentify type of packet
|
||||
LT.writeUint8(Broadcast); //who is the packet sent to
|
||||
LT.writeUint8(ThisNode); //where is packet from
|
||||
LT.writeUint16(TXVolts);
|
||||
len = LT.endWriteSXBuffer();
|
||||
|
||||
digitalWrite(LED1, HIGH);
|
||||
SendOK = LT.transmitSXBuffer(0, len, 10000, TXpower, WAIT_TX); //timeout set at 10 seconds
|
||||
digitalWrite(LED1, LOW);
|
||||
|
||||
if (SendOK)
|
||||
{
|
||||
Serial.println(F(" - Done"));
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println(F(" - Error"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint16_t readSupplyVoltage()
|
||||
{
|
||||
//relies on 1V internal reference and 91K & 11K resistor divider
|
||||
//returns supply in mV @ 10mV per AD bit read
|
||||
uint16_t temp;
|
||||
uint16_t voltage = 0;
|
||||
uint8_t index;
|
||||
|
||||
if (BATVREADON >= 0)
|
||||
{
|
||||
digitalWrite(BATVREADON, HIGH); //turn on MOSFET connecting resitor divider in circuit
|
||||
}
|
||||
|
||||
analogReference(INTERNAL);
|
||||
temp = analogRead(SupplyAD);
|
||||
|
||||
for (index = 0; index <= 4; index++) //sample AD 5 times
|
||||
{
|
||||
temp = analogRead(SupplyAD);
|
||||
voltage = voltage + temp;
|
||||
}
|
||||
|
||||
if (BATVREADON >= 0)
|
||||
{
|
||||
digitalWrite(BATVREADON, LOW); //turn off MOSFET connecting resitor divider in circuit
|
||||
}
|
||||
|
||||
|
||||
voltage = ((voltage / 5) * ADMultiplier) + DIODEMV;
|
||||
return voltage;
|
||||
}
|
||||
|
||||
|
||||
void GPSON()
|
||||
{
|
||||
if (GPSPOWER >= 0)
|
||||
{
|
||||
digitalWrite(GPSPOWER, GPSONSTATE); //power up GPS
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void GPSOFF()
|
||||
{
|
||||
if (GPSPOWER)
|
||||
{
|
||||
digitalWrite(GPSPOWER, GPSOFFSTATE); //power off GPS
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
uint32_t endmS;
|
||||
|
||||
if (GPSPOWER >= 0)
|
||||
{
|
||||
pinMode(GPSPOWER, OUTPUT);
|
||||
GPSON();
|
||||
}
|
||||
|
||||
if (BATVREADON >= 0)
|
||||
{
|
||||
pinMode(BATVREADON, OUTPUT);
|
||||
}
|
||||
|
||||
pinMode(LED1, OUTPUT); //setup pin as output for indicator LED
|
||||
led_Flash(2, 125); //two quick LED flashes to indicate program start
|
||||
|
||||
Serial.begin(9600);
|
||||
Serial.println();
|
||||
|
||||
Serial.println(F("23_GPS_Tracker_Transmitter Starting"));
|
||||
|
||||
SPI.begin();
|
||||
|
||||
if (LT.begin(NSS, NRESET, RFBUSY, DIO1, LORA_DEVICE))
|
||||
{
|
||||
Serial.println(F("LoRa Device found"));
|
||||
led_Flash(2, 125);
|
||||
delay(1000);
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println(F("No device responding"));
|
||||
while (1)
|
||||
{
|
||||
led_Flash(50, 50); //long fast speed flash indicates device error
|
||||
}
|
||||
}
|
||||
|
||||
LT.setupLoRa(Frequency, Offset, SpreadingFactor, Bandwidth, CodeRate);
|
||||
|
||||
Serial.println();
|
||||
LT.printModemSettings(); //reads and prints the configured LoRa settings, useful check
|
||||
Serial.println();
|
||||
LT.printOperatingSettings(); //reads and prints the configured operating settings, useful check
|
||||
Serial.println();
|
||||
|
||||
TXVolts = readSupplyVoltage();
|
||||
|
||||
Serial.print(F("Supply "));
|
||||
Serial.print(TXVolts);
|
||||
Serial.println(F("mV"));
|
||||
|
||||
send_Command(PowerUp); //send power up command, includes supply mV
|
||||
|
||||
Serial.println(F("Startup GPS check"));
|
||||
|
||||
GPSserial.begin(9600);
|
||||
|
||||
endmS = millis() + echomS;
|
||||
|
||||
while (millis() < endmS)
|
||||
{
|
||||
while (GPSserial.available() > 0)
|
||||
Serial.write(GPSserial.read());
|
||||
}
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
|
||||
Serial.println(F("Wait for first GPS fix"));
|
||||
gpsWaitFix(WaitFirstGPSFixSeconds);
|
||||
|
||||
sendLocation(TXLat, TXLon, TXAlt, TXHdop, TXGPSFixTime);
|
||||
}
|
||||
@ -0,0 +1,63 @@
|
||||
/*******************************************************************************************************
|
||||
Programs for Arduino - Copyright of the author Stuart Robinson - 16/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 my own boards, the Easy Pro Mini,
|
||||
//be sure to change the definitions to match your own setup.
|
||||
|
||||
#define NSS 10 //select on LoRa device
|
||||
#define NRESET 9 //reset on LoRa device
|
||||
#define RFBUSY 7 //SX128X busy pin
|
||||
#define DIO1 3 //DIO1 on LoRa device, used for RX and TX done
|
||||
|
||||
#define GPSPOWER 4 //Pin that controls power to GPS, set to -1 if not used
|
||||
#define GPSONSTATE HIGH //logic level to turn GPS on via pin GPSPOWER
|
||||
#define GPSOFFSTATE LOW //logic level to turn GPS off via pin GPSPOWER
|
||||
|
||||
#define RXpin A3 //pin number for GPS RX input into Arduino - TX from GPS
|
||||
#define TXpin A2 //pin number for GPS TX output from Arduino- RX into GPS
|
||||
|
||||
#define LED1 8 //On board LED, high for on
|
||||
#define SupplyAD A7 //pin for reading supply\battery voltage
|
||||
#define BATVREADON 8 //turns on battery resistor divider, high for on, -1 if not used
|
||||
|
||||
const float ADMultiplier = 10.0; //multiplier for supply volts calculation
|
||||
#define DIODEMV 98 //mV voltage drop accross diode at approx 8mA
|
||||
|
||||
|
||||
#define LORA_DEVICE DEVICE_SX1280 //we need to define the device we are using
|
||||
|
||||
|
||||
|
||||
//******* Setup LoRa 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_0200; //LoRa bandwidth
|
||||
const uint8_t SpreadingFactor = LORA_SF12; //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 ThisNode '2' //a character that identifies this tracker
|
||||
|
||||
//**************************************************************************************************
|
||||
// GPS Settings
|
||||
//**************************************************************************************************
|
||||
|
||||
#define USE_SOFTSERIAL_GPS //need to include this if we are using softserial for GPS
|
||||
//#define HardwareSerialPort Serial1 //if using hardware serial enable this define for hardware serial port
|
||||
|
||||
#define GPSBaud 9600 //GPS Baud rate
|
||||
|
||||
#define WaitGPSFixSeconds 30 //time in seconds to wait for a new GPS fix
|
||||
#define WaitFirstGPSFixSeconds 1800 //time to seconds to wait for the first GPS fix at startup
|
||||
#define Sleepsecs 5 //seconds between transmissions, this delay is used to set overall transmission cycle time
|
||||
|
||||
#define echomS 2000 //number of mS to run GPS echo at startup
|
||||
@ -0,0 +1,313 @@
|
||||
/*******************************************************************************************************
|
||||
Programs for Arduino - Copyright of the author Stuart Robinson - 22/03/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 - This program is an basic receiver for the '23_Simple_GPS_Tracker_Transmitter' program.
|
||||
The program reads the received packet from the tracker transmitter and displays the results on
|
||||
the serial monitor. The LoRa and frequency settings provided in the Settings.h file must
|
||||
match those used by the transmitter.
|
||||
|
||||
The program receives direct from the LoRa devices internal buffer.
|
||||
|
||||
Serial monitor baud rate is set at 9600.
|
||||
*******************************************************************************************************/
|
||||
|
||||
#include <SPI.h>
|
||||
#include <SX128XLT.h>
|
||||
|
||||
SX128XLT LT;
|
||||
|
||||
#include "Settings.h"
|
||||
#include <ProgramLT_Definitions.h>
|
||||
|
||||
|
||||
uint32_t RXpacketCount; //count of received packets
|
||||
|
||||
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 PacketType; //for packet addressing, identifies packet type
|
||||
uint8_t Destination; //for packet addressing, identifies the destination (receiving) node
|
||||
uint8_t Source; //for packet addressing, identifies the source (transmiting) node
|
||||
uint8_t TXStatus; //A status byte
|
||||
float TXLat; //latitude
|
||||
float TXLon; //longitude
|
||||
float TXAlt; //altitude
|
||||
uint32_t TXHdop; //HDOP, indication of fix quality, horizontal dilution of precision, low is good
|
||||
uint32_t TXGPSFixTime; //time in mS for fix
|
||||
uint16_t TXVolts; //supply\battery voltage
|
||||
uint8_t TXSats; //number of sattelites in use
|
||||
uint32_t TXupTimemS; //up time of TX in mS
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
RXPacketL = LT.receiveSXBuffer(0, 0, WAIT_RX); //returns 0 if packet error of some sort
|
||||
|
||||
digitalWrite(LED1, HIGH);
|
||||
|
||||
if (BUZZER > 0)
|
||||
{
|
||||
digitalWrite(BUZZER, HIGH);
|
||||
}
|
||||
|
||||
PacketRSSI = LT.readPacketRSSI();
|
||||
PacketSNR = LT.readPacketSNR();
|
||||
|
||||
if (RXPacketL == 0)
|
||||
{
|
||||
packet_is_Error();
|
||||
}
|
||||
else
|
||||
{
|
||||
packet_is_OK();
|
||||
}
|
||||
|
||||
digitalWrite(LED1, LOW);
|
||||
|
||||
if (BUZZER > 0)
|
||||
{
|
||||
digitalWrite(BUZZER, LOW);
|
||||
}
|
||||
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
|
||||
void readPacketAddressing()
|
||||
{
|
||||
//the transmitter is using packet addressing, so read in the details
|
||||
LT.startReadSXBuffer(0);
|
||||
PacketType = LT.readUint8();
|
||||
Destination = LT.readUint8();
|
||||
Source = LT.readUint8();
|
||||
LT.endReadSXBuffer();
|
||||
}
|
||||
|
||||
|
||||
void packet_is_OK()
|
||||
{
|
||||
float tempHdop;
|
||||
|
||||
RXpacketCount++;
|
||||
Serial.print(F("Packet OK > "));
|
||||
|
||||
readPacketAddressing();
|
||||
|
||||
if (PacketType == PowerUp)
|
||||
{
|
||||
LT.startReadSXBuffer(0);
|
||||
LT.readUint8(); //read byte from FIFO, not used
|
||||
LT.readUint8(); //read byte from FIFO, not used
|
||||
LT.readUint8(); //read byte from FIFO, not used
|
||||
TXVolts = LT.readUint16();
|
||||
LT.endReadSXBuffer();
|
||||
Serial.print(F("Tracker transmitter powerup - battery "));
|
||||
Serial.print(TXVolts);
|
||||
Serial.print(F("mV"));
|
||||
}
|
||||
|
||||
|
||||
if (PacketType == LocationPacket)
|
||||
{
|
||||
//packet has been received, now read from the SX12XX FIFO in the correct order.
|
||||
Serial.print(F("LocationPacket "));
|
||||
LT.startReadSXBuffer(0);
|
||||
PacketType = LT.readUint8();
|
||||
Destination = LT.readUint8();
|
||||
Source = LT.readUint8();
|
||||
TXLat = LT.readFloat();
|
||||
TXLon = LT.readFloat();
|
||||
TXAlt = LT.readFloat();
|
||||
TXSats = LT.readUint8();
|
||||
TXHdop = LT.readUint32();
|
||||
TXStatus = LT.readUint8();
|
||||
TXGPSFixTime = LT.readUint32();
|
||||
TXVolts = LT.readUint16();
|
||||
TXupTimemS = LT.readUint32();
|
||||
RXPacketL = LT.endReadSXBuffer();
|
||||
|
||||
tempHdop = ( (float) TXHdop / 100); //need to convert Hdop read from GPS as uint32_t to a float for display
|
||||
|
||||
Serial.write(PacketType);
|
||||
Serial.write(Destination);
|
||||
Serial.write(Source);
|
||||
Serial.print(F(","));
|
||||
Serial.print(TXLat, 5);
|
||||
Serial.print(F(","));
|
||||
Serial.print(TXLon, 5);
|
||||
Serial.print(F(","));
|
||||
Serial.print(TXAlt, 1);
|
||||
Serial.print(F("m,"));
|
||||
Serial.print(TXSats);
|
||||
Serial.print(F(","));
|
||||
Serial.print(tempHdop, 2);
|
||||
Serial.print(F(","));
|
||||
Serial.print(TXStatus);
|
||||
Serial.print(F(","));
|
||||
Serial.print(TXGPSFixTime);
|
||||
Serial.print(F("mS,"));
|
||||
Serial.print(TXVolts);
|
||||
Serial.print(F("mV,"));
|
||||
Serial.print((TXupTimemS / 1000));
|
||||
Serial.print(F("s,"));
|
||||
printpacketDetails();
|
||||
return;
|
||||
}
|
||||
|
||||
if (PacketType == LocationBinaryPacket)
|
||||
{
|
||||
//packet from locator has been received, now read from the SX12XX FIFO in the correct order.
|
||||
Serial.print(F("LocationBinaryPacket "));
|
||||
LT.startReadSXBuffer(0);
|
||||
PacketType = LT.readUint8();
|
||||
Destination = LT.readUint8();
|
||||
Source = LT.readUint8();
|
||||
TXLat = LT.readFloat();
|
||||
TXLon = LT.readFloat();
|
||||
TXAlt = LT.readInt16();
|
||||
TXStatus = LT.readUint8();
|
||||
RXPacketL = LT.endReadSXBuffer();
|
||||
|
||||
tempHdop = ( (float) TXHdop / 100); //need to convert Hdop read from GPS as uint32_t to a float for display
|
||||
|
||||
Serial.write(PacketType);
|
||||
Serial.write(Destination);
|
||||
Serial.write(Source);
|
||||
Serial.print(F(","));
|
||||
Serial.print(TXLat, 5);
|
||||
Serial.print(F(","));
|
||||
Serial.print(TXLon, 5);
|
||||
Serial.print(F(","));
|
||||
Serial.print(TXAlt, 0);
|
||||
Serial.print(F("m,"));
|
||||
Serial.print(TXStatus);
|
||||
printpacketDetails();
|
||||
return;
|
||||
}
|
||||
|
||||
if (PacketType == NoFix)
|
||||
{
|
||||
Serial.print(F("No Tracker GPS fix "));
|
||||
printpacketDetails();
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void printpacketDetails()
|
||||
{
|
||||
uint16_t IRQStatus;
|
||||
Serial.print(F(",RSSI,"));
|
||||
Serial.print(PacketRSSI);
|
||||
Serial.print(F("dBm,SNR,"));
|
||||
Serial.print(PacketSNR);
|
||||
Serial.print(F("dB,Packets,"));
|
||||
Serial.print(RXpacketCount);
|
||||
|
||||
Serial.print(F(",Length,"));
|
||||
Serial.print(RXPacketL);
|
||||
IRQStatus = LT.readIrqStatus();
|
||||
Serial.print(F(",IRQreg,"));
|
||||
Serial.print(IRQStatus, HEX);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void packet_is_Error()
|
||||
{
|
||||
uint16_t IRQStatus;
|
||||
|
||||
if (BUZZER > 0)
|
||||
{
|
||||
digitalWrite(BUZZER, LOW);
|
||||
delay(100);
|
||||
digitalWrite(BUZZER, HIGH);
|
||||
}
|
||||
|
||||
IRQStatus = LT.readIrqStatus(); //get the IRQ status
|
||||
Serial.print(F("PacketError,RSSI"));
|
||||
Serial.print(PacketRSSI);
|
||||
Serial.print(F("dBm,SNR,"));
|
||||
Serial.print(PacketSNR);
|
||||
|
||||
Serial.print(F("dB,Length,"));
|
||||
Serial.print(LT.readRXPacketL()); //get the real packet length
|
||||
Serial.print(F(",IRQreg,"));
|
||||
Serial.print(IRQStatus, HEX);
|
||||
LT.printIrqStatus();
|
||||
digitalWrite(LED1, LOW);
|
||||
|
||||
if (BUZZER > 0)
|
||||
{
|
||||
digitalWrite(BUZZER, LOW);
|
||||
delay(100);
|
||||
digitalWrite(BUZZER, HIGH);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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); //setup pin as output for indicator LED
|
||||
led_Flash(2, 125); //two quick LED flashes to indicate program start
|
||||
|
||||
Serial.begin(9600);
|
||||
Serial.println();
|
||||
|
||||
Serial.println(F("24_GPS_Tracker_Receiver Starting"));
|
||||
|
||||
if (BUZZER >= 0)
|
||||
{
|
||||
pinMode(BUZZER, OUTPUT);
|
||||
Serial.println(F("BUZZER Enabled"));
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println(F("BUZZER Not Enabled"));
|
||||
}
|
||||
|
||||
SPI.begin();
|
||||
|
||||
if (LT.begin(NSS, NRESET, RFBUSY, DIO1, LORA_DEVICE))
|
||||
{
|
||||
Serial.println(F("LoRa device found"));
|
||||
led_Flash(2, 125);
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println(F("No device responding"));
|
||||
while (1)
|
||||
{
|
||||
led_Flash(50, 50); //long fast speed flash indicates device error
|
||||
}
|
||||
}
|
||||
|
||||
LT.setupLoRa(Frequency, Offset, SpreadingFactor, Bandwidth, CodeRate);
|
||||
|
||||
Serial.println();
|
||||
LT.printModemSettings(); //reads and prints the configured LoRa settings, useful check
|
||||
Serial.println();
|
||||
|
||||
Serial.println(F("Receiver ready"));
|
||||
Serial.println();
|
||||
}
|
||||
@ -0,0 +1,37 @@
|
||||
/*******************************************************************************************************
|
||||
Programs for Arduino - Copyright of the author Stuart Robinson - 22/03/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 -
|
||||
|
||||
Serial monitor baud rate is set at 9600.
|
||||
*******************************************************************************************************/
|
||||
|
||||
//******* 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 //select on LoRa device
|
||||
#define NRESET 9 //reset on LoRa device
|
||||
#define RFBUSY 7 //SX128X busy pin
|
||||
#define DIO1 3 //DIO1 on LoRa device, used for RX and TX done
|
||||
|
||||
#define LED1 8 //On board LED, high for on
|
||||
|
||||
#define BUZZER -1 //Buzzer if fitted, high for on. Set to -1 if not used
|
||||
|
||||
#define LORA_DEVICE DEVICE_SX1280 //this is 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_0200; //LoRa bandwidth
|
||||
const uint8_t SpreadingFactor = LORA_SF12; //LoRa spreading factor
|
||||
const uint8_t CodeRate = LORA_CR_4_5; //LoRa coding rate
|
||||
@ -0,0 +1,613 @@
|
||||
/*******************************************************************************************************
|
||||
Programs for Arduino - Copyright of the author Stuart Robinson - 21/03/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 - This program is an example of a functional GPS tracker receiver using lora.
|
||||
It is capable of picking up the trackers location packets from many kilometres away with only basic antennas.
|
||||
|
||||
The program receives the location packets from the remote tracker transmitter and writes them on an OLED
|
||||
display and also prints the information to the Arduino IDE serial monitor. The program can read a locally
|
||||
attached GPS and when that has a fix, will display the distance and direction to the remote tracker.
|
||||
|
||||
The program writes direct to the lora devices internal buffer, no memory buffer is used. The lora settings
|
||||
are configured in the Settings.h file.
|
||||
|
||||
The receiver recognises two types of tracker packet, the one from the matching program '23_GPS_Tracker_Transmitter'
|
||||
(LocationPacket, 27 bytes) which causes these fields to be printed to the serial monitor;
|
||||
|
||||
Latitude, Longitude, Altitude, Satellites, HDOP, TrackerStatusByte, GPS Fixtime, Battery mV, Distance, Direction,
|
||||
Distance, Direction, PacketRSSI, PacketSNR, NumberPackets, PacketLength, IRQRegister.
|
||||
|
||||
This is a long packet which at the long range LoRa settings takes just over 3 seconds to transmit.
|
||||
|
||||
The receiver also recognises a much shorter location only packet (LocationBinaryPacket, 11 bytes) and when
|
||||
received this is printed to the serial monitor;
|
||||
|
||||
Latitude, Longitude, Altitude, TrackerStatusByte, Distance, Direction, PacketRSSI, PacketSNR, NumberPackets,
|
||||
PacketLength, IRQRegister.
|
||||
|
||||
Most of the tracker information (for both types of packet) is shown on the OLED display. If there has been a
|
||||
tracker transmitter GPS fix the number\identifier of that tracker is shown on row 0 right of screen and if there
|
||||
is a recent local (receiver) GPS fix an 'R' is displayed row 1 right of screen.
|
||||
|
||||
When the tracker transmitter starts up or is reset its sends a power up message containing the battery voltage
|
||||
which is shown on the OLED and printer to the serial monitor.
|
||||
|
||||
The program has the option of using a pin to control the power to the GPS, if the GPS module being used has this
|
||||
feature. To use the option change the define in Settings.h;
|
||||
|
||||
'#define GPSPOWER -1' from -1 to the pin number being used. Also set the GPSONSTATE and GPSOFFSTATE defines to
|
||||
the appropriate logic levels.
|
||||
|
||||
The program by default uses software serial to read the GPS, you can use hardware serial by commenting out this
|
||||
line in the Settings.h file;
|
||||
|
||||
#define USE_SOFTSERIAL_GPS
|
||||
|
||||
And then defining the hardware serial port you are using, which defaults to Serial1.
|
||||
|
||||
Serial monitor baud rate is set at 9600.
|
||||
*******************************************************************************************************/
|
||||
|
||||
#include <SPI.h>
|
||||
#include <SX128XLT.h>
|
||||
SX128XLT LT;
|
||||
|
||||
#include "Settings.h"
|
||||
#include <ProgramLT_Definitions.h>
|
||||
|
||||
#include <U8x8lib.h> //https://github.com/olikraus/u8g2
|
||||
U8X8_SSD1306_128X64_NONAME_HW_I2C disp(U8X8_PIN_NONE); //standard 0.96" SSD1306
|
||||
//U8X8_SH1106_128X64_NONAME_HW_I2C disp(U8X8_PIN_NONE); //1.3" OLED often sold as 1.3" SSD1306
|
||||
|
||||
|
||||
#include <TinyGPS++.h> //http://arduiniana.org/libraries/tinygpsplus/
|
||||
TinyGPSPlus gps; //create the TinyGPS++ object
|
||||
|
||||
#ifdef USE_SOFTSERIAL_GPS
|
||||
#include <SoftwareSerial.h>
|
||||
SoftwareSerial GPSserial(RXpin, TXpin);
|
||||
#else
|
||||
#define GPSserial HardwareSerialPort //hardware serial port (eg Serial1) is configured in the Settings.h file
|
||||
#endif
|
||||
|
||||
uint32_t RXpacketCount; //count of received packets
|
||||
uint8_t RXPacketL; //length of received packet
|
||||
int16_t PacketRSSI; //signal strength (RSSI) dBm of received packet
|
||||
int8_t PacketSNR; //signal to noise ratio (SNR) dB of received packet
|
||||
uint8_t PacketType; //for packet addressing, identifies packet type
|
||||
uint8_t Destination; //for packet addressing, identifies the destination (receiving) node
|
||||
uint8_t Source; //for packet addressing, identifies the source (transmiting) node
|
||||
uint8_t TXStatus; //status byte from tracker transmitter
|
||||
uint8_t TXSats; //number of sattelites in use
|
||||
float TXLat; //latitude
|
||||
float TXLon; //longitude
|
||||
float TXAlt; //altitude
|
||||
float RXLat; //latitude
|
||||
float RXLon; //longitude
|
||||
float RXAlt; //altitude
|
||||
uint32_t TXHdop; //HDOP, indication of fix quality, horizontal dilution of precision, low is good
|
||||
uint32_t TXGPSFixTime; //time in mS for fix
|
||||
uint16_t TXVolts; //supply\battery voltage
|
||||
uint16_t RXVolts; //supply\battery voltage
|
||||
float TXdistance; //calculated distance to tracker
|
||||
uint16_t TXdirection; //calculated direction to tracker
|
||||
uint16_t RXerrors;
|
||||
uint32_t TXupTimemS; //up time of TX in mS
|
||||
|
||||
uint32_t LastRXGPSfixCheck; //used to record the time of the last GPS fix
|
||||
|
||||
bool TXLocation = false; //set to true when at least one tracker location packet has been received
|
||||
bool RXGPSfix = false; //set to true if the local GPS has a recent fix
|
||||
|
||||
uint8_t FixCount = DisplayRate; //used to keep track of number of GPS fixes before display updated
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
RXPacketL = LT.receiveSXBuffer(0, 0, NO_WAIT); //returns 0 if packet error of some sort
|
||||
|
||||
while (!digitalRead(DIO1))
|
||||
{
|
||||
readGPS(); //If the DIO pin is low, no packet arrived, so read the GPS
|
||||
}
|
||||
|
||||
//something has happened in receiver
|
||||
digitalWrite(LED1, HIGH);
|
||||
|
||||
if (BUZZER > 0)
|
||||
{
|
||||
digitalWrite(BUZZER, HIGH);
|
||||
}
|
||||
|
||||
RXPacketL = LT.readRXPacketL();
|
||||
PacketRSSI = LT.readPacketRSSI();
|
||||
PacketSNR = LT.readPacketSNR();
|
||||
|
||||
|
||||
if (RXPacketL == 0)
|
||||
{
|
||||
packet_is_Error();
|
||||
}
|
||||
else
|
||||
{
|
||||
packet_is_OK();
|
||||
}
|
||||
|
||||
digitalWrite(LED1, LOW);
|
||||
|
||||
if (BUZZER > 0)
|
||||
{
|
||||
digitalWrite(BUZZER, LOW);
|
||||
}
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
|
||||
void readGPS()
|
||||
{
|
||||
if (GPSserial.available() > 0)
|
||||
{
|
||||
gps.encode(GPSserial.read());
|
||||
}
|
||||
|
||||
|
||||
if ( millis() > (LastRXGPSfixCheck + NoRXGPSfixms))
|
||||
{
|
||||
RXGPSfix = false;
|
||||
LastRXGPSfixCheck = millis();
|
||||
dispscreen1();
|
||||
}
|
||||
|
||||
|
||||
if (gps.location.isUpdated() && gps.altitude.isUpdated())
|
||||
{
|
||||
RXGPSfix = true;
|
||||
RXLat = gps.location.lat();
|
||||
RXLon = gps.location.lng();
|
||||
RXAlt = gps.altitude.meters();
|
||||
printRXLocation();
|
||||
LastRXGPSfixCheck = millis();
|
||||
|
||||
if ( FixCount == 1) //update screen when FIXcoount counts down from DisplayRate to 1
|
||||
{
|
||||
FixCount = DisplayRate;
|
||||
dispscreen1();
|
||||
}
|
||||
FixCount--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool readTXStatus(byte bitnum)
|
||||
{
|
||||
return bitRead(TXStatus, bitnum);
|
||||
}
|
||||
|
||||
|
||||
void printRXLocation()
|
||||
{
|
||||
Serial.print(F("LocalGPS "));
|
||||
Serial.print(RXLat, 5);
|
||||
Serial.print(F(","));
|
||||
Serial.print(RXLon, 5);
|
||||
Serial.print(F(","));
|
||||
Serial.print(RXAlt, 1);
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
|
||||
void readPacketAddressing()
|
||||
{
|
||||
LT.startReadSXBuffer(0);
|
||||
PacketType = LT.readUint8();
|
||||
Destination = LT.readUint8();
|
||||
Source = LT.readUint8();
|
||||
LT.endReadSXBuffer();
|
||||
}
|
||||
|
||||
|
||||
void packet_is_OK()
|
||||
{
|
||||
//uint16_t IRQStatus;
|
||||
float tempfloat;
|
||||
|
||||
RXpacketCount++;
|
||||
|
||||
readPacketAddressing();
|
||||
|
||||
if (PacketType == PowerUp)
|
||||
{
|
||||
LT.startReadSXBuffer(0);
|
||||
LT.readUint8(); //read byte from SXBuffer, not used
|
||||
LT.readUint8(); //read byte from SXBuffer, not used
|
||||
LT.readUint8(); //read byte from SXBuffer, not used
|
||||
TXVolts = LT.readUint16(); //read tracker transmitter voltage
|
||||
LT.endReadSXBuffer();
|
||||
Serial.print(F("Tracker Powerup - Battery "));
|
||||
Serial.print(TXVolts);
|
||||
Serial.println(F("mV"));
|
||||
dispscreen2();
|
||||
}
|
||||
|
||||
if (PacketType == LocationPacket)
|
||||
{
|
||||
//packet has been received, now read from the SX12XX FIFO in the correct order.
|
||||
Serial.print(F("LocationPacket "));
|
||||
TXLocation = true;
|
||||
LT.startReadSXBuffer(0); //start the read of received packet
|
||||
PacketType = LT.readUint8(); //read in the PacketType
|
||||
Destination = LT.readUint8(); //read in the Packet destination address
|
||||
Source = LT.readUint8(); //read in the Packet source address
|
||||
TXLat = LT.readFloat(); //read in the tracker latitude
|
||||
TXLon = LT.readFloat(); //read in the tracker longitude
|
||||
TXAlt = LT.readFloat(); //read in the tracker altitude
|
||||
TXSats = LT.readUint8(); //read in the satellites in use by tracker GPS
|
||||
TXHdop = LT.readUint32(); //read in the HDOP of tracker GPS
|
||||
TXStatus = LT.readUint8(); //read in the tracker status byte
|
||||
TXGPSFixTime = LT.readUint32(); //read in the last fix time of tracker GPS
|
||||
TXVolts = LT.readUint16(); //read in the tracker supply\battery volts
|
||||
TXupTimemS = LT.readUint32(); //read in the TX uptime in mS
|
||||
RXPacketL = LT.endReadSXBuffer(); //end the read of received packet
|
||||
|
||||
|
||||
if (RXGPSfix) //if there has been a local GPS fix do the distance and direction calculation
|
||||
{
|
||||
TXdirection = (int16_t) TinyGPSPlus::courseTo(RXLat, RXLon, TXLat, TXLon);
|
||||
TXdistance = TinyGPSPlus::distanceBetween(RXLat, RXLon, TXLat, TXLon);
|
||||
}
|
||||
else
|
||||
{
|
||||
TXdistance = 0;
|
||||
TXdirection = 0;
|
||||
}
|
||||
|
||||
Serial.write(PacketType);
|
||||
Serial.write(Destination);
|
||||
Serial.write(Source);
|
||||
Serial.print(F(","));
|
||||
Serial.print(TXLat, 5);
|
||||
Serial.print(F(","));
|
||||
Serial.print(TXLon, 5);
|
||||
Serial.print(F(","));
|
||||
Serial.print(TXAlt, 1);
|
||||
Serial.print(F(","));
|
||||
Serial.print(TXSats);
|
||||
Serial.print(F(","));
|
||||
|
||||
tempfloat = ( (float) TXHdop / 100); //need to convert Hdop read from GPS as uint32_t to a float for display
|
||||
Serial.print(tempfloat, 2);
|
||||
|
||||
Serial.print(F(","));
|
||||
Serial.print(TXStatus);
|
||||
Serial.print(F(","));
|
||||
|
||||
Serial.print(TXGPSFixTime);
|
||||
Serial.print(F("mS,"));
|
||||
Serial.print(TXVolts);
|
||||
Serial.print(F("mV,"));
|
||||
Serial.print((TXupTimemS / 1000));
|
||||
Serial.print(F("s,"));
|
||||
|
||||
Serial.print(TXdistance, 0);
|
||||
Serial.print(F("m,"));
|
||||
Serial.print(TXdirection);
|
||||
Serial.print(F("d"));
|
||||
printpacketDetails();
|
||||
dispscreen1(); //and show the packet detail it on screen
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (PacketType == LocationBinaryPacket)
|
||||
{
|
||||
//packet from locator has been received, now read from the SX12XX FIFO in the correct order.
|
||||
TXLocation = true;
|
||||
Serial.print(F("LocationBinaryPacket "));
|
||||
LT.startReadSXBuffer(0);
|
||||
PacketType = LT.readUint8();
|
||||
Destination = LT.readUint8();
|
||||
Source = LT.readUint8();
|
||||
TXLat = LT.readFloat();
|
||||
TXLon = LT.readFloat();
|
||||
TXAlt = LT.readInt16();
|
||||
TXStatus = LT.readUint8();
|
||||
RXPacketL = LT.endReadSXBuffer();
|
||||
|
||||
if (RXGPSfix) //if there has been a local GPS fix do the distance and direction calculation
|
||||
{
|
||||
TXdirection = (int16_t) TinyGPSPlus::courseTo(RXLat, RXLon, TXLat, TXLon);
|
||||
TXdistance = TinyGPSPlus::distanceBetween(RXLat, RXLon, TXLat, TXLon);
|
||||
}
|
||||
else
|
||||
{
|
||||
TXdistance = 0;
|
||||
TXdirection = 0;
|
||||
}
|
||||
|
||||
Serial.write(PacketType);
|
||||
Serial.write(Destination);
|
||||
Serial.write(Source);
|
||||
Serial.print(F(","));
|
||||
Serial.print(TXLat, 5);
|
||||
Serial.print(F(","));
|
||||
Serial.print(TXLon, 5);
|
||||
Serial.print(F(","));
|
||||
Serial.print(TXAlt, 0);
|
||||
Serial.print(F("m,"));
|
||||
Serial.print(TXStatus);
|
||||
Serial.print(F(","));
|
||||
Serial.print(TXdistance, 0);
|
||||
Serial.print(F("m,"));
|
||||
Serial.print(TXdirection);
|
||||
Serial.print(F("d"));
|
||||
printpacketDetails();
|
||||
dispscreen1();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void printpacketDetails()
|
||||
{
|
||||
uint16_t IRQStatus;
|
||||
Serial.print(F(",RSSI,"));
|
||||
Serial.print(PacketRSSI);
|
||||
Serial.print(F("dBm,SNR,"));
|
||||
Serial.print(PacketSNR);
|
||||
Serial.print(F("dB,Packets,"));
|
||||
Serial.print(RXpacketCount);
|
||||
|
||||
Serial.print(F(",Length,"));
|
||||
Serial.print(RXPacketL);
|
||||
IRQStatus = LT.readIrqStatus();
|
||||
Serial.print(F(",IRQreg,"));
|
||||
Serial.print(IRQStatus, HEX);
|
||||
}
|
||||
|
||||
|
||||
void packet_is_Error()
|
||||
{
|
||||
uint16_t IRQStatus;
|
||||
|
||||
if (BUZZER >= 0)
|
||||
{
|
||||
digitalWrite(BUZZER, LOW);
|
||||
delay(100);
|
||||
digitalWrite(BUZZER, HIGH);
|
||||
}
|
||||
|
||||
IRQStatus = LT.readIrqStatus(); //get the IRQ status
|
||||
RXerrors++;
|
||||
Serial.print(F("PacketError,RSSI"));
|
||||
|
||||
Serial.print(PacketRSSI);
|
||||
Serial.print(F("dBm,SNR,"));
|
||||
Serial.print(PacketSNR);
|
||||
|
||||
Serial.print(F("dB,Length,"));
|
||||
Serial.print(LT.readRXPacketL()); //get the real packet length
|
||||
Serial.print(F(",IRQreg,"));
|
||||
Serial.print(IRQStatus, HEX);
|
||||
LT.printIrqStatus();
|
||||
digitalWrite(LED1, LOW);
|
||||
|
||||
if (BUZZER >= 0)
|
||||
{
|
||||
digitalWrite(BUZZER, LOW);
|
||||
delay(100);
|
||||
digitalWrite(BUZZER, HIGH);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void led_Flash(uint16_t flashes, uint16_t delaymS)
|
||||
{
|
||||
unsigned int index;
|
||||
|
||||
for (index = 1; index <= flashes; index++)
|
||||
{
|
||||
digitalWrite(LED1, HIGH);
|
||||
delay(delaymS);
|
||||
digitalWrite(LED1, LOW);
|
||||
delay(delaymS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void dispscreen1()
|
||||
{
|
||||
//show received packet data on display
|
||||
float tempfloat;
|
||||
disp.clearLine(0);
|
||||
disp.setCursor(0, 0);
|
||||
disp.print(TXLat, 5);
|
||||
disp.clearLine(1);
|
||||
disp.setCursor(0, 1);
|
||||
disp.print(TXLon, 5);
|
||||
disp.clearLine(2);
|
||||
disp.setCursor(0, 2);
|
||||
disp.print(TXAlt, 0);
|
||||
disp.print(F("m"));
|
||||
disp.clearLine(3);
|
||||
disp.setCursor(0, 3);
|
||||
|
||||
disp.print(F("RSSI "));
|
||||
disp.print(PacketRSSI);
|
||||
disp.print(F("dBm"));
|
||||
disp.clearLine(4);
|
||||
disp.setCursor(0, 4);
|
||||
disp.print(F("SNR "));
|
||||
|
||||
if (PacketSNR > 0)
|
||||
{
|
||||
disp.print(F("+"));
|
||||
}
|
||||
|
||||
if (PacketSNR == 0)
|
||||
{
|
||||
disp.print(F(" "));
|
||||
}
|
||||
|
||||
if (PacketSNR < 0)
|
||||
{
|
||||
disp.print(F("-"));
|
||||
}
|
||||
|
||||
disp.print(PacketSNR);
|
||||
disp.print(F("dB"));
|
||||
|
||||
if (PacketType == LocationPacket)
|
||||
{
|
||||
disp.clearLine(5);
|
||||
disp.setCursor(0, 5);
|
||||
tempfloat = ((float) TXVolts / 1000);
|
||||
disp.print(F("Batt "));
|
||||
disp.print(tempfloat, 2);
|
||||
disp.print(F("v"));
|
||||
}
|
||||
|
||||
disp.clearLine(6);
|
||||
disp.setCursor(0, 6);
|
||||
disp.print(F("Packets "));
|
||||
disp.print(RXpacketCount);
|
||||
|
||||
disp.clearLine(7);
|
||||
|
||||
if (RXGPSfix)
|
||||
{
|
||||
disp.setCursor(15, 1);
|
||||
disp.print(F("R"));
|
||||
}
|
||||
else
|
||||
{
|
||||
disp.setCursor(15, 1);
|
||||
disp.print(F(" "));
|
||||
disp.setCursor(0, 7);
|
||||
disp.print(F("No Local Fix"));
|
||||
}
|
||||
|
||||
if (RXGPSfix && TXLocation) //only display distance and direction if have received tracker packet and have local GPS fix
|
||||
{
|
||||
disp.clearLine(7);
|
||||
disp.setCursor(0, 7);
|
||||
disp.print(TXdistance, 0);
|
||||
disp.print(F("m "));
|
||||
disp.print(TXdirection);
|
||||
disp.print(F("d"));
|
||||
}
|
||||
|
||||
if (readTXStatus(GPSFix))
|
||||
{
|
||||
disp.setCursor(15, 0);
|
||||
disp.write(Source);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void dispscreen2()
|
||||
{
|
||||
//show tracker powerup data on display
|
||||
float tempfloat;
|
||||
disp.clear();
|
||||
disp.setCursor(0, 0);
|
||||
disp.print(F("Tracker Powerup"));
|
||||
disp.setCursor(0, 1);
|
||||
disp.print(F("Battery "));
|
||||
tempfloat = ((float) TXVolts / 1000);
|
||||
disp.print(tempfloat, 2);
|
||||
disp.print(F("v"));
|
||||
}
|
||||
|
||||
|
||||
void GPSON()
|
||||
{
|
||||
if (GPSPOWER >= 0)
|
||||
{
|
||||
digitalWrite(GPSPOWER, GPSONSTATE); //power up GPS
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void GPSOFF()
|
||||
{
|
||||
if (GPSPOWER >= 0)
|
||||
{
|
||||
digitalWrite(GPSPOWER, GPSOFFSTATE); //power off GPS
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
uint32_t endmS;
|
||||
|
||||
pinMode(LED1, OUTPUT); //setup pin as output for indicator LED
|
||||
led_Flash(2, 125); //two quick LED flashes to indicate program start
|
||||
|
||||
Serial.begin(9600);
|
||||
Serial.println();
|
||||
|
||||
Serial.println(F("25_GPS_Tracker_Receiver_With_Display_and_GPS Starting"));
|
||||
|
||||
if (BUZZER >= 0)
|
||||
{
|
||||
pinMode(BUZZER, OUTPUT);
|
||||
}
|
||||
|
||||
SPI.begin();
|
||||
|
||||
disp.begin();
|
||||
disp.setFont(u8x8_font_chroma48medium8_r);
|
||||
|
||||
Serial.print(F("Checking LoRa device - ")); //Initialize LoRa
|
||||
disp.setCursor(0, 0);
|
||||
|
||||
if (LT.begin(NSS, NRESET, RFBUSY, DIO1, LORA_DEVICE))
|
||||
{
|
||||
Serial.println(F("Receiver ready"));
|
||||
disp.print(F("Receiver ready"));
|
||||
led_Flash(2, 125);
|
||||
delay(1000);
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println(F("No LoRa device responding"));
|
||||
disp.print(F("No LoRa device"));
|
||||
while (1)
|
||||
{
|
||||
led_Flash(50, 50); //long fast speed flash indicates device error
|
||||
}
|
||||
}
|
||||
|
||||
LT.setupLoRa(Frequency, Offset, SpreadingFactor, Bandwidth, CodeRate);
|
||||
|
||||
Serial.println();
|
||||
Serial.println(F("Startup GPS check"));
|
||||
|
||||
endmS = millis() + echomS;
|
||||
|
||||
//now startup GPS
|
||||
if (GPSPOWER >= 0)
|
||||
{
|
||||
pinMode(GPSPOWER, OUTPUT);
|
||||
}
|
||||
|
||||
GPSON();
|
||||
GPSserial.begin(GPSBaud);
|
||||
|
||||
while (millis() < endmS)
|
||||
{
|
||||
while (GPSserial.available() > 0)
|
||||
Serial.write(GPSserial.read());
|
||||
}
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
|
||||
Serial.println(F("Receiver ready"));
|
||||
Serial.println();
|
||||
}
|
||||
@ -0,0 +1,54 @@
|
||||
/*******************************************************************************************************
|
||||
Programs for Arduino - Copyright of the author Stuart Robinson - 16/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 my own boards, the Easy Pro Mini,
|
||||
//be sure to change the definitions to match your own setup.
|
||||
|
||||
#define NSS 10 //select on LoRa device
|
||||
#define NRESET 9 //reset on LoRa device
|
||||
#define RFBUSY 7 //SX128X busy pin
|
||||
#define DIO1 3 //DIO1 on LoRa device, used for RX and TX done
|
||||
#define LED1 8 //On board LED, high for on
|
||||
|
||||
#define BUZZER -1 //Buzzer if fitted, high for on. Set to -1 if not used
|
||||
|
||||
#define RXpin A3 //pin number for GPS RX input into Arduino - TX from GPS
|
||||
#define TXpin A2 //pin number for GPS TX output from Arduino- RX into GPS
|
||||
|
||||
#define GPSPOWER 4 //Pin that controls power to GPS, set to -1 if not used
|
||||
#define GPSONSTATE HIGH //logic level to turn GPS on via pin GPSPOWER
|
||||
#define GPSOFFSTATE LOW //logic level to turn GPS off via pin GPSPOWER
|
||||
|
||||
#define LORA_DEVICE DEVICE_SX1280 //this is 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_0200; //LoRa bandwidth
|
||||
const uint8_t SpreadingFactor = LORA_SF12; //LoRa spreading factor
|
||||
const uint8_t CodeRate = LORA_CR_4_5; //LoRa coding rate
|
||||
|
||||
//**************************************************************************************************
|
||||
// GPS Settings
|
||||
//**************************************************************************************************
|
||||
|
||||
#define USE_SOFTSERIAL_GPS //need to include this if we are using softserial for GPS
|
||||
//#define HardwareSerialPort Serial1 //if using hardware serial enable this define for hardware serial port
|
||||
|
||||
#define GPSBaud 9600 //GPS Baud rate
|
||||
#define WaitGPSFixSeconds 30 //time to wait for a new GPS fix
|
||||
#define echomS 2000 //number of mS to run GPS echo for at startup
|
||||
|
||||
#define NoRXGPSfixms 15000 //max number of mS to allow before no local fix flagged
|
||||
#define DisplayRate 7 //when working OK the GPS will get a new fix every second or so
|
||||
//this rate defines how often the display should be updated
|
||||
156
examples/SX128x_examples/Tracker/38_lora_Relay/38_lora_Relay.ino
Normal file
156
examples/SX128x_examples/Tracker/38_lora_Relay/38_lora_Relay.ino
Normal file
@ -0,0 +1,156 @@
|
||||
/*******************************************************************************************************
|
||||
Programs for Arduino - Copyright of the author Stuart Robinson - 19/03/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 - This program will receive a LoRa packet and relay (re-transmit) it. The receiving
|
||||
and transmitting can use different frequencies and lora settings, although in this example they are
|
||||
the same. The receiving and transmitting settings are in the 'Settings.h' file. If the relay is located
|
||||
in an advantageous position, for instance on top of a tall tree, building or in an radio controlled model
|
||||
then the range at which trackers or nodes on the ground can be received is considerably increased.
|
||||
In these circumstances the relay may listen at a long range setting using SF12 for example and then
|
||||
re-transmit back to the ground at SF7.
|
||||
|
||||
Serial monitor baud rate is set at 9600.
|
||||
|
||||
*******************************************************************************************************/
|
||||
|
||||
#include <SPI.h>
|
||||
#include <SX128XLT.h>
|
||||
#include "Settings.h"
|
||||
|
||||
SX128XLT LT;
|
||||
|
||||
uint8_t RXPacketL, TXPacketL;
|
||||
int16_t PacketRSSI, PacketSNR;
|
||||
uint16_t RXPacketErrors;
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
LT.setupLoRa(Frequency, Offset, SpreadingFactor, Bandwidth, CodeRate);
|
||||
|
||||
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(); //read the recived RSSI value
|
||||
PacketSNR = LT.readPacketSNR(); //read the received SNR value
|
||||
|
||||
if (RXPacketL == 0) //if the LT.receive() function detects an error, RXpacketL == 0
|
||||
{
|
||||
packet_is_Error();
|
||||
}
|
||||
else
|
||||
{
|
||||
packet_is_OK();
|
||||
}
|
||||
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
|
||||
void packet_is_OK()
|
||||
{
|
||||
//a packet has been received, so change to relay settings and transmit buffer
|
||||
|
||||
Serial.print(F("PacketOK "));
|
||||
printreceptionDetails();
|
||||
delay(packet_delay / 2);
|
||||
digitalWrite(LED1, LOW);
|
||||
delay(packet_delay / 2);
|
||||
|
||||
Serial.print(F(" Retransmit"));
|
||||
LT.setupLoRa(RelayFrequency, RelayOffset, RelaySpreadingFactor, RelayBandwidth, RelayCodeRate);
|
||||
digitalWrite(LED1, HIGH);
|
||||
TXPacketL = LT.transmitSXBuffer(0, RXPacketL, 10000, TXpower, WAIT_TX);
|
||||
Serial.print(F(" - Done"));
|
||||
digitalWrite(LED1, LOW);
|
||||
}
|
||||
|
||||
|
||||
void packet_is_Error()
|
||||
{
|
||||
uint16_t IRQStatus;
|
||||
|
||||
RXPacketErrors++;
|
||||
IRQStatus = LT.readIrqStatus();
|
||||
|
||||
led_Flash(5, 50);
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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 led_Flash(uint16_t flashdelay, uint16_t flashes)
|
||||
{
|
||||
uint16_t index;
|
||||
|
||||
for (index = 1; index <= flashes; index++)
|
||||
{
|
||||
|
||||
delay(flashdelay);
|
||||
digitalWrite(LED1, HIGH);
|
||||
delay(flashdelay);
|
||||
digitalWrite(LED1, LOW);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
pinMode(LED1, OUTPUT);
|
||||
led_Flash(2, 125);
|
||||
|
||||
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 device error
|
||||
}
|
||||
}
|
||||
|
||||
LT.setupLoRa(Frequency, Offset, SpreadingFactor, Bandwidth, CodeRate);
|
||||
Serial.print("ListenSettings,");
|
||||
LT.printModemSettings();
|
||||
Serial.println();
|
||||
LT.setupLoRa(RelayFrequency, RelayOffset, RelaySpreadingFactor, RelayBandwidth, RelayCodeRate);
|
||||
Serial.print("RelaySettings,");
|
||||
LT.printModemSettings();
|
||||
Serial.println();
|
||||
Serial.println("Relay Ready");
|
||||
}
|
||||
43
examples/SX128x_examples/Tracker/38_lora_Relay/Settings.h
Normal file
43
examples/SX128x_examples/Tracker/38_lora_Relay/Settings.h
Normal file
@ -0,0 +1,43 @@
|
||||
/*******************************************************************************************************
|
||||
Programs for Arduino - Copyright of the author Stuart Robinson - 19/03/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 //select on LoRa device
|
||||
#define NRESET 9 //reset on LoRa device
|
||||
#define RFBUSY 7 //SX128X busy pin
|
||||
#define DIO1 3 //DIO1 on LoRa device, used for RX and TX done
|
||||
#define LED1 8 //On board LED, high for on
|
||||
|
||||
#define LORA_DEVICE DEVICE_SX1280 //this is the device we are using
|
||||
|
||||
|
||||
//******* Setup LoRa Test Parameters Here ! ***************
|
||||
|
||||
//LoRa Modem Parameters - relay listens on these 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_0200; //LoRa bandwidth
|
||||
const uint8_t SpreadingFactor = LORA_SF12; //LoRa spreading factor
|
||||
const uint8_t CodeRate = LORA_CR_4_5; //LoRa coding rate
|
||||
|
||||
//LoRa relay re-transmitts on these LoRa Modem Parameters
|
||||
const uint32_t RelayFrequency = 2445000000; //frequency of transmissions
|
||||
const uint32_t RelayOffset = 0; //offset frequency for calibration purposes
|
||||
|
||||
const uint8_t RelayBandwidth = LORA_BW_0400; //LoRa bandwidth
|
||||
const uint8_t RelaySpreadingFactor = LORA_SF7; //LoRa spreading factor
|
||||
const uint8_t RelayCodeRate = LORA_CR_4_5; //LoRa coding rate
|
||||
|
||||
|
||||
const int8_t TXpower = 10; //LoRa TX power in dBm
|
||||
|
||||
#define packet_delay 1000 //mS delay before received packet transmitted
|
||||
Reference in New Issue
Block a user