first commit
@@ -0,0 +1,182 @@
|
||||
/*******************************************************************************************************
|
||||
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 is a program that demonstrates the detailed setup of a LoRa test transmitter.
|
||||
A packet containing ASCII text is sent according to the frequency and LoRa settings specified in the
|
||||
'Settings.h' file. The pins to access the lora device need to be defined in the 'Settings.h' file also.
|
||||
|
||||
The details of the packet sent and any errors are shown on the Arduino IDE Serial Monitor, together with
|
||||
the transmit power used, the packet length and the CRC of the packet. The matching receive program,
|
||||
'104_LoRa_Receiver' can be used to check the packets are being sent correctly, the frequency and LoRa
|
||||
settings (in Settings.h) must be the same for the transmitter and receiver programs. Sample Serial
|
||||
Monitor output;
|
||||
|
||||
10dBm Packet> Hello World 1234567890* BytesSent,23 CRC,DAAB TransmitTime,64mS PacketsSent,2
|
||||
|
||||
Serial monitor baud rate is set at 9600
|
||||
*******************************************************************************************************/
|
||||
|
||||
#define Program_Version "V1.0"
|
||||
|
||||
#include <SPI.h> //the lora device is SPI based so load the SPI library
|
||||
#include <SX128XLT.h> //include the appropriate library
|
||||
#include "Settings.h" //include the setiings file, frequencies, LoRa settings etc
|
||||
|
||||
SX128XLT LT; //create a library class instance called LT
|
||||
|
||||
uint8_t TXPacketL;
|
||||
uint32_t TXPacketCount, startmS, endmS;
|
||||
|
||||
uint8_t buff[] = "Hello World 1234567890";
|
||||
|
||||
void loop()
|
||||
{
|
||||
Serial.print(TXpower); //print the transmit power defined
|
||||
Serial.print(F("dBm "));
|
||||
Serial.print(F("Packet> "));
|
||||
Serial.flush();
|
||||
|
||||
TXPacketL = sizeof(buff); //set TXPacketL to length of array
|
||||
buff[TXPacketL - 1] = '*'; //replace null character at buffer end so its visible on receiver
|
||||
|
||||
LT.printASCIIPacket(buff, TXPacketL); //print the buffer (the sent packet) as ASCII
|
||||
|
||||
digitalWrite(LED1, HIGH);
|
||||
startmS = millis(); //start transmit timer
|
||||
if (LT.transmit(buff, TXPacketL, 10000, TXpower, WAIT_TX)) //will return packet length sent if OK, otherwise 0 if transmit error
|
||||
{
|
||||
endmS = millis(); //packet sent, note end time
|
||||
TXPacketCount++;
|
||||
packet_is_OK();
|
||||
}
|
||||
else
|
||||
{
|
||||
packet_is_Error(); //transmit packet returned 0, there was an error
|
||||
}
|
||||
|
||||
digitalWrite(LED1, LOW);
|
||||
Serial.println();
|
||||
delay(packet_delay); //have a delay between packets
|
||||
}
|
||||
|
||||
|
||||
void packet_is_OK()
|
||||
{
|
||||
//if here packet has been sent OK
|
||||
uint16_t localCRC;
|
||||
|
||||
Serial.print(F(" BytesSent,"));
|
||||
Serial.print(TXPacketL); //print transmitted packet length
|
||||
localCRC = LT.CRCCCITT(buff, TXPacketL, 0xFFFF);
|
||||
Serial.print(F(" CRC,"));
|
||||
Serial.print(localCRC, HEX); //print CRC of transmitted packet
|
||||
Serial.print(F(" TransmitTime,"));
|
||||
Serial.print(endmS - startmS); //print transmit time of packet
|
||||
Serial.print(F("mS"));
|
||||
Serial.print(F(" PacketsSent,"));
|
||||
Serial.print(TXPacketCount); //print total of packets sent OK
|
||||
}
|
||||
|
||||
|
||||
void packet_is_Error()
|
||||
{
|
||||
//if here there was an error transmitting packet
|
||||
uint16_t IRQStatus;
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
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.print(F(__TIME__));
|
||||
Serial.print(F(" "));
|
||||
Serial.println(F(__DATE__));
|
||||
Serial.println(F(Program_Version));
|
||||
Serial.println();
|
||||
Serial.println(F("103_LoRa_Transmitter_Detailed_Setup Starting"));
|
||||
|
||||
SPI.begin();
|
||||
|
||||
//SPI beginTranscation is normally part of library routines, but if it is disabled in library
|
||||
//a single instance is needed here, so uncomment the program line below
|
||||
//SPI.beginTransaction(SPISettings(8000000, MSBFIRST, SPI_MODE0));
|
||||
|
||||
//setup hardware pins used by device, then check if device is found
|
||||
if (LT.begin(NSS, NRESET, RFBUSY, DIO1, DIO2, DIO3, RX_EN, TX_EN, LORA_DEVICE))
|
||||
{
|
||||
Serial.println(F("LoRa Device found"));
|
||||
led_Flash(2, 125); //two further quick LED flashes to indicate device found
|
||||
delay(1000);
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println(F("No device responding"));
|
||||
while (1)
|
||||
{
|
||||
led_Flash(50, 50); //long fast speed LED flash indicates device error
|
||||
}
|
||||
}
|
||||
|
||||
//The function call list below shows the complete setup for the LoRa device using the information defined in the
|
||||
//Settings.h file.
|
||||
//The 'Setup LoRa device' list below can be replaced with a single function call;
|
||||
//LT.setupLoRa(Frequency, Offset, SpreadingFactor, Bandwidth, CodeRate);
|
||||
|
||||
//***************************************************************************************************
|
||||
//Setup LoRa device
|
||||
//***************************************************************************************************
|
||||
LT.setMode(MODE_STDBY_RC);
|
||||
LT.setRegulatorMode(USE_LDO);
|
||||
LT.setPacketType(PACKET_TYPE_LORA);
|
||||
LT.setRfFrequency(Frequency, Offset);
|
||||
LT.setBufferBaseAddress(0, 0);
|
||||
LT.setModulationParams(SpreadingFactor, Bandwidth, CodeRate);
|
||||
LT.setPacketParams(12, LORA_PACKET_VARIABLE_LENGTH, 255, LORA_CRC_ON, LORA_IQ_NORMAL, 0, 0);
|
||||
LT.setDioIrqParams(IRQ_RADIO_ALL, (IRQ_TX_DONE + IRQ_RX_TX_TIMEOUT), 0, 0);
|
||||
//***************************************************************************************************
|
||||
|
||||
|
||||
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();
|
||||
Serial.println();
|
||||
LT.printRegisters(0x900, 0x9FF); //print contents of device registers, normally 0x900 to 0x9FF
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
|
||||
Serial.print(F("Transmitter ready"));
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
/*******************************************************************************************************
|
||||
Programs for Arduino - Copyright of the author Stuart Robinson - 02/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. Some pins such as DIO2,
|
||||
//DIO3, BUZZER are not used by this sketch so they do not need to be connected and
|
||||
//should be set to -1.
|
||||
|
||||
#define NSS 10
|
||||
#define RFBUSY 7
|
||||
#define NRESET 9
|
||||
#define LED1 8
|
||||
#define DIO1 3
|
||||
#define DIO2 -1 //not used
|
||||
#define DIO3 -1 //not used
|
||||
#define RX_EN -1 //pin for RX enable, used on some SX1280 devices, set to -1 if not used
|
||||
#define TX_EN -1 //pin for TX enable, used on some SX1280 devices, set to -1 if not used
|
||||
|
||||
#define BUZZER -1 //connect a buzzer here if wanted
|
||||
|
||||
#define LORA_DEVICE DEVICE_SX1280 //we need to define the device we are using
|
||||
|
||||
|
||||
//******* Setup LoRa Parameters Here ! ***************
|
||||
|
||||
//LoRa Modem Parameters
|
||||
#define Frequency 2445000000 //frequency of transmissions
|
||||
#define Offset 0 //offset frequency for calibration purposes
|
||||
#define Bandwidth LORA_BW_0400 //LoRa bandwidth
|
||||
#define SpreadingFactor LORA_SF7 //LoRa spreading factor
|
||||
#define CodeRate LORA_CR_4_5 //LoRa coding rate
|
||||
|
||||
const int8_t TXpower = 10; //LoRa transmit power in dBm
|
||||
|
||||
const uint16_t packet_delay = 1000; //mS delay between packets
|
||||
|
||||
@@ -0,0 +1,247 @@
|
||||
/*******************************************************************************************************
|
||||
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 is a program that demonstrates the detailed setup of a LoRa test receiver.
|
||||
The program listens for incoming packets using the lora settings in the 'Settings.h' file. The pins
|
||||
to access the lora device need to be defined in the 'Settings.h' file also.
|
||||
|
||||
There is a printout on the Arduino IDE Serial Monitor of the valid packets received, the packet is
|
||||
assumed to be in ASCII printable text, if it's not ASCII text characters from 0x20 to 0x7F, expect
|
||||
weird things to happen on the Serial Monitor. The LED will flash for each packet received and the
|
||||
buzzer will sound, if fitted.
|
||||
|
||||
Sample serial monitor output;
|
||||
|
||||
7s Hello World 1234567890*,CRC,DAAB,RSSI,-52dBm,SNR,9dB,Length,23,Packets,5,Errors,0,IRQreg,50
|
||||
|
||||
If there is a packet error it might look like this, which is showing a CRC error,
|
||||
|
||||
968s PacketError,RSSI,-87dBm,SNR,-11dB,Length,23,Packets,613,Errors,2,IRQreg,70,IRQ_HEADER_VALID,IRQ_CRC_ERROR,IRQ_RX_DONE
|
||||
|
||||
Serial monitor baud rate is set at 9600.
|
||||
*******************************************************************************************************/
|
||||
|
||||
#define Program_Version "V1.0"
|
||||
|
||||
#include <SPI.h> //the lora device is SPI based so load the SPI library
|
||||
#include <SX128XLT.h> //include the appropriate library
|
||||
#include "Settings.h" //include the setiings file, frequencies, LoRa settings etc
|
||||
|
||||
SX128XLT LT; //create a library class instance called LT
|
||||
|
||||
uint32_t RXpacketCount;
|
||||
uint32_t errors;
|
||||
|
||||
uint8_t RXBUFFER[RXBUFFER_SIZE]; //create the buffer that received packets are copied into
|
||||
|
||||
uint8_t RXPacketL; //stores length of packet received
|
||||
int8_t PacketRSSI; //stores RSSI of received packet
|
||||
int8_t PacketSNR; //stores signal to noise ratio (SNR) of received packet
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
RXPacketL = LT.receive(RXBUFFER, RXBUFFER_SIZE, 60000, WAIT_RX); //wait for a packet to arrive with 60seconds (60000mS) timeout
|
||||
|
||||
digitalWrite(LED1, HIGH); //something has happened
|
||||
|
||||
if (BUZZER > 0) //turn buzzer on
|
||||
{
|
||||
digitalWrite(BUZZER, HIGH);
|
||||
}
|
||||
|
||||
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 is 0
|
||||
{
|
||||
packet_is_Error();
|
||||
}
|
||||
else
|
||||
{
|
||||
packet_is_OK();
|
||||
}
|
||||
|
||||
if (BUZZER > 0)
|
||||
{
|
||||
digitalWrite(BUZZER, LOW); //buzzer off
|
||||
}
|
||||
|
||||
digitalWrite(LED1, LOW); //LED off
|
||||
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
|
||||
void packet_is_OK()
|
||||
{
|
||||
uint16_t IRQStatus, localCRC;
|
||||
|
||||
IRQStatus = LT.readIrqStatus(); //read the LoRa device IRQ status register
|
||||
|
||||
RXpacketCount++;
|
||||
|
||||
printElapsedTime(); //print elapsed time to Serial Monitor
|
||||
Serial.print(F(" "));
|
||||
LT.printASCIIPacket(RXBUFFER, RXPacketL); //print the packet as ASCII characters
|
||||
|
||||
localCRC = LT.CRCCCITT(RXBUFFER, RXPacketL, 0xFFFF); //calculate the CRC, this is the external CRC calculation of the RXBUFFER
|
||||
Serial.print(F(",CRC,")); //contents, not the LoRa device internal CRC
|
||||
Serial.print(localCRC, HEX);
|
||||
Serial.print(F(",RSSI,"));
|
||||
Serial.print(PacketRSSI);
|
||||
Serial.print(F("dBm,SNR,"));
|
||||
Serial.print(PacketSNR);
|
||||
Serial.print(F("dB,Length,"));
|
||||
Serial.print(RXPacketL);
|
||||
Serial.print(F(",Packets,"));
|
||||
Serial.print(RXpacketCount);
|
||||
Serial.print(F(",Errors,"));
|
||||
Serial.print(errors);
|
||||
Serial.print(F(",IRQreg,"));
|
||||
Serial.print(IRQStatus, HEX);
|
||||
}
|
||||
|
||||
|
||||
void packet_is_Error()
|
||||
{
|
||||
uint16_t IRQStatus;
|
||||
IRQStatus = LT.readIrqStatus(); //read the LoRa device IRQ status register
|
||||
|
||||
printElapsedTime(); //print elapsed time to Serial Monitor
|
||||
|
||||
if (IRQStatus & IRQ_RX_TIMEOUT) //check for an RX timeout
|
||||
{
|
||||
Serial.print(F(" RXTimeout"));
|
||||
}
|
||||
else
|
||||
{
|
||||
errors++;
|
||||
Serial.print(F(" PacketError"));
|
||||
Serial.print(F(",RSSI,"));
|
||||
Serial.print(PacketRSSI);
|
||||
Serial.print(F("dBm,SNR,"));
|
||||
Serial.print(PacketSNR);
|
||||
Serial.print(F("dB,Length,"));
|
||||
Serial.print(LT.readRXPacketL()); //get the device packet length
|
||||
Serial.print(F(",Packets,"));
|
||||
Serial.print(RXpacketCount);
|
||||
Serial.print(F(",Errors,"));
|
||||
Serial.print(errors);
|
||||
Serial.print(F(",IRQreg,"));
|
||||
Serial.print(IRQStatus, HEX);
|
||||
LT.printIrqStatus(); //print the names of the IRQ registers set
|
||||
}
|
||||
|
||||
delay(250); //gives a longer buzzer and LED flash for error
|
||||
|
||||
}
|
||||
|
||||
|
||||
void printElapsedTime()
|
||||
{
|
||||
float seconds;
|
||||
seconds = millis() / 1000;
|
||||
Serial.print(seconds, 0);
|
||||
Serial.print(F("s"));
|
||||
}
|
||||
|
||||
|
||||
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.print(F(__TIME__));
|
||||
Serial.print(F(" "));
|
||||
Serial.println(F(__DATE__));
|
||||
Serial.println(F(Program_Version));
|
||||
Serial.println();
|
||||
Serial.println(F("104_LoRa_Receiver_Detailed_Setup Starting"));
|
||||
Serial.println();
|
||||
|
||||
if (BUZZER > 0)
|
||||
{
|
||||
pinMode(BUZZER, OUTPUT);
|
||||
digitalWrite(BUZZER, HIGH);
|
||||
delay(50);
|
||||
digitalWrite(BUZZER, LOW);
|
||||
}
|
||||
|
||||
SPI.begin();
|
||||
|
||||
//SPI beginTranscation is normally part of library routines, but if it is disabled in the library
|
||||
//a single instance is needed here, so uncomment the program line below
|
||||
//SPI.beginTransaction(SPISettings(8000000, MSBFIRST, SPI_MODE0));
|
||||
|
||||
//setup hardware pins used by device, then check if device is found
|
||||
if (LT.begin(NSS, NRESET, RFBUSY, DIO1, DIO2, DIO3, RX_EN, TX_EN, 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 LED flash indicates device error
|
||||
}
|
||||
}
|
||||
|
||||
//The function call list below shows the complete setup for the LoRa device using the information defined in the
|
||||
//Settings.h file.
|
||||
//The 'Setup LoRa device' list below can be replaced with a single function call;
|
||||
//LT.setupLoRa(Frequency, Offset, SpreadingFactor, Bandwidth, CodeRate);
|
||||
|
||||
//***************************************************************************************************
|
||||
//Setup LoRa device
|
||||
//***************************************************************************************************
|
||||
LT.setMode(MODE_STDBY_RC);
|
||||
LT.setRegulatorMode(USE_LDO);
|
||||
LT.setPacketType(PACKET_TYPE_LORA);
|
||||
LT.setRfFrequency(Frequency, Offset);
|
||||
LT.setBufferBaseAddress(0, 0);
|
||||
LT.setModulationParams(SpreadingFactor, Bandwidth, CodeRate);
|
||||
LT.setPacketParams(12, LORA_PACKET_VARIABLE_LENGTH, 255, LORA_CRC_ON, LORA_IQ_NORMAL, 0, 0);
|
||||
LT.setDioIrqParams(IRQ_RADIO_ALL, (IRQ_TX_DONE + IRQ_RX_TX_TIMEOUT), 0, 0);
|
||||
//***************************************************************************************************
|
||||
|
||||
|
||||
Serial.println();
|
||||
LT.printModemSettings(); //reads and prints the configured LoRa settings, useful check
|
||||
Serial.println();
|
||||
LT.printOperatingSettings(); //reads and prints the configured operting settings, useful check
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
LT.printRegisters(0x900, 0x9FF); //print contents of device registers, normally 0x900 to 0x9FF
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
|
||||
Serial.print(F("Receiver ready - RXBUFFER_SIZE "));
|
||||
Serial.println(RXBUFFER_SIZE);
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
/*******************************************************************************************************
|
||||
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. Some pins such as DIO2,
|
||||
//DIO3, BUZZER are not used by this sketch so they do not need to be connected and
|
||||
//should be set to -1.
|
||||
|
||||
#define NSS 10 //select pin on LoRa device
|
||||
#define NRESET 9 //reset pin on LoRa device
|
||||
#define RFBUSY 7 //busy pin on LoRa device
|
||||
#define DIO1 3 //DIO1 pin on LoRa device, used for RX and TX done
|
||||
#define DIO2 -1 //DIO2 pin on LoRa device, normally not used so set to -1
|
||||
#define DIO3 -1 //DIO3 pin on LoRa device, normally not used so set to -1
|
||||
#define RX_EN -1 //pin for RX enable, used on some SX128X devices, set to -1 if not used
|
||||
#define TX_EN -1 //pin for TX enable, used on some SX128X devices, set to -1 if not used
|
||||
#define LED1 8 //on board LED, high for on
|
||||
#define BUZZER -1 //pin for buzzer, set to -1 if not used
|
||||
|
||||
#define LORA_DEVICE DEVICE_SX1280 //we need to define the device we are using
|
||||
|
||||
|
||||
|
||||
//******* Setup LoRa Parameters Here ! ***************
|
||||
|
||||
//LoRa Modem Parameters
|
||||
#define Frequency 2445000000 //frequency of transmissions
|
||||
#define Offset 0 //offset frequency for calibration purposes
|
||||
#define Bandwidth LORA_BW_0400 //LoRa bandwidth
|
||||
#define SpreadingFactor LORA_SF7 //LoRa spreading factor
|
||||
#define CodeRate LORA_CR_4_5 //LoRa coding rate
|
||||
|
||||
const uint16_t packet_delay = 1000; //mS delay between packets
|
||||
|
||||
#define RXBUFFER_SIZE 32 //RX buffer size
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,145 @@
|
||||
/*******************************************************************************************************
|
||||
Programs for Arduino - Copyright of the author Stuart Robinson - 08/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 - This program demonstrates the transmitting of a structure as a LoRa packet. The
|
||||
contents of the structure are the same as in the '8_LoRa_LowMemory_TX' program. The packet sent is
|
||||
typical of what might be sent from a GPS tracker.
|
||||
|
||||
The structure type is defined as trackerPacket and an instance called location1 is created. The struture
|
||||
which includes a character array (text) is filled with values and transmitted.
|
||||
|
||||
The matching receiving program '15_LoRa_RX_Structure' can be used to receive and display the packet,
|
||||
though the program '9_LoRa_LowMemory_RX' should receive it as well, since the contents are the same.
|
||||
|
||||
Note that the structure definition and variable order (including the buffer size) used in the transmitter
|
||||
need to match those used in the receiver.
|
||||
|
||||
The contents of the packet transmitted should be;
|
||||
|
||||
"tracker1" (buffer) - trackerID
|
||||
1+ (uint32_t) - packet count
|
||||
51.23456 (float) - latitude
|
||||
-3.12345 (float) - longitude
|
||||
199 (uint16_t) - altitude
|
||||
8 (uint8_t) - number of satellites
|
||||
3999 (uint16_t) - battery voltage
|
||||
-9 (int8_t) - temperature
|
||||
|
||||
Good luck.
|
||||
|
||||
Serial monitor baud rate is set at 9600.
|
||||
|
||||
*******************************************************************************************************/
|
||||
|
||||
#include <SPI.h>
|
||||
#include <SX128XLT.h>
|
||||
#include "Settings.h"
|
||||
|
||||
SX128XLT LT;
|
||||
|
||||
uint32_t TXpacketCount = 1;
|
||||
uint32_t startmS, endmS;
|
||||
|
||||
struct trackerPacket
|
||||
{
|
||||
uint8_t trackerID[13];
|
||||
uint32_t txcount;
|
||||
float latitude;
|
||||
float longitude;
|
||||
uint16_t altitude;
|
||||
uint8_t satellites;
|
||||
uint16_t voltage;
|
||||
int8_t temperature;
|
||||
};
|
||||
|
||||
struct trackerPacket location1; //define an instance called location1 of the structure trackerPacket
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
|
||||
//fill the defined structure with values
|
||||
uint8_t buff[] = "tracker1"; //create the contents to be of location1.trackerID
|
||||
memcpy (&location1.trackerID, &buff, sizeof(buff)); //copy the contents of buff[] into the structure
|
||||
location1.txcount = TXpacketCount;
|
||||
location1.latitude = 51.23456;
|
||||
location1.longitude = -3.12345;
|
||||
location1.altitude = 199;
|
||||
location1.satellites = 8;
|
||||
location1.voltage = 3999;
|
||||
location1.temperature = -9;
|
||||
|
||||
digitalWrite(LED1, HIGH);
|
||||
startmS = millis();
|
||||
|
||||
if (LT.transmit((uint8_t *) &location1, sizeof(location1), 0, TXpower, WAIT_TX)) //will return packet length sent if OK, otherwise 0
|
||||
{
|
||||
endmS = millis();
|
||||
digitalWrite(LED1, LOW);
|
||||
TXpacketCount++;
|
||||
Serial.print(TXpacketCount);
|
||||
Serial.print(F(" "));
|
||||
Serial.print(sizeof(location1));
|
||||
Serial.print(F(" Bytes Sent"));
|
||||
Serial.print(F(" "));
|
||||
Serial.print(endmS - startmS);
|
||||
Serial.print(F("mS"));
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.print(F("Send Error - IRQreg,"));
|
||||
Serial.print(LT.readIrqStatus(), HEX);
|
||||
}
|
||||
|
||||
digitalWrite(LED1, LOW);
|
||||
Serial.println();
|
||||
delay(packet_delay);
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
|
||||
SPI.begin();
|
||||
|
||||
if (LT.begin(NSS, NRESET, RFBUSY, DIO1, DIO2, DIO3, RX_EN, TX_EN, 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.println(F("Transmitter ready"));
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
/*******************************************************************************************************
|
||||
Programs for Arduino - Copyright of the author Stuart Robinson - 08/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. Some pins such as DIO2,
|
||||
//DIO3, BUZZER may not be in used by this sketch so they do not need to be
|
||||
//connected and should be included and be set to -1.
|
||||
|
||||
#define NSS 10
|
||||
#define RFBUSY 7
|
||||
#define NRESET 9
|
||||
#define LED1 8
|
||||
#define DIO1 3
|
||||
#define DIO2 -1 //not used
|
||||
#define DIO3 -1 //not used
|
||||
#define RX_EN -1 //pin for RX enable, used on some SX1280 devices, set to -1 if not used
|
||||
#define TX_EN -1 //pin for TX enable, used on some SX1280 devices, set to -1 if not used
|
||||
|
||||
#define BUZZER -1 //connect a buzzer here if wanted
|
||||
|
||||
#define LORA_DEVICE DEVICE_SX1280 //we need to define the device we are using
|
||||
|
||||
//LoRa Modem Parameters
|
||||
#define Frequency 2445000000 //frequency of transmissions
|
||||
#define Offset 0 //offset frequency for calibration purposes
|
||||
#define Bandwidth LORA_BW_0400 //LoRa bandwidth
|
||||
#define SpreadingFactor LORA_SF7 //LoRa spreading factor
|
||||
#define CodeRate LORA_CR_4_5 //LoRa coding rate
|
||||
|
||||
#define TXpower 10 //power for transmissions in dBm
|
||||
|
||||
#define packet_delay 1000 //mS delay between packets
|
||||
|
||||
@@ -0,0 +1,194 @@
|
||||
/*******************************************************************************************************
|
||||
Programs for Arduino - Copyright of the author Stuart Robinson - 08/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 - This program demonstrates the receiving of a structure as a LoRa packet. The packet
|
||||
sent is typical of what might be sent from a GPS tracker.
|
||||
|
||||
The structure type is defined as trackerPacket and an instance called location1 is created. The structure
|
||||
includes a character array (text).
|
||||
|
||||
The matching receiving program is '15_LoRa_RX_Structure' can be used to receive and display the packet,
|
||||
though the program '9_LoRa_LowMemory_RX' should receive it as well, since the packet contents are the same.
|
||||
|
||||
Not that the structure definition and variable order (including the buffer size) used in the transmitter
|
||||
need to match those used in the receiver. Good luck.
|
||||
|
||||
The contents of the packet received, and printed to serial monitor, should be;
|
||||
|
||||
"tracker1" (buffer) - trackerID
|
||||
1+ (uint32_t) - packet count
|
||||
51.23456 (float) - latitude
|
||||
-3.12345 (float) - longitude
|
||||
199 (uint16_t) - altitude
|
||||
8 (uint8_t) - number of satellites
|
||||
3999 (uint16_t) - battery voltage
|
||||
-9 (int8_t) - temperature
|
||||
|
||||
Serial monitor baud rate is set at 9600.
|
||||
|
||||
*******************************************************************************************************/
|
||||
|
||||
#include <SPI.h>
|
||||
#include <SX128XLT.h>
|
||||
#include "Settings.h"
|
||||
|
||||
SX128XLT LT;
|
||||
|
||||
uint8_t RXPacketL; //stores length of packet received
|
||||
uint32_t RXpacketCount; //count of received packets
|
||||
int8_t PacketRSSI; //RSSI of received packet
|
||||
int8_t PacketSNR; //signal to noise ratio of received packet
|
||||
uint32_t errors; //count of packet errors
|
||||
|
||||
|
||||
struct trackerPacket
|
||||
{
|
||||
uint8_t trackerID[13];
|
||||
uint32_t txcount;
|
||||
float latitude;
|
||||
float longitude;
|
||||
uint16_t altitude;
|
||||
uint8_t satellites;
|
||||
uint16_t voltage;
|
||||
int8_t temperature;
|
||||
};
|
||||
|
||||
struct trackerPacket location1; //define an instance called location1 of the structure trackerPacket
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
RXPacketL = LT.receive( (uint8_t *) &location1, sizeof(location1), 0, WAIT_RX); //wait for a packet to arrive with no timeout
|
||||
|
||||
digitalWrite(LED1, HIGH); //something has happened, what I wonder ?
|
||||
|
||||
PacketRSSI = LT.readPacketRSSI();
|
||||
PacketSNR = LT.readPacketSNR();
|
||||
|
||||
if (RXPacketL == 0)
|
||||
{
|
||||
packet_is_Error();
|
||||
}
|
||||
else
|
||||
{
|
||||
packet_is_OK();
|
||||
}
|
||||
|
||||
digitalWrite(LED1, LOW);
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
|
||||
void printlocation1()
|
||||
{
|
||||
uint8_t buff[13]; //define a buffer to receive a copy from the structure
|
||||
memcpy (&buff, &location1.trackerID, sizeof(buff)); //copy the contents of buffer in struture to buff[]
|
||||
|
||||
//now print the contents of the structure
|
||||
Serial.print((char*) buff); //cast to a char type for printing
|
||||
Serial.print(F(","));
|
||||
Serial.print(location1.txcount);
|
||||
Serial.print(F(","));
|
||||
Serial.print(location1.latitude, 5);
|
||||
Serial.print(F(","));
|
||||
Serial.print(location1.longitude, 5);
|
||||
Serial.print(F(","));
|
||||
Serial.print(location1.altitude);
|
||||
Serial.print(F("m,"));
|
||||
Serial.print(location1.satellites);
|
||||
Serial.print(F("sats,"));
|
||||
Serial.print(location1.voltage);
|
||||
Serial.print(F("mV,"));
|
||||
Serial.print(location1.temperature);
|
||||
Serial.print(F("c "));
|
||||
}
|
||||
|
||||
|
||||
void packet_is_OK()
|
||||
{
|
||||
RXpacketCount++;
|
||||
Serial.print(RXpacketCount);
|
||||
Serial.print(F(" "));
|
||||
printlocation1();
|
||||
printpacketDetails();
|
||||
}
|
||||
|
||||
|
||||
void packet_is_Error()
|
||||
{
|
||||
uint16_t IRQStatus;
|
||||
IRQStatus = LT.readIrqStatus();
|
||||
|
||||
if (IRQStatus & IRQ_RX_TIMEOUT)
|
||||
{
|
||||
Serial.print(F("RXTimeout"));
|
||||
}
|
||||
else
|
||||
{
|
||||
errors++;
|
||||
Serial.print(F("PacketError"));
|
||||
printpacketDetails();
|
||||
Serial.print(F("IRQreg,"));
|
||||
Serial.print(IRQStatus, HEX);
|
||||
}
|
||||
}
|
||||
|
||||
void printpacketDetails()
|
||||
{
|
||||
Serial.print(F(" RSSI,"));
|
||||
Serial.print(PacketRSSI);
|
||||
Serial.print(F("dBm,SNR,"));
|
||||
Serial.print(PacketSNR);
|
||||
Serial.print(F("dB"));
|
||||
}
|
||||
|
||||
|
||||
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(void)
|
||||
{
|
||||
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);
|
||||
|
||||
SPI.begin();
|
||||
|
||||
if (LT.begin(NSS, NRESET, RFBUSY, DIO1, DIO2, DIO3, RX_EN, TX_EN, LORA_DEVICE))
|
||||
{
|
||||
led_Flash(2, 125);
|
||||
delay(1000);
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println(F("Device error"));
|
||||
while (1)
|
||||
{
|
||||
led_Flash(50, 50);
|
||||
}
|
||||
}
|
||||
|
||||
LT.setupLoRa(Frequency, Offset, SpreadingFactor, Bandwidth, CodeRate);
|
||||
|
||||
Serial.print(F("Receiver ready"));
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/*******************************************************************************************************
|
||||
Programs for Arduino - Copyright of the author Stuart Robinson - 06/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. Some pins such as DIO2,
|
||||
//DIO3, BUZZER may not be in used by this sketch so they do not need to be
|
||||
//connected and should be included and be set to -1.
|
||||
|
||||
#define NSS 10
|
||||
#define RFBUSY 7
|
||||
#define NRESET 9
|
||||
#define LED1 8
|
||||
#define DIO1 3
|
||||
#define DIO2 -1 //not used
|
||||
#define DIO3 -1 //not used
|
||||
#define RX_EN -1 //pin for RX enable, used on some SX1280 devices, set to -1 if not used
|
||||
#define TX_EN -1 //pin for TX enable, used on some SX1280 devices, set to -1 if not used
|
||||
#define BUZZER -1 //connect a buzzer here if wanted
|
||||
|
||||
#define LORA_DEVICE DEVICE_SX1280 //we need to define the device we are using
|
||||
|
||||
//LoRa Modem Parameters
|
||||
#define Frequency 2445000000 //frequency of transmissions
|
||||
#define Offset 0 //offset frequency for calibration purposes
|
||||
#define Bandwidth LORA_BW_0400 //LoRa bandwidth
|
||||
#define SpreadingFactor LORA_SF7 //LoRa spreading factor
|
||||
#define CodeRate LORA_CR_4_5 //LoRa coding rate
|
||||
|
||||
#define TXpower 10 //power for transmissions in dBm
|
||||
|
||||
#define packet_delay 1000 //mS delay between packets
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
/*******************************************************************************************************
|
||||
Programs for Arduino - Copyright of the author Stuart Robinson - 06/02/20
|
||||
|
||||
This programs is supplied as is, it is up to the user of the program to decide if the programs are
|
||||
suitable for the intended purpose and free from errors.
|
||||
*******************************************************************************************************/
|
||||
|
||||
/*******************************************************************************************************
|
||||
Program Operation - This program blinks an LED connected the pin number defined below. The pin 13 LED,
|
||||
fitted to some Arduinos is blinked as well. The blinks should be close to one per second. messages are
|
||||
sent to the Serial Monitor also.
|
||||
|
||||
Serial monitor baud rate is set at 9600.
|
||||
*******************************************************************************************************/
|
||||
|
||||
#define LED1 8 //pin number for LED, set logic level high for on
|
||||
|
||||
#define Program_Version "V1.0"
|
||||
|
||||
uint16_t seconds; //used to display time elapsed on Serial Monitor
|
||||
|
||||
void loop()
|
||||
{
|
||||
Serial.print(seconds);
|
||||
Serial.println(F(" Seconds")); //this message should print on console at close to once per second
|
||||
seconds++;
|
||||
digitalWrite(LED1, HIGH);
|
||||
digitalWrite(13, HIGH);
|
||||
delay(100);
|
||||
digitalWrite(LED1, LOW);
|
||||
digitalWrite(13, LOW);
|
||||
delay(890); //should give approx 1 second flash
|
||||
}
|
||||
|
||||
|
||||
void led_Flash(uint16_t flashes, uint16_t delaymS)
|
||||
{
|
||||
//general purpose routine for flashing LED as indicator
|
||||
uint16_t index;
|
||||
|
||||
for (index = 1; index <= flashes; index++)
|
||||
{
|
||||
digitalWrite(LED1, HIGH); //LED on
|
||||
digitalWrite(13, HIGH); //Arduino board LED on
|
||||
delay(delaymS);
|
||||
digitalWrite(LED1, LOW); //LED off
|
||||
digitalWrite(13, LOW); //Arduino board LED off
|
||||
delay(delaymS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
pinMode(LED1, OUTPUT); //setup pin as output for indicator LED
|
||||
pinMode(13, OUTPUT); //setup pin as output for some Arduino boards that include an LED on pin 13
|
||||
led_Flash(2, 125); //two quick LED flashes to indicate program start
|
||||
|
||||
Serial.begin(9600);
|
||||
Serial.println();
|
||||
Serial.print(__TIME__);
|
||||
Serial.print(F(" "));
|
||||
Serial.println(__DATE__);
|
||||
Serial.println(F(Program_Version));
|
||||
Serial.println();
|
||||
|
||||
Serial.println(F("1_LED_Blink Starting"));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,375 @@
|
||||
/*******************************************************************************************************
|
||||
Programs for Arduino - Copyright of the author Stuart Robinson - 11/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 - This program is stand alone, it is not necessary to install the SX12XX-LoRa library
|
||||
to use it. This test program is for the SX128X LoRa devices.
|
||||
|
||||
The program checks that a SX128X LoRa device can be accessed by doing a test register write and read.
|
||||
If there is no device found a message is printed on the serial monitor. The contents of the registers
|
||||
from 0x00 to 0x7F are printed, there is a copy of a typical printout below. Note that the read back
|
||||
changed frequency may be slightly different to the programmed frequency, there is a rounding error due
|
||||
to the use of floats to calculate the frequency.
|
||||
|
||||
The Arduino pin numbers that the NSS and NRESET pins on the LoRa device are connected to must be
|
||||
specified in the hardware definitions section below. The LoRa device type in use, SX1280 or SX1281
|
||||
must be specified also.
|
||||
|
||||
Typical printout;
|
||||
|
||||
2_Register_Test Starting
|
||||
Reset device
|
||||
LoRa Device found
|
||||
Reset device
|
||||
Registers at reset
|
||||
Reg 0 1 2 3 4 5 6 7 8 9 A B C D E F
|
||||
0x900 80 0C 7B 02 20 FA C0 00 00 80 00 00 00 00 00 FF
|
||||
0x910 FF FF 00 00 00 19 00 00 00 19 87 65 43 21 7F FF
|
||||
0x920 FF FF FF 0C 70 37 0A 50 D0 80 00 C0 5F D2 8F 0A
|
||||
0x930 00 C0 00 00 00 24 00 21 28 B0 30 09 1A 59 70 08
|
||||
0x940 58 0B 32 0A 14 24 6A 96 00 18 00 00 00 00 00 00
|
||||
0x950 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
0x960 00 00 00 00 00 00 00 00 00 00 FF FF FF FF FF FF
|
||||
0x970 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 04
|
||||
0x980 00 0B 18 70 00 00 00 4C 00 F0 64 00 00 00 00 00
|
||||
0x990 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
0x9A0 00 08 EC B8 9D 8A E6 66 06 00 00 00 00 00 00 00
|
||||
0x9B0 00 08 EC B8 9D 8A E6 66 06 00 00 00 00 00 00 00
|
||||
0x9C0 00 16 00 3F E8 01 FF FF FF FF 5E 4D 25 10 55 55
|
||||
0x9D0 55 55 55 55 55 55 55 55 55 55 55 55 55 00 00 00
|
||||
0x9E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
0x9F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
|
||||
Frequency at reset 2495996672hz
|
||||
Change Frequency to 2445000000hz
|
||||
Frequency now 2444999936hz
|
||||
|
||||
Reg 0 1 2 3 4 5 6 7 8 9 A B C D E F
|
||||
0x900 80 0C 7B 02 20 FA BC 13 C1 80 00 00 00 00 00 61
|
||||
|
||||
Serial monitor baud rate is set at 9600.
|
||||
*******************************************************************************************************/
|
||||
|
||||
const uint16_t REG_RFFrequency23_16 = 0x906;
|
||||
const uint16_t REG_RFFrequency15_8 = 0x907;
|
||||
const uint16_t REG_RFFrequency7_0 = 0x908;
|
||||
const uint8_t RADIO_WRITE_REGISTER = 0x18;
|
||||
const uint8_t RADIO_READ_REGISTER = 0x19;
|
||||
const uint8_t RADIO_SET_RFFREQUENCY = 0x86; //commnad to change frequency
|
||||
const uint8_t RADIO_SET_PACKETTYPE = 0x8A; //commnad to set packet mode
|
||||
const float FREQ_STEP = 198.364;
|
||||
const uint8_t PACKET_TYPE_LORA = 0x01;
|
||||
|
||||
//********* Setup hardware definitions here ! *****************
|
||||
|
||||
//These are the pin definitions for one of the Tracker boards, 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 an Arduino Pro Mini are
|
||||
//SCK pin 13, MISO pin 12, and MOSI pin 11.
|
||||
|
||||
#define NSS 10 //SX128X device select
|
||||
#define NRESET 9 //SX128X reset pin
|
||||
#define RFBUSY 7 //SX128X busy pin
|
||||
#define LED1 8 //for on board LED, put high for on
|
||||
|
||||
//**************************************************************/
|
||||
|
||||
|
||||
#include <SPI.h>
|
||||
|
||||
uint8_t saveddevice;
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(9600);
|
||||
Serial.println(F("2_Register_Test Starting"));
|
||||
|
||||
SPI.begin();
|
||||
SPI.beginTransaction(SPISettings(8000000, MSBFIRST, SPI_MODE0));
|
||||
|
||||
//The begin function setups the hardware pins used by device and then checks if device is found
|
||||
//the DIO1, DIO2 and DIO3 pins are not used in this example so are set to -1
|
||||
|
||||
if (begin(NSS, NRESET, RFBUSY, -1, -1, -1, 0))
|
||||
{
|
||||
Serial.println(F("LoRa Device found"));
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println(F("No device responding"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
uint32_t frequency;
|
||||
resetDevice(); //reset the device
|
||||
Serial.println(F("Registers at reset")); //show the all registers following a reset
|
||||
printRegisters(0x0900, 0x09FF);
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
|
||||
frequency = getFreqInt(); //read the set frequency following a reset
|
||||
Serial.print(F(" Frequency at reset "));
|
||||
Serial.print(frequency);
|
||||
Serial.println(F("hz"));
|
||||
|
||||
Serial.print(F("Change Frequency to 2445000000hz"));
|
||||
setPacketType(PACKET_TYPE_LORA); //this is needed to ensure frequency change is reflected in register print
|
||||
setRfFrequency(2445000000, 0); //change the frequency to 2445000000hertz
|
||||
|
||||
frequency = getFreqInt(); //read back the changed frequency
|
||||
Serial.println();
|
||||
Serial.print(F(" Frequency now "));
|
||||
Serial.print(frequency); //print the changed frequency, did the write work (allow for rounding errors) ?
|
||||
Serial.println(F("hz"));
|
||||
Serial.println();
|
||||
printRegisters(0x0900, 0x090F); //show the registers after frequency change
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
delay(5000);
|
||||
}
|
||||
|
||||
|
||||
void readRegisters(uint16_t address, uint8_t *buffer, uint16_t size)
|
||||
{
|
||||
uint16_t index;
|
||||
uint8_t addr_l, addr_h;
|
||||
|
||||
addr_h = address >> 8;
|
||||
addr_l = address & 0x00FF;
|
||||
checkBusy();
|
||||
|
||||
digitalWrite(NSS, LOW);
|
||||
SPI.transfer(RADIO_READ_REGISTER);
|
||||
SPI.transfer(addr_h); //MSB
|
||||
SPI.transfer(addr_l); //LSB
|
||||
SPI.transfer(0xFF);
|
||||
for (index = 0; index < size; index++)
|
||||
{
|
||||
*(buffer + index) = SPI.transfer(0xFF);
|
||||
}
|
||||
|
||||
digitalWrite(NSS, HIGH);
|
||||
checkBusy();
|
||||
}
|
||||
|
||||
|
||||
uint8_t readRegister(uint16_t address)
|
||||
{
|
||||
uint8_t data;
|
||||
|
||||
readRegisters(address, &data, 1);
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
void writeRegisters(uint16_t address, uint8_t *buffer, uint16_t size)
|
||||
{
|
||||
uint8_t addr_l, addr_h;
|
||||
uint8_t i;
|
||||
|
||||
addr_l = address & 0xff;
|
||||
addr_h = address >> 8;
|
||||
checkBusy();
|
||||
|
||||
digitalWrite(NSS, LOW);
|
||||
SPI.transfer(RADIO_WRITE_REGISTER);
|
||||
SPI.transfer(addr_h); //MSB
|
||||
SPI.transfer(addr_l); //LSB
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
SPI.transfer(buffer[i]);
|
||||
}
|
||||
|
||||
digitalWrite(NSS, HIGH);
|
||||
|
||||
checkBusy();
|
||||
}
|
||||
|
||||
|
||||
void writeRegister(uint16_t address, uint8_t value)
|
||||
{
|
||||
writeRegisters(address, &value, 1 );
|
||||
}
|
||||
|
||||
|
||||
uint32_t getFreqInt()
|
||||
{
|
||||
//get the current set device frequency, return as long integer
|
||||
uint8_t Msb, Mid, Lsb;
|
||||
uint32_t uinttemp;
|
||||
float floattemp;
|
||||
Msb = readRegister(REG_RFFrequency23_16);
|
||||
Mid = readRegister(REG_RFFrequency15_8);
|
||||
Lsb = readRegister(REG_RFFrequency7_0);
|
||||
floattemp = ((Msb * 0x10000ul) + (Mid * 0x100ul) + Lsb);
|
||||
floattemp = ((floattemp * FREQ_STEP) / 1000000ul);
|
||||
uinttemp = (uint32_t)(floattemp * 1000000);
|
||||
return uinttemp;
|
||||
}
|
||||
|
||||
|
||||
void printRegisters(uint16_t Start, uint16_t End)
|
||||
{
|
||||
//prints the contents of SX128x registers to serial monitor
|
||||
|
||||
uint16_t Loopv1, Loopv2, RegData;
|
||||
|
||||
Serial.print(F("Reg 0 1 2 3 4 5 6 7 8 9 A B C D E F"));
|
||||
Serial.println();
|
||||
|
||||
for (Loopv1 = Start; Loopv1 <= End;) //32 lines
|
||||
{
|
||||
Serial.print(F("0x"));
|
||||
Serial.print((Loopv1), HEX); //print the register number
|
||||
Serial.print(F(" "));
|
||||
for (Loopv2 = 0; Loopv2 <= 15; Loopv2++)
|
||||
{
|
||||
RegData = readRegister(Loopv1);
|
||||
if (RegData < 0x10)
|
||||
{
|
||||
Serial.print(F("0"));
|
||||
}
|
||||
Serial.print(RegData, HEX); //print the register number
|
||||
Serial.print(F(" "));
|
||||
Loopv1++;
|
||||
}
|
||||
Serial.println();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void setRfFrequency(uint32_t frequency, int32_t offset)
|
||||
{
|
||||
frequency = frequency + offset;
|
||||
uint8_t buffer[3];
|
||||
uint32_t freqtemp = 0;
|
||||
freqtemp = ( uint32_t )( (float) frequency / (float) FREQ_STEP);
|
||||
buffer[0] = ( uint8_t )( ( freqtemp >> 16 ) & 0xFF );
|
||||
buffer[1] = ( uint8_t )( ( freqtemp >> 8 ) & 0xFF );
|
||||
buffer[2] = ( uint8_t )( freqtemp & 0xFF );
|
||||
writeCommand(RADIO_SET_RFFREQUENCY, buffer, 3);
|
||||
writeCommand(RADIO_SET_RFFREQUENCY, buffer, 3);
|
||||
}
|
||||
|
||||
|
||||
void checkBusy()
|
||||
{
|
||||
uint8_t busy_timeout_cnt;
|
||||
busy_timeout_cnt = 0;
|
||||
|
||||
while (digitalRead(RFBUSY))
|
||||
{
|
||||
delay(1);
|
||||
busy_timeout_cnt++;
|
||||
|
||||
if (busy_timeout_cnt > 10) //wait 10mS for busy to complete
|
||||
{
|
||||
busy_timeout_cnt = 0;
|
||||
Serial.println(F("ERROR - Busy Timeout!"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void resetDevice()
|
||||
{
|
||||
Serial.println(F("Reset device"));
|
||||
delay(10);
|
||||
digitalWrite(NRESET, LOW);
|
||||
delay(2);
|
||||
digitalWrite(NRESET, HIGH);
|
||||
delay(25);
|
||||
checkBusy();
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool begin(int8_t pinNSS, int8_t pinNRESET, int8_t pinRFBUSY, int8_t pinDIO1, int8_t pinDIO2, int8_t pinDIO3, uint8_t device)
|
||||
{
|
||||
saveddevice = device;
|
||||
|
||||
pinMode(pinNSS, OUTPUT);
|
||||
digitalWrite(pinNSS, HIGH);
|
||||
pinMode(pinNRESET, OUTPUT);
|
||||
digitalWrite(pinNRESET, HIGH);
|
||||
pinMode(pinRFBUSY, INPUT);
|
||||
|
||||
if (pinDIO1 >= 0)
|
||||
{
|
||||
pinMode( pinDIO1, INPUT);
|
||||
}
|
||||
|
||||
if (pinDIO2 >= 0)
|
||||
{
|
||||
pinMode(pinDIO2, INPUT);
|
||||
}
|
||||
|
||||
if (pinDIO3 >= 0)
|
||||
{
|
||||
pinMode(pinDIO3, INPUT);
|
||||
}
|
||||
|
||||
resetDevice();
|
||||
|
||||
if (checkDevice())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool checkDevice()
|
||||
{
|
||||
//check there is a device out there, writes a register and reads back
|
||||
|
||||
uint8_t Regdata1, Regdata2;
|
||||
Regdata1 = readRegister(0x0908); //low byte of frequency setting
|
||||
writeRegister(0x0908, (Regdata1 + 1));
|
||||
Regdata2 = readRegister(0x0908); //read changed value back
|
||||
writeRegister(0x0908, Regdata1); //restore register to original value
|
||||
|
||||
if (Regdata2 == (Regdata1 + 1))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void writeCommand(uint8_t Opcode, uint8_t *buffer, uint16_t size)
|
||||
{
|
||||
uint8_t index;
|
||||
checkBusy();
|
||||
|
||||
digitalWrite(NSS, LOW);
|
||||
SPI.transfer(Opcode);
|
||||
|
||||
for (index = 0; index < size; index++)
|
||||
{
|
||||
SPI.transfer(buffer[index]);
|
||||
//Serial.println(buffer[index], HEX);
|
||||
}
|
||||
digitalWrite(NSS, HIGH);
|
||||
|
||||
checkBusy();
|
||||
}
|
||||
|
||||
void setPacketType(uint8_t packettype)
|
||||
{
|
||||
writeCommand(RADIO_SET_PACKETTYPE, &packettype, 1);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,183 @@
|
||||
/*******************************************************************************************************
|
||||
Programs for Arduino - Copyright of the author Stuart Robinson - 06/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 - This is a simple LoRa test transmitter. A packet containing ASCII text is sent
|
||||
according to the frequency and LoRa settings specified in the 'Settings.h' file. The pins to access
|
||||
the lora device need to be defined in the 'Settings.h' file also.
|
||||
|
||||
The details of the packet sent and any errors are shown on the Serial Monitor, together with the transmit
|
||||
power used, the packet length and the CRC of the packet. The matching receive program, '4_LoRa_Receive'
|
||||
can be used to check the packets are being sent correctly, the frequency and LoRa settings (in Settings.h)
|
||||
must be the same for the Transmit and Receive program. Sample Serial Monitor output;
|
||||
|
||||
10dBm Packet> {packet contents*} BytesSent,23 CRC,DAAB TransmitTime,54mS PacketsSent,1
|
||||
|
||||
Serial monitor baud rate is set at 9600
|
||||
*******************************************************************************************************/
|
||||
|
||||
#define Program_Version "V1.0"
|
||||
|
||||
#include <SPI.h> //the SX128X device is SPI based so load the SPI library
|
||||
#include <SX128XLT.h> //include the appropriate library
|
||||
#include "Settings.h" //include the setiings file, frequencies, LoRa settings etc
|
||||
|
||||
SX128XLT LT; //create a library class instance called LT
|
||||
|
||||
uint8_t TXPacketL;
|
||||
uint32_t TXPacketCount, startmS, endmS;
|
||||
|
||||
uint8_t buff[] = "Hello World 1234567890";
|
||||
|
||||
void loop()
|
||||
{
|
||||
Serial.print(TXpower); //print the transmit power defined
|
||||
Serial.print(F("dBm "));
|
||||
Serial.print(F("Packet> "));
|
||||
Serial.flush();
|
||||
|
||||
TXPacketL = sizeof(buff); //set TXPacketL to length of array
|
||||
buff[TXPacketL - 1] = '*'; //replace null character at buffer end so its visible on reciver
|
||||
|
||||
LT.printASCIIPacket(buff, TXPacketL); //print the buffer (the sent packet) as ASCII
|
||||
|
||||
digitalWrite(LED1, HIGH);
|
||||
startmS = millis(); //start transmit timer
|
||||
if (LT.transmit(buff, TXPacketL, 10000, TXpower, WAIT_TX)) //will return packet length sent if OK, otherwise 0 if transmit, timeout 10 seconds
|
||||
{
|
||||
endmS = millis(); //packet sent, note end time
|
||||
TXPacketCount++;
|
||||
packet_is_OK();
|
||||
}
|
||||
else
|
||||
{
|
||||
packet_is_Error(); //transmit packet returned 0, there was an error
|
||||
}
|
||||
|
||||
digitalWrite(LED1, LOW);
|
||||
Serial.println();
|
||||
delay(packet_delay); //have a delay between packets
|
||||
}
|
||||
|
||||
|
||||
void packet_is_OK()
|
||||
{
|
||||
//if here packet has been sent OK
|
||||
uint16_t localCRC;
|
||||
|
||||
Serial.print(F(" BytesSent,"));
|
||||
Serial.print(TXPacketL); //print transmitted packet length
|
||||
localCRC = LT.CRCCCITT(buff, TXPacketL, 0xFFFF);
|
||||
Serial.print(F(" CRC,"));
|
||||
Serial.print(localCRC, HEX); //print CRC of sent packet
|
||||
Serial.print(F(" TransmitTime,"));
|
||||
Serial.print(endmS - startmS); //print transmit time of packet
|
||||
Serial.print(F("mS"));
|
||||
Serial.print(F(" PacketsSent,"));
|
||||
Serial.print(TXPacketCount); //print total of packets sent OK
|
||||
}
|
||||
|
||||
|
||||
void packet_is_Error()
|
||||
{
|
||||
//if here there was an error transmitting packet
|
||||
uint16_t IRQStatus;
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
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.print(F(__TIME__));
|
||||
Serial.print(F(" "));
|
||||
Serial.println(F(__DATE__));
|
||||
Serial.println(F(Program_Version));
|
||||
Serial.println();
|
||||
Serial.println(F("3_LoRa_Transmitter Starting"));
|
||||
|
||||
SPI.begin();
|
||||
|
||||
//SPI beginTranscation is normally part of library routines, but if it is disabled in library
|
||||
//a single instance is needed here, so uncomment the program line below
|
||||
//SPI.beginTransaction(SPISettings(8000000, MSBFIRST, SPI_MODE0));
|
||||
|
||||
//setup hardware pins used by device, then check if device is found
|
||||
|
||||
if (LT.begin(NSS, NRESET, RFBUSY, DIO1, DIO2, DIO3, RX_EN, TX_EN, LORA_DEVICE))
|
||||
{
|
||||
Serial.println(F("LoRa Device found"));
|
||||
led_Flash(2, 125); //two further quick LED flashes to indicate device found
|
||||
delay(1000);
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println(F("No device responding"));
|
||||
while (1)
|
||||
{
|
||||
led_Flash(50, 50); //long fast speed LED flash indicates device error
|
||||
}
|
||||
}
|
||||
|
||||
//The function call list below shows the complete setup for the LoRa device using the information defined in the
|
||||
//Settings.h file.
|
||||
//The 'Setup LoRa device' list below can be replaced with a single function call;
|
||||
//LT.setupLoRa(Frequency, Offset, SpreadingFactor, Bandwidth, CodeRate);
|
||||
|
||||
//***************************************************************************************************
|
||||
//Setup LoRa device
|
||||
//***************************************************************************************************
|
||||
LT.setMode(MODE_STDBY_RC);
|
||||
LT.setRegulatorMode(USE_LDO);
|
||||
LT.setPacketType(PACKET_TYPE_LORA);
|
||||
LT.setRfFrequency(Frequency, Offset);
|
||||
LT.setBufferBaseAddress(0, 0);
|
||||
LT.setModulationParams(SpreadingFactor, Bandwidth, CodeRate);
|
||||
LT.setPacketParams(12, LORA_PACKET_VARIABLE_LENGTH, 255, LORA_CRC_ON, LORA_IQ_NORMAL, 0, 0);
|
||||
LT.setDioIrqParams(IRQ_RADIO_ALL, (IRQ_TX_DONE + IRQ_RX_TX_TIMEOUT), 0, 0);
|
||||
LT.setHighSensitivity();
|
||||
//LT.setLowPowerRX();
|
||||
//***************************************************************************************************
|
||||
|
||||
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();
|
||||
Serial.println();
|
||||
LT.printRegisters(0x900, 0x9FF); //print contents of device registers
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
|
||||
Serial.print(F("Transmitter ready"));
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/*******************************************************************************************************
|
||||
Programs for Arduino - Copyright of the author Stuart Robinson - 06/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. Some pins such as DIO2,
|
||||
//DIO3, 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 10
|
||||
#define RFBUSY 7
|
||||
#define NRESET 9
|
||||
#define LED1 8
|
||||
#define DIO1 3
|
||||
#define DIO2 -1 //not used
|
||||
#define DIO3 -1 //not used
|
||||
#define RX_EN -1 //pin for RX enable, used on some SX1280 devices, set to -1 if not used
|
||||
#define TX_EN -1 //pin for TX enable, used on some SX1280 devices, set to -1 if not used
|
||||
|
||||
|
||||
#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 uint8_t TXpower = 10; //Power for transmissions in dBm
|
||||
|
||||
const uint16_t packet_delay = 1000; //mS delay between packets
|
||||
|
||||
@@ -0,0 +1,247 @@
|
||||
/*******************************************************************************************************
|
||||
Programs for Arduino - Copyright of the author Stuart Robinson - 08/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 listens for incoming packets using the LoRa settings in the 'Settings.h'
|
||||
file. The pins to access the lora device need to be defined in the 'Settings.h' file also.
|
||||
|
||||
There is a printout of the valid packets received, the packet is assumed to be in ASCII printable text,
|
||||
if its not ASCII text characters from 0x20 to 0x7F, expect weird things to happen on the Serial Monitor.
|
||||
The LED will flash for each packet received and the buzzer will sound, if fitted.
|
||||
|
||||
Sample serial monitor output;
|
||||
|
||||
1109s Hello World 1234567890*,CRC,DAAB,RSSI,-61dBm,SNR,9dB,Length,23,Packets,1026,Errors,0,IRQreg,50
|
||||
|
||||
If there is a packet error it might look like this, which is showing a CRC error,
|
||||
|
||||
1189s PacketError,RSSI,-111dBm,SNR,-12dB,Length,0,Packets,1126,Errors,1,IRQreg,70,IRQ_HEADER_VALID,IRQ_CRC_ERROR,IRQ_RX_DONE
|
||||
|
||||
Serial monitor baud rate is set at 9600.
|
||||
*******************************************************************************************************/
|
||||
|
||||
#define Program_Version "V1.0"
|
||||
|
||||
#include <SPI.h> //the lora device is SPI based so load the SPI library
|
||||
#include <SX128XLT.h> //include the appropriate library
|
||||
#include "Settings.h" //include the setiings file, frequencies, LoRa settings etc
|
||||
|
||||
SX128XLT LT; //create a library class instance called LT
|
||||
|
||||
uint32_t RXpacketCount;
|
||||
uint32_t errors;
|
||||
|
||||
uint8_t RXBUFFER[RXBUFFER_SIZE]; //create the buffer that received packets are copied into
|
||||
|
||||
uint8_t RXPacketL; //stores length of packet received
|
||||
int8_t PacketRSSI; //stores RSSI of received packet
|
||||
int8_t PacketSNR; //stores signal to noise ratio of received packet
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
RXPacketL = LT.receive(RXBUFFER, RXBUFFER_SIZE, 60000, WAIT_RX); //wait for a packet to arrive with 60seconds (60000mS) timeout
|
||||
|
||||
digitalWrite(LED1, HIGH); //something has happened
|
||||
|
||||
if (BUZZER > 0) //turn buzzer on
|
||||
{
|
||||
digitalWrite(BUZZER, HIGH);
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
if (BUZZER > 0)
|
||||
{
|
||||
digitalWrite(BUZZER, LOW); //buzzer off
|
||||
}
|
||||
|
||||
digitalWrite(LED1, LOW); //LED off
|
||||
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
|
||||
void packet_is_OK()
|
||||
{
|
||||
uint16_t IRQStatus, localCRC;
|
||||
|
||||
IRQStatus = LT.readIrqStatus(); //read the LoRa device IRQ status register
|
||||
|
||||
RXpacketCount++;
|
||||
|
||||
printElapsedTime(); //print elapsed time to Serial Monitor
|
||||
Serial.print(F(" "));
|
||||
LT.printASCIIPacket(RXBUFFER, RXPacketL); //print the packet as ASCII characters
|
||||
|
||||
localCRC = LT.CRCCCITT(RXBUFFER, RXPacketL, 0xFFFF); //calculate the CRC, this is the external CRC calculation of the RXBUFFER
|
||||
Serial.print(F(",CRC,")); //contents, not the LoRa device internal CRC
|
||||
Serial.print(localCRC, HEX);
|
||||
Serial.print(F(",RSSI,"));
|
||||
Serial.print(PacketRSSI);
|
||||
Serial.print(F("dBm,SNR,"));
|
||||
Serial.print(PacketSNR);
|
||||
Serial.print(F("dB,Length,"));
|
||||
Serial.print(RXPacketL);
|
||||
Serial.print(F(",Packets,"));
|
||||
Serial.print(RXpacketCount);
|
||||
Serial.print(F(",Errors,"));
|
||||
Serial.print(errors);
|
||||
Serial.print(F(",IRQreg,"));
|
||||
Serial.print(IRQStatus, HEX);
|
||||
}
|
||||
|
||||
|
||||
void packet_is_Error()
|
||||
{
|
||||
uint16_t IRQStatus;
|
||||
IRQStatus = LT.readIrqStatus(); //read the LoRa device IRQ status register
|
||||
|
||||
printElapsedTime(); //print elapsed time to Serial Monitor
|
||||
|
||||
if (IRQStatus & IRQ_RX_TIMEOUT) //check for an RX timeout
|
||||
{
|
||||
Serial.print(F(" RXTimeout"));
|
||||
}
|
||||
else
|
||||
{
|
||||
errors++;
|
||||
Serial.print(F(" PacketError"));
|
||||
Serial.print(F(",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(",Packets,"));
|
||||
Serial.print(RXpacketCount);
|
||||
Serial.print(F(",Errors,"));
|
||||
Serial.print(errors);
|
||||
Serial.print(F(",IRQreg,"));
|
||||
Serial.print(IRQStatus, HEX);
|
||||
LT.printIrqStatus(); //print the names of the IRQ registers set
|
||||
}
|
||||
|
||||
delay(250); //gives a longer buzzer and LED flash for error
|
||||
|
||||
}
|
||||
|
||||
|
||||
void printElapsedTime()
|
||||
{
|
||||
float seconds;
|
||||
seconds = millis() / 1000;
|
||||
Serial.print(seconds, 0);
|
||||
Serial.print(F("s"));
|
||||
}
|
||||
|
||||
|
||||
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.print(F(__TIME__));
|
||||
Serial.print(F(" "));
|
||||
Serial.println(F(__DATE__));
|
||||
Serial.println(F(Program_Version));
|
||||
Serial.println();
|
||||
Serial.println(F("4_LoRa_Receiver Starting"));
|
||||
Serial.println();
|
||||
|
||||
if (BUZZER > 0)
|
||||
{
|
||||
pinMode(BUZZER, OUTPUT);
|
||||
digitalWrite(BUZZER, HIGH);
|
||||
delay(50);
|
||||
digitalWrite(BUZZER, LOW);
|
||||
}
|
||||
|
||||
SPI.begin();
|
||||
|
||||
//SPI beginTranscation is normally part of library routines, but if it is disabled in the library
|
||||
//a single instance is needed here, so uncomment the program line below
|
||||
//SPI.beginTransaction(SPISettings(8000000, MSBFIRST, SPI_MODE0));
|
||||
|
||||
//setup hardware pins used by device, then check if device is found
|
||||
if (LT.begin(NSS, NRESET, RFBUSY, DIO1, DIO2, DIO3, RX_EN, TX_EN, 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 LED flash indicates device error
|
||||
}
|
||||
}
|
||||
|
||||
//The function call list below shows the complete setup for the LoRa device using the information defined in the
|
||||
//Settings.h file.
|
||||
//The 'Setup LoRa device' list below can be replaced with a single function call;
|
||||
//LT.setupLoRa(Frequency, Offset, SpreadingFactor, Bandwidth, CodeRate);
|
||||
|
||||
//***************************************************************************************************
|
||||
//Setup LoRa device
|
||||
//***************************************************************************************************
|
||||
LT.setMode(MODE_STDBY_RC);
|
||||
LT.setRegulatorMode(USE_LDO);
|
||||
LT.setPacketType(PACKET_TYPE_LORA);
|
||||
LT.setRfFrequency(Frequency, Offset);
|
||||
LT.setBufferBaseAddress(0, 0);
|
||||
LT.setModulationParams(SpreadingFactor, Bandwidth, CodeRate);
|
||||
LT.setPacketParams(12, LORA_PACKET_VARIABLE_LENGTH, 255, LORA_CRC_ON, LORA_IQ_NORMAL, 0, 0);
|
||||
LT.setDioIrqParams(IRQ_RADIO_ALL, (IRQ_TX_DONE + IRQ_RX_TX_TIMEOUT), 0, 0);
|
||||
LT.setHighSensitivity();
|
||||
//LT.setLowPowerRX();
|
||||
//***************************************************************************************************
|
||||
|
||||
|
||||
Serial.println();
|
||||
LT.printModemSettings(); //reads and prints the configured LoRa settings, useful check
|
||||
Serial.println();
|
||||
LT.printOperatingSettings(); //reads and prints the configured operting settings, useful check
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
LT.printRegisters(0x900, 0x9FF); //print contents of device registers
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
|
||||
Serial.print(F("Receiver ready - RXBUFFER_SIZE "));
|
||||
Serial.println(RXBUFFER_SIZE);
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
/*******************************************************************************************************
|
||||
Programs for Arduino - Copyright of the author Stuart Robinson - 06/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. Some pins such as DIO2,
|
||||
//DIO3, BUZZER may not be in used by this sketch so they do not need to be
|
||||
//connected and should be included and be set to -1.
|
||||
|
||||
#define NSS 10
|
||||
#define RFBUSY 7
|
||||
#define NRESET 9
|
||||
#define LED1 8
|
||||
#define DIO1 3
|
||||
#define DIO2 -1 //not used
|
||||
#define DIO3 -1 //not used
|
||||
#define RX_EN -1 //pin for RX enable, used on some SX1280 devices, set to -1 if not used
|
||||
#define TX_EN -1 //pin for TX enable, used on some SX1280 devices, set to -1 if not used
|
||||
#define BUZZER -1 //pin for BUZZER, set to -1 if not used
|
||||
|
||||
#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 uint8_t TXpower = 10; //Power for transmissions in dBm
|
||||
|
||||
const uint16_t packet_delay = 1000; //mS delay between packets
|
||||
|
||||
#define RXBUFFER_SIZE 32 //RX buffer size
|
||||
|
||||
@@ -0,0 +1,180 @@
|
||||
/*******************************************************************************************************
|
||||
Programs for Arduino - Copyright of the author Stuart Robinson - 09/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 - This is a test transmitter for the Fast Long Range Communication (FLRC) mode
|
||||
introduced in the SX128X devices. A packet containing ASCII text is sent according to the frequency and
|
||||
FLRC settings specified in the 'Settings.h' file. The pins to access the SX128X device need to be defined
|
||||
in the 'Settings.h' file also.
|
||||
|
||||
The details of the packet sent and any errors are shown on the Serial Monitor, together with the transmit
|
||||
power used, the packet length and the CRC of the packet. The matching receive program, '53_FLRC_Receiver'
|
||||
can be used to check the packets are being sent correctly, the frequency and FLRC settings (in Settings.h)
|
||||
must be the same for the Transmit and Receive program. Sample Serial Monitor output;
|
||||
|
||||
10dBm Packet> {packet contents*} BytesSent,23 CRC,DAAB TransmitTime,54mS PacketsSent,1
|
||||
|
||||
Serial monitor baud rate is set at 9600
|
||||
*******************************************************************************************************/
|
||||
|
||||
#define Program_Version "V1.0"
|
||||
|
||||
#include <SPI.h> //the SX128X device is SPI based so load the SPI library
|
||||
#include <SX128XLT.h> //include the appropriate library
|
||||
#include "Settings.h" //include the setiings file, frequencies, LoRa settings etc
|
||||
|
||||
SX128XLT LT; //create a library class instance called LT
|
||||
|
||||
uint8_t TXPacketL;
|
||||
uint32_t TXPacketCount, startmS, endmS;
|
||||
|
||||
uint8_t buff[] = "Hello World 1234567890";
|
||||
|
||||
void loop()
|
||||
{
|
||||
Serial.print(TXpower); //print the transmit power defined
|
||||
Serial.print(F("dBm "));
|
||||
Serial.print(F("Packet> "));
|
||||
Serial.flush();
|
||||
|
||||
TXPacketL = sizeof(buff); //set TXPacketL to length of array
|
||||
buff[TXPacketL - 1] = '*'; //replace null character at buffer end so its visible on reciver
|
||||
|
||||
LT.printASCIIPacket(buff, TXPacketL); //print the buffer (the sent packet) as ASCII
|
||||
|
||||
digitalWrite(LED1, HIGH);
|
||||
startmS = millis(); //start transmit timer
|
||||
if (LT.transmit(buff, TXPacketL, 10000, TXpower, WAIT_TX)) //will return packet length sent if OK, otherwise 0 if transmit, timeout 10 seconds
|
||||
{
|
||||
endmS = millis(); //packet sent, note end time
|
||||
TXPacketCount++;
|
||||
packet_is_OK();
|
||||
}
|
||||
else
|
||||
{
|
||||
packet_is_Error(); //transmit packet returned 0, there was an error
|
||||
}
|
||||
|
||||
digitalWrite(LED1, LOW);
|
||||
Serial.println();
|
||||
delay(packet_delay); //have a delay between packets
|
||||
}
|
||||
|
||||
|
||||
void packet_is_OK()
|
||||
{
|
||||
//if here packet has been sent OK
|
||||
uint16_t localCRC;
|
||||
|
||||
Serial.print(F(" BytesSent,"));
|
||||
Serial.print(TXPacketL); //print transmitted packet length
|
||||
localCRC = LT.CRCCCITT(buff, TXPacketL, 0xFFFF);
|
||||
Serial.print(F(" CRC,"));
|
||||
Serial.print(localCRC, HEX); //print CRC of sent packet
|
||||
Serial.print(F(" TransmitTime,"));
|
||||
Serial.print(endmS - startmS); //print transmit time of packet
|
||||
Serial.print(F("mS"));
|
||||
Serial.print(F(" PacketsSent,"));
|
||||
Serial.print(TXPacketCount); //print total of packets sent OK
|
||||
}
|
||||
|
||||
|
||||
void packet_is_Error()
|
||||
{
|
||||
//if here there was an error transmitting packet
|
||||
uint16_t IRQStatus;
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
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.print(F(__TIME__));
|
||||
Serial.print(F(" "));
|
||||
Serial.println(F(__DATE__));
|
||||
Serial.println(F(Program_Version));
|
||||
Serial.println();
|
||||
Serial.println(F("52_FLRC_Transmitter Starting"));
|
||||
|
||||
SPI.begin();
|
||||
|
||||
//SPI beginTranscation is normally part of library routines, but if it is disabled in library
|
||||
//a single instance is needed here, so uncomment the program line below
|
||||
//SPI.beginTransaction(SPISettings(8000000, MSBFIRST, SPI_MODE0));
|
||||
|
||||
//setup hardware pins used by device, then check if device is found
|
||||
if (LT.begin(NSS, NRESET, RFBUSY, DIO1, DIO2, DIO3, RX_EN, TX_EN, LORA_DEVICE))
|
||||
{
|
||||
Serial.println(F("LoRa Device found"));
|
||||
led_Flash(2, 125); //two further quick LED flashes to indicate device found
|
||||
delay(1000);
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println(F("No device responding"));
|
||||
while (1)
|
||||
{
|
||||
led_Flash(50, 50); //long fast speed LED flash indicates device error
|
||||
}
|
||||
}
|
||||
|
||||
//The function call list below shows the complete setup for the LoRa device using the information defined in the
|
||||
//Settings.h file.
|
||||
|
||||
//***************************************************************************************************
|
||||
//Setup FLRC
|
||||
//***************************************************************************************************
|
||||
LT.setMode(MODE_STDBY_RC);
|
||||
LT.setRegulatorMode(USE_LDO);
|
||||
LT.setPacketType(PACKET_TYPE_FLRC);
|
||||
LT.setRfFrequency(Frequency, Offset);
|
||||
LT.setBufferBaseAddress(0, 0);
|
||||
LT.setModulationParams(BandwidthBitRate, CodingRate, BT);
|
||||
LT.setPacketParams(PREAMBLE_LENGTH_32_BITS, FLRC_SYNC_WORD_LEN_P32S, RADIO_RX_MATCH_SYNCWORD_1, RADIO_PACKET_VARIABLE_LENGTH, 127, RADIO_CRC_3_BYTES, RADIO_WHITENING_OFF);
|
||||
LT.setDioIrqParams(IRQ_RADIO_ALL, (IRQ_TX_DONE + IRQ_RX_TX_TIMEOUT), 0, 0); //set for IRQ on TX done and timeout on DIO1
|
||||
LT.setSyncWord1(Sample_Syncword);
|
||||
//***************************************************************************************************
|
||||
|
||||
Serial.println();
|
||||
LT.printModemSettings(); //reads and prints the configured modem settings, useful check
|
||||
Serial.println();
|
||||
LT.printOperatingSettings(); //reads and prints the configured operating settings, useful check
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
LT.printRegisters(0x900, 0x9FF); //print contents of device registers
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
|
||||
Serial.print(F("Transmitter ready"));
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
/*******************************************************************************************************
|
||||
Programs for Arduino - Copyright of the author Stuart Robinson - 06/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. Some pins such as DIO2,
|
||||
//DIO3, BUZZER may not be in used by this sketch so they do not need to be
|
||||
//connected and should be included and be set to -1.
|
||||
|
||||
#define NSS 10
|
||||
#define RFBUSY 7
|
||||
#define NRESET 9
|
||||
#define LED1 8
|
||||
#define DIO1 3
|
||||
#define DIO2 -1 //not used
|
||||
#define DIO3 -1 //not used
|
||||
#define RX_EN -1 //pin for RX enable, used on some SX1280 devices, set to -1 if not used
|
||||
#define TX_EN -1 //pin for TX enable, used on some SX1280 devices, set to -1 if not used
|
||||
#define BUZZER -1 //connect a buzzer here if wanted
|
||||
|
||||
#define LORA_DEVICE DEVICE_SX1280 //we need to define the device we are using
|
||||
|
||||
//FLRC Modem Parameters
|
||||
const uint32_t Frequency = 2445000000; //frequency of transmissions
|
||||
const int32_t Offset = 0; //offset frequency for calibration purposes
|
||||
|
||||
const uint8_t BandwidthBitRate = FLRC_BR_1_300_BW_1_2; //FLRC bandwidth and bit rate, 1.3Mbs
|
||||
const uint8_t CodingRate = FLRC_CR_1_2; //FLRC coding rate
|
||||
const uint8_t BT = RADIO_MOD_SHAPING_BT_1_0; //FLRC BT
|
||||
const uint32_t Sample_Syncword = 0x01234567; //FLRC uses syncword
|
||||
|
||||
|
||||
const int8_t TXpower = 0; //power for transmissions in dBm
|
||||
|
||||
const uint16_t packet_delay = 1000; //mS delay between packets
|
||||
@@ -0,0 +1,240 @@
|
||||
/*******************************************************************************************************
|
||||
Programs for Arduino - Copyright of the author Stuart Robinson - 09/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 - This is a test receiver for the Fast Long Range Communication (FLRC) mode introduced
|
||||
in the SX128X devices. The program listens for incoming packets using the FLRC settings in the 'Settings.h'
|
||||
file. The pins to access the SX128X device need to be defined in the 'Settings.h' file also.
|
||||
|
||||
There is a printout of the valid packets received, the packet is assumed to be in ASCII printable text,
|
||||
if its not ASCII text characters from 0x20 to 0x7F, expect weird things to happen on the Serial Monitor.
|
||||
The LED will flash for each packet received and the buzzer will sound, if fitted.
|
||||
|
||||
Sample serial monitor output;
|
||||
|
||||
3s Hello World 1234567890*,CRC,DAAB,RSSI,-73dB,Length,23,Packets,1,Errors,0,IRQreg,6
|
||||
|
||||
If there is a packet error it might look like this, which is showing a CRC error,
|
||||
|
||||
6s PacketError,RSSI,-103dB,Length,119,Packets,3,Errors,1,IRQreg,46,IRQ_RX_DONE,IRQ_SYNCWORD_VALID,IRQ_CRC_ERROR
|
||||
|
||||
Serial monitor baud rate is set at 9600.
|
||||
*******************************************************************************************************/
|
||||
|
||||
#define Program_Version "V1.0"
|
||||
|
||||
#include <SPI.h> //the lora device is SPI based so load the SPI library
|
||||
#include <SX128XLT.h> //include the appropriate library
|
||||
#include "Settings.h" //include the setiings file, frequencies, LoRa settings etc
|
||||
|
||||
SX128XLT LT; //create a library class instance called LT
|
||||
|
||||
uint32_t RXpacketCount;
|
||||
uint32_t errors;
|
||||
|
||||
uint8_t RXBUFFER[RXBUFFER_SIZE]; //create the buffer that received packets are copied into
|
||||
|
||||
uint8_t RXPacketL; //stores length of packet received
|
||||
int8_t PacketRSSI; //stores RSSI of received packet
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
RXPacketL = LT.receive(RXBUFFER, RXBUFFER_SIZE, 60000, WAIT_RX); //wait for a packet to arrive with 60seconds (60000mS) timeout
|
||||
|
||||
digitalWrite(LED1, HIGH); //something has happened
|
||||
|
||||
if (BUZZER > 0) //turn buzzer on
|
||||
{
|
||||
digitalWrite(BUZZER, HIGH);
|
||||
}
|
||||
|
||||
PacketRSSI = LT.readPacketRSSI(); //read the recived RSSI value
|
||||
|
||||
if (RXPacketL == 0) //if the LT.receive() function detects an error, RXpacketL == 0
|
||||
{
|
||||
packet_is_Error();
|
||||
}
|
||||
else
|
||||
{
|
||||
packet_is_OK();
|
||||
}
|
||||
|
||||
if (BUZZER > 0)
|
||||
{
|
||||
digitalWrite(BUZZER, LOW); //buzzer off
|
||||
}
|
||||
|
||||
digitalWrite(LED1, LOW); //LED off
|
||||
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
|
||||
void packet_is_OK()
|
||||
{
|
||||
uint16_t IRQStatus, localCRC;
|
||||
|
||||
IRQStatus = LT.readIrqStatus(); //read the LoRa device IRQ status register
|
||||
|
||||
RXpacketCount++;
|
||||
|
||||
printElapsedTime(); //print elapsed time to Serial Monitor
|
||||
Serial.print(F(" "));
|
||||
LT.printASCIIPacket(RXBUFFER, RXPacketL); //print the packet as ASCII characters
|
||||
|
||||
localCRC = LT.CRCCCITT(RXBUFFER, RXPacketL, 0xFFFF); //calculate the CRC, this is the external CRC calculation of the RXBUFFER
|
||||
Serial.print(F(",CRC,")); //contents, not the LoRa device internal CRC
|
||||
Serial.print(localCRC, HEX);
|
||||
Serial.print(F(",RSSI,"));
|
||||
Serial.print(PacketRSSI);
|
||||
Serial.print(F("dB,Length,"));
|
||||
Serial.print(RXPacketL);
|
||||
Serial.print(F(",Packets,"));
|
||||
Serial.print(RXpacketCount);
|
||||
Serial.print(F(",Errors,"));
|
||||
Serial.print(errors);
|
||||
Serial.print(F(",IRQreg,"));
|
||||
Serial.print(IRQStatus, HEX);
|
||||
}
|
||||
|
||||
|
||||
void packet_is_Error()
|
||||
{
|
||||
uint16_t IRQStatus;
|
||||
IRQStatus = LT.readIrqStatus(); //read the LoRa device IRQ status register
|
||||
|
||||
printElapsedTime(); //print elapsed time to Serial Monitor
|
||||
|
||||
if (IRQStatus & IRQ_RX_TIMEOUT) //check for an RX timeout
|
||||
{
|
||||
Serial.print(F(" RXTimeout"));
|
||||
}
|
||||
else
|
||||
{
|
||||
errors++;
|
||||
Serial.print(F(" PacketError"));
|
||||
Serial.print(F(",RSSI,"));
|
||||
Serial.print(PacketRSSI);
|
||||
Serial.print(F("dB,Length,"));
|
||||
Serial.print(LT.readRXPacketL()); //get the real packet length
|
||||
Serial.print(F(",Packets,"));
|
||||
Serial.print(RXpacketCount);
|
||||
Serial.print(F(",Errors,"));
|
||||
Serial.print(errors);
|
||||
Serial.print(F(",IRQreg,"));
|
||||
Serial.print(IRQStatus, HEX);
|
||||
LT.printIrqStatus(); //print the names of the IRQ registers set
|
||||
}
|
||||
|
||||
delay(250); //gives a longer buzzer and LED flash for error
|
||||
|
||||
}
|
||||
|
||||
|
||||
void printElapsedTime()
|
||||
{
|
||||
float seconds;
|
||||
seconds = millis() / 1000;
|
||||
Serial.print(seconds, 0);
|
||||
Serial.print(F("s"));
|
||||
}
|
||||
|
||||
|
||||
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.print(F(__TIME__));
|
||||
Serial.print(F(" "));
|
||||
Serial.println(F(__DATE__));
|
||||
Serial.println(F(Program_Version));
|
||||
Serial.println();
|
||||
Serial.println(F("53_FLRC_Receiver Starting"));
|
||||
Serial.println();
|
||||
|
||||
if (BUZZER > 0)
|
||||
{
|
||||
pinMode(BUZZER, OUTPUT);
|
||||
digitalWrite(BUZZER, HIGH);
|
||||
delay(50);
|
||||
digitalWrite(BUZZER, LOW);
|
||||
}
|
||||
|
||||
SPI.begin();
|
||||
|
||||
//SPI beginTranscation is normally part of library routines, but if it is disabled in the library
|
||||
//a single instance is needed here, so uncomment the program line below
|
||||
//SPI.beginTransaction(SPISettings(8000000, MSBFIRST, SPI_MODE0));
|
||||
|
||||
//setup hardware pins used by device, then check if device is found
|
||||
if (LT.begin(NSS, NRESET, RFBUSY, DIO1, DIO2, DIO3, RX_EN, TX_EN, 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 LED flash indicates device error
|
||||
}
|
||||
}
|
||||
|
||||
//The function call list below shows the complete setup for the LoRa device using the information defined in the
|
||||
//Settings.h file.
|
||||
|
||||
//***************************************************************************************************
|
||||
//Setup FLRC
|
||||
//***************************************************************************************************
|
||||
LT.setMode(MODE_STDBY_RC);
|
||||
LT.setRegulatorMode(USE_LDO);
|
||||
LT.setPacketType(PACKET_TYPE_FLRC);
|
||||
LT.setRfFrequency(Frequency, Offset);
|
||||
LT.setBufferBaseAddress(0, 0);
|
||||
LT.setModulationParams(BandwidthBitRate, CodingRate, BT);
|
||||
LT.setPacketParams(PREAMBLE_LENGTH_32_BITS, FLRC_SYNC_WORD_LEN_P32S, RADIO_RX_MATCH_SYNCWORD_1, RADIO_PACKET_VARIABLE_LENGTH, 127, RADIO_CRC_3_BYTES, RADIO_WHITENING_OFF);
|
||||
LT.setDioIrqParams(IRQ_RADIO_ALL, (IRQ_TX_DONE + IRQ_RX_TX_TIMEOUT), 0, 0); //set for IRQ on TX done and timeout on DIO1
|
||||
LT.setSyncWord1(Sample_Syncword);
|
||||
//***************************************************************************************************
|
||||
|
||||
|
||||
Serial.println();
|
||||
LT.printModemSettings(); //reads and prints the configured modem settings, useful check
|
||||
Serial.println();
|
||||
LT.printOperatingSettings(); //reads and prints the configured operting settings, useful check
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
LT.printRegisters(0x900, 0x9FF); //print contents of device registers
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
|
||||
Serial.print(F("Receiver ready - RXBUFFER_SIZE "));
|
||||
Serial.println(RXBUFFER_SIZE);
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
/*******************************************************************************************************
|
||||
Programs for Arduino - Copyright of the author Stuart Robinson - 06/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. Some pins such as DIO2,
|
||||
//DIO3, BUZZER may not be in used by this sketch so they do not need to be
|
||||
//connected and should be included and be set to -1.
|
||||
|
||||
#define NSS 10
|
||||
#define RFBUSY 7
|
||||
#define NRESET 9
|
||||
#define LED1 8
|
||||
#define DIO1 3
|
||||
#define DIO2 -1 //not used
|
||||
#define DIO3 -1 //not used
|
||||
#define RX_EN -1 //pin for RX enable, used on some SX1280 devices, set to -1 if not used
|
||||
#define TX_EN -1 //pin for TX enable, used on some SX1280 devices, set to -1 if not used
|
||||
#define BUZZER -1 //connect a buzzer here if wanted
|
||||
|
||||
#define LORA_DEVICE DEVICE_SX1280 //we need to define the device we are using
|
||||
|
||||
//FLRC Modem Parameters
|
||||
const uint32_t Frequency = 2445000000; //frequency of transmissions
|
||||
const int32_t Offset = 0; //offset frequency for calibration purposes
|
||||
|
||||
const uint8_t BandwidthBitRate = FLRC_BR_1_300_BW_1_2; //FLRC bandwidth and bit rate, 1.3Mbs
|
||||
const uint8_t CodingRate = FLRC_CR_1_2; //FLRC coding rate
|
||||
const uint8_t BT = RADIO_MOD_SHAPING_BT_1_0; //FLRC BT
|
||||
const uint32_t Sample_Syncword = 0x01234567; //FLRC uses syncword
|
||||
|
||||
const int8_t TXpower = 0; //power for transmissions in dBm
|
||||
|
||||
const uint16_t packet_delay = 1000; //mS delay between packets
|
||||
|
||||
#define RXBUFFER_SIZE 32 //RX buffer size
|
||||
|
||||
@@ -0,0 +1,266 @@
|
||||
/*******************************************************************************************************
|
||||
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 is a program that can be used to test the effectiveness of a LoRa link or its
|
||||
attached antennas. Simulations of antenna performance are no substitute for real world tests and this
|
||||
simple program allows both long distance link performance to be evaluated and antenna performance to be
|
||||
compared.
|
||||
|
||||
The program sends short test packets that reduce in power by 1dBm at a time. The start power is defined
|
||||
by start_power and the end power is defined by end_power (see Settings.h file). Once the end_power point
|
||||
is reached, the program pauses a short while and starts the transmit sequence again at start_power.
|
||||
The packet sent contains the power used to send the packet. By listening for the packets with the basic
|
||||
LoRa receive program (4_LoRa_Receiver) you can see the reception results, which should look something
|
||||
like this;
|
||||
|
||||
11s 1*T+05,CRC,80B8,RSSI,-73dBm,SNR,9dB,Length,6,Packets,9,Errors,0,IRQreg,50
|
||||
12s 1*T+04,CRC,9099,RSSI,-74dBm,SNR,9dB,Length,6,Packets,10,Errors,0,IRQreg,50
|
||||
14s 1*T+03,CRC,E07E,RSSI,-75dBm,SNR,9dB,Length,6,Packets,11,Errors,0,IRQreg,50
|
||||
|
||||
Above shows 3 packets received, the first at +05dBm (+05 in printout), the second at 4dBm (+04 in
|
||||
printout) and the third at 3dBm (+03) in printout.
|
||||
|
||||
If it is arranged so that reception of packets fails halfway through the sequence by attenuating either the
|
||||
transmitter (with an SMA attenuator for instance) or the receiver (by placing it in a tin perhaps) then
|
||||
if you swap transmitter antennas you can see the dBm difference in reception, which will be the dBm difference
|
||||
(gain) of the antenna.
|
||||
|
||||
To start the sequence a packet is sent with the number 999, when received it looks like this;
|
||||
|
||||
T*1999
|
||||
|
||||
This received packet could be used for the RX program to be able to print totals etc.
|
||||
|
||||
LoRa settings to use for the link test are specified in the 'Settings.h' file.
|
||||
|
||||
Serial monitor baud rate is set at 9600.
|
||||
*******************************************************************************************************/
|
||||
|
||||
#define Program_Version "V1.0"
|
||||
|
||||
#include <SPI.h>
|
||||
#include <SX128XLT.h>
|
||||
#include <ProgramLT_Definitions.h>
|
||||
#include "Settings.h"
|
||||
|
||||
SX128XLT LT;
|
||||
|
||||
int8_t TestPower;
|
||||
uint8_t TXPacketL;
|
||||
|
||||
void loop()
|
||||
{
|
||||
Serial.println(F("Start Test Sequence"));
|
||||
Serial.print(TXpower);
|
||||
Serial.print(F("dBm "));
|
||||
Serial.print(F("Start Packet> "));
|
||||
|
||||
SendTest1ModePacket();
|
||||
|
||||
Serial.println();
|
||||
|
||||
for (TestPower = start_power; TestPower >= end_power; TestPower--)
|
||||
{
|
||||
Serial.print(TestPower);
|
||||
Serial.print(F("dBm "));
|
||||
Serial.print(F("Test Packet> "));
|
||||
Serial.flush();
|
||||
SendTestPacket(TestPower);
|
||||
Serial.println();
|
||||
delay(packet_delay);
|
||||
}
|
||||
|
||||
Serial.println(F("Finished Test Sequence"));
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
|
||||
void SendTestPacket(int8_t lpower)
|
||||
{
|
||||
//build and send the test packet in addressed form, 3 bytes will be added to begining of packet
|
||||
int8_t temppower;
|
||||
uint8_t buff[3]; //the packet is built in this buffer
|
||||
TXPacketL = sizeof(buff);
|
||||
|
||||
if (lpower < 0)
|
||||
{
|
||||
buff[0] = '-';
|
||||
}
|
||||
else
|
||||
{
|
||||
buff[0] = '+';
|
||||
}
|
||||
|
||||
if (TestPower == 0)
|
||||
{
|
||||
buff[0] = ' ';
|
||||
}
|
||||
|
||||
temppower = TestPower;
|
||||
|
||||
if (temppower < 0)
|
||||
{
|
||||
temppower = -temppower;
|
||||
}
|
||||
|
||||
if (temppower > 19)
|
||||
{
|
||||
buff[1] = '2';
|
||||
buff[2] = ((temppower - 20) + 0x30);
|
||||
}
|
||||
else if (temppower > 9)
|
||||
{
|
||||
buff[1] = '1';
|
||||
buff[2] = ((temppower - 10) + 0x30);
|
||||
}
|
||||
else
|
||||
{
|
||||
buff[1] = '0';
|
||||
buff[2] = (temppower + 0x30);
|
||||
}
|
||||
|
||||
LT.printASCIIPacket(buff, sizeof(buff));
|
||||
|
||||
digitalWrite(LED1, HIGH);
|
||||
TXPacketL = LT.transmitAddressed(buff, sizeof(buff), TestPacket, Broadcast, ThisNode, 5000, lpower, WAIT_TX);
|
||||
digitalWrite(LED1, LOW);
|
||||
|
||||
if (TXPacketL == 0)
|
||||
{
|
||||
packet_is_Error();
|
||||
}
|
||||
else
|
||||
{
|
||||
packet_is_OK();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SendTest1ModePacket()
|
||||
{
|
||||
//used to allow an RX to recognise the start off the sequence and possibly print totals
|
||||
|
||||
uint8_t buff[3]; //the packet is built in this buffer
|
||||
|
||||
buff[0] = '9';
|
||||
buff[1] = '9';
|
||||
buff[2] = '9';
|
||||
TXPacketL = sizeof(buff);
|
||||
|
||||
LT.printASCIIPacket(buff, sizeof(buff));
|
||||
|
||||
digitalWrite(LED1, HIGH);
|
||||
TXPacketL = LT.transmitAddressed(buff, sizeof(buff), TestMode1, Broadcast, ThisNode, 5000, start_power, WAIT_TX);
|
||||
delay(mode_delaymS); //longer delay, so that the start test sequence is obvious
|
||||
digitalWrite(LED1, LOW);
|
||||
|
||||
if (TXPacketL == 0)
|
||||
{
|
||||
packet_is_Error();
|
||||
}
|
||||
else
|
||||
{
|
||||
packet_is_OK();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void packet_is_OK()
|
||||
{
|
||||
uint16_t IRQStatus;
|
||||
IRQStatus = LT.readIrqStatus(); //get the IRQ status
|
||||
Serial.print(F(" "));
|
||||
Serial.print(TXPacketL);
|
||||
Serial.print(F(" Bytes SentOK"));
|
||||
Serial.print(F(",IRQreg,"));
|
||||
Serial.print(IRQStatus, HEX);
|
||||
LT.printIrqStatus();
|
||||
}
|
||||
|
||||
|
||||
void packet_is_Error()
|
||||
{
|
||||
uint16_t IRQStatus;
|
||||
IRQStatus = LT.readIrqStatus(); //get the IRQ status
|
||||
Serial.print(F(" SendError,"));
|
||||
Serial.print(F("Length,"));
|
||||
Serial.print(TXPacketL);
|
||||
Serial.print(F(",IRQreg,"));
|
||||
Serial.print(IRQStatus, HEX);
|
||||
LT.printIrqStatus();
|
||||
delay(packet_delay); //change LED flash so packet error visible
|
||||
delay(packet_delay);
|
||||
digitalWrite(LED1, HIGH);
|
||||
delay(packet_delay);
|
||||
delay(packet_delay);
|
||||
digitalWrite(LED1, LOW);
|
||||
}
|
||||
|
||||
|
||||
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.print(__TIME__);
|
||||
Serial.print(F(" "));
|
||||
Serial.println(__DATE__);
|
||||
Serial.println(F(Program_Version));
|
||||
Serial.println();
|
||||
|
||||
Serial.println(F("10_LoRa_Link_Test_Transmitter Starting"));
|
||||
|
||||
SPI.begin();
|
||||
|
||||
if (LT.begin(NSS, NRESET, RFBUSY, DIO1, DIO2, DIO3, RX_EN, TX_EN, LORA_DEVICE))
|
||||
{
|
||||
Serial.println(F("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 operting settings, useful check
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
LT.printRegisters(0x900, 0x9FF); //print contents of device registers
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
|
||||
Serial.print(F("Transmitter ready"));
|
||||
Serial.println();
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
/*******************************************************************************************************
|
||||
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 definitiosn to match your own setup. Some pins such as DIO2,
|
||||
//DIO3 may not be in used by this sketch so they do not need to be connected and should
|
||||
//be set to -1.
|
||||
|
||||
#define NSS 10 //select pin on LoRa device
|
||||
#define NRESET 9 //reset pin on LoRa device
|
||||
#define LED1 8 //on board LED, high for on
|
||||
#define RFBUSY 7 //SX128X busy pin
|
||||
#define DIO1 3 //DIO1 pin on LoRa device, used for RX and TX done
|
||||
#define DIO2 -1 //DIO2 pin on LoRa device, normally not used so set to -1
|
||||
#define DIO3 -1 //DIO3 pin on LoRa device, normally not used so set to -1
|
||||
#define RX_EN -1 //pin for RX enable, used on some SX128X devices, set to -1 if not used
|
||||
#define TX_EN -1 //pin for TX enable, used on some SX128X devices, 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
|
||||
#define Frequency 2445000000 //frequency of transmissions
|
||||
#define Offset 0 //offset frequency for calibration purposes
|
||||
#define Bandwidth LORA_BW_0400 //LoRa bandwidth
|
||||
#define SpreadingFactor LORA_SF7 //LoRa spreading factor
|
||||
#define CodeRate LORA_CR_4_5 //LoRa coding rate
|
||||
|
||||
const int8_t TXpower = 10; //Transmit power used when sending packet starting test sequence
|
||||
const int8_t start_power = 10; //link test starts at this transmit power, maximum +12dBm
|
||||
const int8_t end_power = -18; //and ends at this power, minimum -18dBm
|
||||
const uint8_t ThisNode = 'T'; //this identifies the node in transmissions
|
||||
|
||||
|
||||
#define packet_delay 250 //mS delay between packets
|
||||
#define mode_delaymS 2000 //mS delay after sending start test sequence
|
||||
|
||||
|
||||
@@ -0,0 +1,223 @@
|
||||
/*******************************************************************************************************
|
||||
Programs for Arduino - Copyright of the author Stuart Robinson - 01/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 - The program listens for incoming packets using the LoRa settings in the 'Settings.h'
|
||||
file. The pins to access the lora device need to be defined in the 'Settings.h' file also.
|
||||
|
||||
There is a printout of the valid packets received in HEX format. Thus the program can be used to receive
|
||||
and record non-ASCII packets. The LED will flash for each packet received and the buzzer will sound,
|
||||
if fitted. The measured frequency difference between the frequency used by the transmitter and the
|
||||
frequency used by the receiver is shown. If this frequency difference gets to 25% of the set LoRa
|
||||
bandwidth, packet reception will fail. The displayed error can be reduced by using the 'offset'
|
||||
setting in the 'Settings.h' file.
|
||||
|
||||
Serial monitor baud rate is set at 9600.
|
||||
*******************************************************************************************************/
|
||||
|
||||
#define Program_Version "V1.0"
|
||||
|
||||
#include <SPI.h>
|
||||
#include <SX128XLT.h>
|
||||
#include "Settings.h"
|
||||
#include <TimeLib.h> //get the library here; https://github.com/PaulStoffregen/Time
|
||||
time_t recordtime; //used to record the current time, preventing displayed rollover on printing
|
||||
|
||||
SX128XLT LT;
|
||||
|
||||
uint32_t RXpacketCount;
|
||||
uint32_t errors;
|
||||
|
||||
uint8_t RXPacketL; //stores length of packet received
|
||||
int8_t PacketRSSI; //stores RSSI of received packet
|
||||
int8_t PacketSNR; //stores signal to noise ratio of received packet
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
RXPacketL = LT.receiveSXBuffer(0, 60000, WAIT_RX); //returns 0 if packet error of some sort, timeout set at 60secs\60000mS
|
||||
|
||||
digitalWrite(LED1, HIGH); //something has happened
|
||||
recordtime = now(); //stop the time to be displayed rolling over
|
||||
printtime();
|
||||
|
||||
PacketRSSI = LT.readPacketRSSI();
|
||||
PacketSNR = LT.readPacketSNR();
|
||||
|
||||
if (RXPacketL == 0)
|
||||
{
|
||||
packet_is_Error();
|
||||
}
|
||||
else
|
||||
{
|
||||
packet_is_OK();
|
||||
}
|
||||
|
||||
digitalWrite(LED1, LOW);
|
||||
|
||||
if (BUZZER > 0)
|
||||
{
|
||||
delay(50); //lets have a slightly longer beep
|
||||
digitalWrite(BUZZER, LOW);
|
||||
}
|
||||
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
|
||||
void packet_is_OK()
|
||||
{
|
||||
uint16_t IRQStatus;
|
||||
IRQStatus = LT.readIrqStatus();
|
||||
|
||||
RXpacketCount++;
|
||||
|
||||
if (BUZZER > 0)
|
||||
{
|
||||
digitalWrite(BUZZER, HIGH);
|
||||
}
|
||||
|
||||
Serial.print(F(" FreqErrror,"));
|
||||
Serial.print(LT.getFrequencyErrorHz());
|
||||
Serial.print(F("hz "));
|
||||
|
||||
LT.printSXBufferHEX(0, (RXPacketL - 1));
|
||||
|
||||
Serial.print(F(" RSSI,"));
|
||||
Serial.print(PacketRSSI);
|
||||
Serial.print(F("dBm,SNR,"));
|
||||
Serial.print(PacketSNR);
|
||||
Serial.print(F("dB,Length,"));
|
||||
Serial.print(RXPacketL);
|
||||
Serial.print(F(",Packets,"));
|
||||
Serial.print(RXpacketCount);
|
||||
Serial.print(F(",Errors,"));
|
||||
Serial.print(errors);
|
||||
Serial.print(F(",IRQreg,"));
|
||||
Serial.print(IRQStatus, HEX);
|
||||
}
|
||||
|
||||
|
||||
void packet_is_Error()
|
||||
{
|
||||
uint16_t IRQStatus;
|
||||
IRQStatus = LT.readIrqStatus(); //get the IRQ status
|
||||
|
||||
if (IRQStatus & IRQ_RX_TIMEOUT)
|
||||
{
|
||||
Serial.print(F(" RXTimeout"));
|
||||
}
|
||||
else
|
||||
{
|
||||
errors++;
|
||||
Serial.print(F(" PacketError"));
|
||||
Serial.print(F(",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(",Packets,"));
|
||||
Serial.print(RXpacketCount);
|
||||
Serial.print(F(",Errors,"));
|
||||
Serial.print(errors);
|
||||
Serial.print(F(",IRQreg,"));
|
||||
Serial.print(IRQStatus, HEX);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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 printDigits(int8_t digits)
|
||||
{
|
||||
//utility function for digital clock display: prints preceding colon and leading 0
|
||||
Serial.print(F(":"));
|
||||
if (digits < 10)
|
||||
Serial.print('0');
|
||||
Serial.print(digits);
|
||||
}
|
||||
|
||||
|
||||
void printtime()
|
||||
{
|
||||
Serial.print(hour(recordtime));
|
||||
printDigits(minute(recordtime));
|
||||
printDigits(second(recordtime));
|
||||
}
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
pinMode(LED1, OUTPUT);
|
||||
led_Flash(2, 125);
|
||||
|
||||
Serial.begin(9600);
|
||||
Serial.println();
|
||||
Serial.print(__TIME__);
|
||||
Serial.print(F(" "));
|
||||
Serial.println(__DATE__);
|
||||
Serial.println(F(Program_Version));
|
||||
Serial.println();
|
||||
|
||||
Serial.println(F("11_LoRa_Packet_Logger_Receiver Starting"));
|
||||
Serial.println();
|
||||
|
||||
if (BUZZER > 0)
|
||||
{
|
||||
pinMode(BUZZER, OUTPUT);
|
||||
digitalWrite(BUZZER, HIGH);
|
||||
delay(50);
|
||||
digitalWrite(BUZZER, LOW);
|
||||
}
|
||||
|
||||
SPI.begin();
|
||||
|
||||
//SPI beginTranscation is normally part of library routines, but if it is disabled in library
|
||||
//a single instance is needed here, so uncomment the program line below
|
||||
//SPI.beginTransaction(SPISettings(8000000, MSBFIRST, SPI_MODE0));
|
||||
|
||||
if (LT.begin(NSS, NRESET, RFBUSY, DIO1, DIO2, DIO3, RX_EN, TX_EN, LORA_DEVICE))
|
||||
{
|
||||
Serial.println(F("Radio Device found"));
|
||||
led_Flash(2, 125);
|
||||
delay(1000);
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println(F("No device responding"));
|
||||
while (1)
|
||||
{
|
||||
led_Flash(50, 50);
|
||||
}
|
||||
}
|
||||
|
||||
LT.setupLoRa(Frequency, Offset, SpreadingFactor, Bandwidth, CodeRate);
|
||||
|
||||
Serial.println();
|
||||
LT.printModemSettings();
|
||||
Serial.println();
|
||||
LT.printOperatingSettings();
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
printtime();
|
||||
Serial.print(F(" Receiver ready"));
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
/*******************************************************************************************************
|
||||
Programs for Arduino - Copyright of the author Stuart Robinson - 01/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. Some pins such as DIO2,
|
||||
//DIO3, 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 10
|
||||
#define RFBUSY 7
|
||||
#define NRESET 9
|
||||
#define LED1 8
|
||||
#define DIO1 3
|
||||
#define DIO2 -1 //not used
|
||||
#define DIO3 -1 //not used
|
||||
#define RX_EN -1 //pin for RX enable, used on some SX1280 devices, set to -1 if not used
|
||||
#define TX_EN -1 //pin for TX enable, used on some SX1280 devices, set to -1 if not used
|
||||
#define BUZZER -1 //pin for buzzer, 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_0400; //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 TXpower = 10; //Power for transmissions in dBm
|
||||
|
||||
#define packet_delay 1000 //mS delay between packets
|
||||
|
||||
@@ -0,0 +1,183 @@
|
||||
/*******************************************************************************************************
|
||||
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 - This program can be used to check the frequency error between a pair of LoRa
|
||||
devices, a transmitter and receiver. This receiver measures the frequecy error between the receivers
|
||||
centre frequency and the centre frequency of the transmitted packet. The frequency difference is shown
|
||||
for each packet and an average over 10 received packets reported. Any transmitter program can be used
|
||||
to give this program something to listen to, including example program '3_LoRa_Transmit'.
|
||||
|
||||
Serial monitor baud rate is set at 9600.
|
||||
*******************************************************************************************************/
|
||||
|
||||
|
||||
#define Program_Version "V1.0"
|
||||
|
||||
#include <SPI.h>
|
||||
#include <SX128XLT.h>
|
||||
#include "Settings.h"
|
||||
|
||||
SX128XLT LT;
|
||||
|
||||
uint32_t RXpacketCount;
|
||||
uint32_t errors;
|
||||
|
||||
uint8_t RXBUFFER[RXBUFFER_SIZE]; //a buffer is needed to receive packets
|
||||
|
||||
uint8_t RXPacketL; //stores length of packet received
|
||||
int8_t PacketRSSI; //stores RSSI of received packet
|
||||
int8_t PacketSNR; //stores signal to noise ratio of received packet
|
||||
int32_t totalHzError = 0; //used to keep a running total of hZ error for averaging
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
|
||||
RXPacketL = LT.receive(RXBUFFER, RXBUFFER_SIZE, 0, WAIT_RX); //wait for a packet to arrive
|
||||
|
||||
digitalWrite(LED1, HIGH); //something has happened
|
||||
|
||||
PacketRSSI = LT.readPacketRSSI();
|
||||
PacketSNR = LT.readPacketSNR();
|
||||
|
||||
if (RXPacketL == 0)
|
||||
{
|
||||
packet_is_Error();
|
||||
}
|
||||
else
|
||||
{
|
||||
packet_is_OK();
|
||||
}
|
||||
|
||||
digitalWrite(LED1, LOW);
|
||||
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
|
||||
void packet_is_OK()
|
||||
{
|
||||
uint16_t IRQStatus;
|
||||
IRQStatus = LT.readIrqStatus();
|
||||
|
||||
RXpacketCount++;
|
||||
Serial.print(F("PacketOK > "));
|
||||
Serial.print(F(" RSSI,"));
|
||||
Serial.print(PacketRSSI);
|
||||
Serial.print(F("dBm,SNR,"));
|
||||
Serial.print(PacketSNR);
|
||||
Serial.print(F("dB,Length,"));
|
||||
Serial.print(RXPacketL);
|
||||
Serial.print(F(",Packets,"));
|
||||
Serial.print(RXpacketCount);
|
||||
Serial.print(F(",Errors,"));
|
||||
Serial.print(errors);
|
||||
Serial.print(F(",IRQreg,"));
|
||||
Serial.print(IRQStatus, HEX);
|
||||
Serial.println();
|
||||
printFrequencyError();
|
||||
}
|
||||
|
||||
|
||||
void printFrequencyError()
|
||||
{
|
||||
int32_t hertzerror, regdata;
|
||||
regdata = LT.getFrequencyErrorRegValue();
|
||||
hertzerror = LT.getFrequencyErrorHz();
|
||||
Serial.print(F("ErrorRegValue,"));
|
||||
Serial.print(regdata, HEX);
|
||||
Serial.print(F(" PacketHertzError,"));
|
||||
Serial.print(hertzerror);
|
||||
Serial.println(F("hz"));
|
||||
|
||||
totalHzError = totalHzError + hertzerror;
|
||||
|
||||
if (RXpacketCount == 10)
|
||||
{
|
||||
Serial.print(F("******** AverageHertzerror "));
|
||||
Serial.print((totalHzError / 10));
|
||||
Serial.println(F("hz"));
|
||||
RXpacketCount = 0;
|
||||
totalHzError = 0;
|
||||
delay(5000);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void packet_is_Error()
|
||||
{
|
||||
uint16_t IRQStatus;
|
||||
|
||||
IRQStatus = LT.readIrqStatus(); //get the IRQ status
|
||||
errors++;
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
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.print(__TIME__);
|
||||
Serial.print(F(" "));
|
||||
Serial.println(__DATE__);
|
||||
Serial.println(F(Program_Version));
|
||||
Serial.println();
|
||||
Serial.println(F("16_LoRa_RX_Frequency_Error_Check Starting"));
|
||||
Serial.println();
|
||||
|
||||
SPI.begin();
|
||||
|
||||
if (LT.begin(NSS, NRESET, RFBUSY, DIO1, DIO2, DIO3, RX_EN, TX_EN, 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(F("Receiver ready"));
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
/*******************************************************************************************************
|
||||
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. Some pins such as DIO2,
|
||||
//DIO3, 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 10
|
||||
#define RFBUSY 7
|
||||
#define NRESET 9
|
||||
#define LED1 8
|
||||
#define DIO1 3
|
||||
#define DIO2 -1 //not used
|
||||
#define DIO3 -1 //not used
|
||||
#define RX_EN -1 //pin for RX enable, used on some SX1280 devices, set to -1 if not used
|
||||
#define TX_EN -1 //pin for TX enable, used on some SX1280 devices, set to -1 if not used
|
||||
|
||||
#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 uint8_t TXpower = 10; //Power for transmissions in dBm
|
||||
|
||||
#define packet_delay 1000 //mS delay between packets
|
||||
|
||||
#define RXBUFFER_SIZE 32 //RX buffer size
|
||||
|
||||
|
||||
@@ -0,0 +1,317 @@
|
||||
/*******************************************************************************************************
|
||||
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 - The program listens for incoming packets using the LoRa settings in the 'Settings.h'
|
||||
file. The pins to access the lora device need to be defined in the 'Settings.h' file also.
|
||||
|
||||
The program is a matching receiver program for the '10_LoRa_Link_Test_Transmitter'. The packets received
|
||||
are displayed on the serial monitor and analysed to extract the packet data which indicates the power
|
||||
used to send the packet. A count is kept of the numbers of each power setting received. When the transmitter
|
||||
sends the test mode packet at the beginning of the sequence (displayed as 999) the running totals of the
|
||||
powers received are printed. Thus you can quickly see at what transmit power levels the reception fails.
|
||||
|
||||
Serial monitor baud rate is set at 9600.
|
||||
*******************************************************************************************************/
|
||||
|
||||
#define Program_Version "V1.0"
|
||||
|
||||
#include <SPI.h> //the lora device is SPI based so load the SPI library
|
||||
#include <SX128XLT.h> //include the appropriate library
|
||||
#include "Settings.h" //include the setiings file, frequencies, LoRa settings etc
|
||||
#include <ProgramLT_Definitions.h>
|
||||
|
||||
SX128XLT LT; //create a library class instance called LT
|
||||
|
||||
uint32_t RXpacketCount;
|
||||
uint32_t errors;
|
||||
|
||||
uint8_t RXBUFFER[RXBUFFER_SIZE]; //create the buffer that received packets are copied into
|
||||
|
||||
uint8_t RXPacketL; //stores length of packet received
|
||||
int8_t PacketRSSI; //stores RSSI of received packet
|
||||
int8_t PacketSNR; //stores signal to noise ratio of received packet
|
||||
|
||||
uint32_t Test1Count[32]; //buffer where counts of received packets are stored, -18dbm to +12dBm
|
||||
uint32_t Mode1_Cycles = 0; //count the number of cyles received
|
||||
bool updateCounts = false; //update counts set to tru when first TestMode1 received, at sequence start
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
RXPacketL = LT.receiveAddressed(RXBUFFER, RXBUFFER_SIZE, 15000, WAIT_RX); //wait for a packet to arrive with 15seconds (15000mS) timeout
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
if (BUZZER > 0)
|
||||
{
|
||||
delay(25); //gives a slightly longer beep
|
||||
digitalWrite(BUZZER, LOW); //buzzer off
|
||||
}
|
||||
|
||||
digitalWrite(LED1, LOW); //LED off
|
||||
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
|
||||
void packet_is_OK()
|
||||
{
|
||||
uint16_t IRQStatus;
|
||||
|
||||
if (BUZZER > 0) //turn buzzer on for a valid packet
|
||||
{
|
||||
digitalWrite(BUZZER, HIGH);
|
||||
}
|
||||
|
||||
IRQStatus = LT.readIrqStatus(); //read the LoRa device IRQ status register
|
||||
|
||||
RXpacketCount++;
|
||||
|
||||
printElapsedTime(); //print elapsed time to Serial Monitor
|
||||
Serial.print(F(" "));
|
||||
LT.printASCIIPacket(RXBUFFER, RXPacketL - 3); //print the packet as ASCII characters
|
||||
|
||||
Serial.print(F(",RSSI,"));
|
||||
Serial.print(PacketRSSI);
|
||||
Serial.print(F("dBm,SNR,"));
|
||||
Serial.print(PacketSNR);
|
||||
Serial.print(F("dB,Length,"));
|
||||
Serial.print(RXPacketL);
|
||||
Serial.print(F(",Packets,"));
|
||||
Serial.print(RXpacketCount);
|
||||
Serial.print(F(",Errors,"));
|
||||
Serial.print(errors);
|
||||
Serial.print(F(",IRQreg,"));
|
||||
Serial.print(IRQStatus, HEX);
|
||||
|
||||
processPacket();
|
||||
}
|
||||
|
||||
|
||||
void processPacket()
|
||||
{
|
||||
int8_t lTXpower;
|
||||
uint8_t packettype;
|
||||
uint32_t temp;
|
||||
|
||||
packettype = LT.readRXPacketType(); //need to know the packet type so we can decide what to do
|
||||
|
||||
if (packettype == TestPacket)
|
||||
{
|
||||
if (RXBUFFER[0] == ' ')
|
||||
{
|
||||
lTXpower = 0;
|
||||
}
|
||||
|
||||
if (RXBUFFER[0] == '+')
|
||||
{
|
||||
lTXpower = ((RXBUFFER[1] - 48) * 10) + (RXBUFFER[2] - 48); //convert packet text to power
|
||||
}
|
||||
|
||||
if (RXBUFFER[0] == '-')
|
||||
{
|
||||
lTXpower = (((RXBUFFER[1] - 48) * 10) + (RXBUFFER[2] - 48)) * -1; //convert packet text to power
|
||||
}
|
||||
|
||||
Serial.print(F(" ("));
|
||||
|
||||
if (RXBUFFER[0] != '-')
|
||||
{
|
||||
Serial.write(RXBUFFER[0]);
|
||||
}
|
||||
|
||||
Serial.print(lTXpower);
|
||||
Serial.print(F("dBm)"));
|
||||
|
||||
if (updateCounts)
|
||||
{
|
||||
temp = (Test1Count[lTXpower+18]);
|
||||
Test1Count[lTXpower+18] = temp + 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (packettype == TestMode1)
|
||||
{
|
||||
//this is a command to switch to TestMode1 also updates totals and logs
|
||||
updateCounts = true;
|
||||
Serial.println();
|
||||
Serial.println(F("End test sequence"));
|
||||
|
||||
if (Mode1_Cycles > 0)
|
||||
{
|
||||
print_Test1Count();
|
||||
}
|
||||
|
||||
Serial.println();
|
||||
Mode1_Cycles++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void print_Test1Count()
|
||||
{
|
||||
//prints running totals of the powers of received packets
|
||||
int8_t index;
|
||||
uint32_t j;
|
||||
|
||||
Serial.print(F("Test Packets "));
|
||||
Serial.println(RXpacketCount);
|
||||
Serial.print(F("Test Cycles "));
|
||||
Serial.println(Mode1_Cycles);
|
||||
|
||||
Serial.println();
|
||||
for (index = 30; index >= 0; index--)
|
||||
{
|
||||
Serial.print(index-18);
|
||||
Serial.print(F("dBm,"));
|
||||
j = Test1Count[index];
|
||||
Serial.print(j);
|
||||
Serial.print(F(" "));
|
||||
}
|
||||
Serial.println();
|
||||
|
||||
Serial.print(F("CSV"));
|
||||
for (index = 30; index >= 0; index--)
|
||||
{
|
||||
Serial.print(F(","));
|
||||
j = Test1Count[index];
|
||||
Serial.print(j);
|
||||
}
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
|
||||
void packet_is_Error()
|
||||
{
|
||||
uint16_t IRQStatus;
|
||||
IRQStatus = LT.readIrqStatus(); //read the LoRa device IRQ status register
|
||||
|
||||
printElapsedTime(); //print elapsed time to Serial Monitor
|
||||
|
||||
if (IRQStatus & IRQ_RX_TIMEOUT) //check for an RX timeout
|
||||
{
|
||||
Serial.print(F(" RXTimeout"));
|
||||
}
|
||||
else
|
||||
{
|
||||
errors++;
|
||||
Serial.print(F(" PacketError"));
|
||||
Serial.print(F(",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(",Packets,"));
|
||||
Serial.print(RXpacketCount);
|
||||
Serial.print(F(",Errors,"));
|
||||
Serial.print(errors);
|
||||
Serial.print(F(",IRQreg,"));
|
||||
Serial.print(IRQStatus, HEX);
|
||||
LT.printIrqStatus(); //print the names of the IRQ registers set
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void printElapsedTime()
|
||||
{
|
||||
float seconds;
|
||||
seconds = millis() / 1000;
|
||||
Serial.print(seconds, 0);
|
||||
Serial.print(F("s"));
|
||||
}
|
||||
|
||||
|
||||
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.print(__TIME__);
|
||||
Serial.print(F(" "));
|
||||
Serial.println(__DATE__);
|
||||
Serial.println(F(Program_Version));
|
||||
Serial.println();
|
||||
Serial.println(F("20_LoRa_Link_Test_Receiver Starting"));
|
||||
Serial.println();
|
||||
|
||||
if (BUZZER > 0)
|
||||
{
|
||||
pinMode(BUZZER, OUTPUT);
|
||||
digitalWrite(BUZZER, HIGH);
|
||||
delay(50);
|
||||
digitalWrite(BUZZER, LOW);
|
||||
}
|
||||
|
||||
//setup SPI, its external to library on purpose, so settings can be mixed and matched with other SPI devices
|
||||
SPI.begin();
|
||||
|
||||
//SPI beginTranscation is normally part of library routines, but if it is disabled in library
|
||||
//a single instance is needed here, so uncomment the program line below
|
||||
//SPI.beginTransaction(SPISettings(8000000, MSBFIRST, SPI_MODE0));
|
||||
|
||||
//setup hardware pins used by device, then check if device is found
|
||||
if (LT.begin(NSS, NRESET, RFBUSY, DIO1, DIO2, DIO3, RX_EN, TX_EN, 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 LED flash indicates device error
|
||||
}
|
||||
}
|
||||
|
||||
//this function call sets up the device for LoRa using the settings from settings.h
|
||||
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 operting settings, useful check
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
|
||||
Serial.print(F("Receiver ready - RXBUFFER_SIZE "));
|
||||
Serial.println(RXBUFFER_SIZE);
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
/*******************************************************************************************************
|
||||
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 definitiosn to match your own setup. Some pins such as DIO2,
|
||||
//DIO3 may not be in used by this sketch so they do not need to be connected and should
|
||||
//be set to -1.
|
||||
|
||||
|
||||
#define NSS 10 //select pin on LoRa device
|
||||
#define NRESET 9 //reset pin on LoRa device
|
||||
#define LED1 8 //on board LED, high for on
|
||||
#define RFBUSY 7 //SX128X busy pin
|
||||
#define DIO1 3 //DIO1 pin on LoRa device, used for RX and TX done
|
||||
#define DIO2 -1 //DIO2 pin on LoRa device, normally not used so set to -1
|
||||
#define DIO3 -1 //DIO3 pin on LoRa device, normally not used so set to -1
|
||||
#define RX_EN -1 //pin for RX enable, used on some SX128X devices, set to -1 if not used
|
||||
#define TX_EN -1 //pin for TX enable, used on some SX128X devices, set to -1 if not used
|
||||
#define BUZZER -1 //pin for buzzer, set to -1 if not used
|
||||
|
||||
#define LORA_DEVICE DEVICE_SX1280 //this is the device we are using
|
||||
|
||||
|
||||
//******* Setup LoRa Parameters Here ! ***************
|
||||
|
||||
//LoRa Modem Parameters
|
||||
#define Frequency 2445000000 //frequency of transmissions
|
||||
#define Offset 0 //offset frequency for calibration purposes
|
||||
#define Bandwidth LORA_BW_0400 //LoRa bandwidth
|
||||
#define SpreadingFactor LORA_SF7 //LoRa spreading factor
|
||||
#define CodeRate LORA_CR_4_5 //LoRa coding rate
|
||||
|
||||
const int8_t TXpower = 10; //LoRa transmit power in dBm
|
||||
|
||||
const uint16_t packet_delay = 1000; //mS delay between packets
|
||||
|
||||
#define RXBUFFER_SIZE 32 //RX buffer size
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,283 @@
|
||||
/*******************************************************************************************************
|
||||
Programs for Arduino - Copyright of the author Stuart Robinson - 01/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 - The program listens for incoming packets using the LoRa settings in the 'Settings.h'
|
||||
file. The pins to access the lora device need to be defined in the 'Settings.h' file also.
|
||||
|
||||
There is a printout of the valid packets received, the packet is assumed to be in ASCII printable text,
|
||||
if its not ASCII text characters from 0x20 to 0x7F, expect weird things to happen on the Serial Monitor.
|
||||
The LED will flash for each packet received and the buzzer will sound, if fitted.
|
||||
|
||||
Sample serial monitor output;
|
||||
|
||||
1109s {packet contents} CRC,3882,RSSI,-69dBm,SNR,10dB,Length,19,Packets,1026,Errors,0,IRQreg,50
|
||||
|
||||
If there is a packet error it might look like this, which is showing a CRC error,
|
||||
|
||||
1189s PacketError,RSSI,-111dBm,SNR,-12dB,Length,0,Packets,1126,Errors,1,IRQreg,70,IRQ_HEADER_VALID,IRQ_CRC_ERROR,IRQ_RX_DONE
|
||||
|
||||
A summary of the packet reception is sent to the OLED display as well, useful for portable applications.
|
||||
|
||||
Serial monitor baud rate is set at 9600.
|
||||
*******************************************************************************************************/
|
||||
|
||||
#define Program_Version "V1.0"
|
||||
|
||||
#include <SPI.h> //the lora device is SPI based so load the SPI library
|
||||
#include <SX128XLT.h> //include the appropriate library
|
||||
#include "Settings.h" //include the setiings file, frequencies, LoRa settings etc
|
||||
|
||||
SX128XLT LT; //create a library class instance called 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;
|
||||
uint32_t RXpacketErrors;
|
||||
uint16_t IRQStatus;
|
||||
|
||||
uint8_t RXBUFFER[RXBUFFER_SIZE]; //create the buffer that received packets are copied into
|
||||
uint8_t RXPacketL; //stores length of packet received
|
||||
int8_t PacketRSSI; //stores RSSI of received packet
|
||||
int8_t PacketSNR; //stores signal to noise ratio of received packet
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
RXPacketL = LT.receive(RXBUFFER, RXBUFFER_SIZE, 0, WAIT_RX); //wait for a packet to arrive with no timeout
|
||||
|
||||
digitalWrite(LED1, HIGH); //something has happened
|
||||
|
||||
if (BUZZER > 0)
|
||||
{
|
||||
digitalWrite(BUZZER, HIGH); //buzzer on
|
||||
}
|
||||
|
||||
PacketRSSI = LT.readPacketRSSI(); //read the recived RSSI value
|
||||
PacketSNR = LT.readPacketSNR(); //read the received SNR value
|
||||
IRQStatus = LT.readIrqStatus(); //read the LoRa device IRQ status register
|
||||
|
||||
if (RXPacketL == 0) //if the LT.receive() function detects an error, RXpacketL == 0
|
||||
{
|
||||
packet_is_Error();
|
||||
}
|
||||
else
|
||||
{
|
||||
packet_is_OK();
|
||||
}
|
||||
|
||||
if (BUZZER > 0)
|
||||
{
|
||||
digitalWrite(BUZZER, LOW); //buzzer off
|
||||
}
|
||||
|
||||
digitalWrite(LED1, LOW); //LED off
|
||||
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
|
||||
void packet_is_OK()
|
||||
{
|
||||
uint16_t localCRC;
|
||||
|
||||
RXpacketCount++;
|
||||
|
||||
printElapsedTime(); //print elapsed time to Serial Monitor
|
||||
Serial.print(F(" "));
|
||||
LT.printASCIIPacket(RXBUFFER, RXPacketL); //print the packet as ASCII characters
|
||||
|
||||
localCRC = LT.CRCCCITT(RXBUFFER, RXPacketL, 0xFFFF); //calculate the CRC, this is the external CRC calculation of the RXBUFFER
|
||||
Serial.print(F(",CRC,")); //contents, not the LoRa device internal CRC
|
||||
Serial.print(localCRC, HEX);
|
||||
Serial.print(F(",RSSI,"));
|
||||
Serial.print(PacketRSSI);
|
||||
Serial.print(F("dBm,SNR,"));
|
||||
Serial.print(PacketSNR);
|
||||
Serial.print(F("dB,Length,"));
|
||||
Serial.print(RXPacketL);
|
||||
Serial.print(F(",Packets,"));
|
||||
Serial.print(RXpacketCount);
|
||||
Serial.print(F(",Errors,"));
|
||||
Serial.print(RXpacketErrors);
|
||||
Serial.print(F(",IRQreg,"));
|
||||
Serial.print(IRQStatus, HEX);
|
||||
|
||||
disp.clearLine(0);
|
||||
disp.setCursor(0, 0);
|
||||
disp.print(F("OK"));
|
||||
dispscreen1();
|
||||
}
|
||||
|
||||
|
||||
void packet_is_Error()
|
||||
{
|
||||
printElapsedTime(); //print elapsed time to Serial Monitor
|
||||
|
||||
RXpacketErrors++;
|
||||
Serial.print(F(" PacketError"));
|
||||
Serial.print(F(",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(",Packets,"));
|
||||
Serial.print(RXpacketCount);
|
||||
Serial.print(F(",Errors,"));
|
||||
Serial.print(RXpacketErrors);
|
||||
Serial.print(F(",IRQreg,"));
|
||||
Serial.print(IRQStatus, HEX);
|
||||
LT.printIrqStatus(); //print the names of the IRQ registers set
|
||||
disp.clearLine(0);
|
||||
disp.setCursor(0, 0);
|
||||
disp.print(F("Packet Error"));
|
||||
dispscreen1();
|
||||
|
||||
delay(500); //gives longer buzzer and LED falsh for error
|
||||
|
||||
}
|
||||
|
||||
|
||||
void printElapsedTime()
|
||||
{
|
||||
float seconds;
|
||||
seconds = millis() / 1000;
|
||||
Serial.print(seconds, 0);
|
||||
Serial.print(F("s"));
|
||||
}
|
||||
|
||||
|
||||
void dispscreen1()
|
||||
{
|
||||
disp.clearLine(1);
|
||||
disp.setCursor(0, 1);
|
||||
disp.print(F("RSSI "));
|
||||
disp.print(PacketRSSI);
|
||||
disp.print(F("dBm"));
|
||||
disp.clearLine(2);
|
||||
disp.setCursor(0, 2);
|
||||
disp.print(F("SNR "));
|
||||
|
||||
if (PacketSNR > 0)
|
||||
{
|
||||
disp.print(F("+"));
|
||||
}
|
||||
|
||||
disp.print(PacketSNR);
|
||||
disp.print(F("dB"));
|
||||
disp.clearLine(3);
|
||||
disp.setCursor(0, 3);
|
||||
disp.print(F("Length "));
|
||||
disp.print(LT.readRXPacketL());
|
||||
disp.clearLine(4);
|
||||
disp.setCursor(0, 4);
|
||||
disp.print(F("Packets "));
|
||||
disp.print(RXpacketCount);
|
||||
disp.clearLine(5);
|
||||
disp.setCursor(0, 5);
|
||||
disp.print(F("Errors "));
|
||||
disp.print(RXpacketErrors);
|
||||
disp.clearLine(6);
|
||||
disp.setCursor(0, 6);
|
||||
disp.print(F("IRQreg "));
|
||||
disp.print(IRQStatus, HEX);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
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.print(F(__TIME__));
|
||||
Serial.print(F(" "));
|
||||
Serial.println(F(__DATE__));
|
||||
Serial.println(F(Program_Version));
|
||||
Serial.println();
|
||||
Serial.println(F("33_LoRa_RSSI_Checker_With_Display Starting"));
|
||||
Serial.println();
|
||||
|
||||
if (BUZZER > 0)
|
||||
{
|
||||
pinMode(BUZZER, OUTPUT);
|
||||
digitalWrite(BUZZER, HIGH);
|
||||
delay(50);
|
||||
digitalWrite(BUZZER, LOW);
|
||||
}
|
||||
|
||||
SPI.begin();
|
||||
|
||||
//SPI beginTranscation is normally part of library routines, but if it is disabled in library
|
||||
//a single instance is needed here, so uncomment the program line below
|
||||
//SPI.beginTransaction(SPISettings(8000000, MSBFIRST, SPI_MODE0));
|
||||
|
||||
disp.begin();
|
||||
disp.setFont(u8x8_font_chroma48medium8_r);
|
||||
|
||||
disp.clear();
|
||||
disp.setCursor(0, 0);
|
||||
disp.print(F("Check LoRa"));
|
||||
disp.setCursor(0, 1);
|
||||
|
||||
//setup hardware pins used by device, then check if device is found
|
||||
if (LT.begin(NSS, NRESET, RFBUSY, DIO1, DIO2, DIO3, RX_EN, TX_EN, LORA_DEVICE))
|
||||
{
|
||||
disp.print(F("LoRa OK"));
|
||||
Serial.println(F("LoRa Device found"));
|
||||
led_Flash(2, 125);
|
||||
delay(1000);
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println(F("No device responding"));
|
||||
while (1)
|
||||
{
|
||||
disp.print(F("Device error"));
|
||||
led_Flash(50, 50); //long fast speed LED flash indicates device error
|
||||
}
|
||||
}
|
||||
|
||||
//this function call sets up the device for LoRa using the settings from settings.h
|
||||
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 operting settings, useful check
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
LT.printRegisters(0x900, 0x9FF); //print contents of device registers
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
|
||||
Serial.print(F("Receiver ready - RXBUFFER_SIZE "));
|
||||
Serial.println(RXBUFFER_SIZE);
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
/*******************************************************************************************************
|
||||
Programs for Arduino - Copyright of the author Stuart Robinson - 01/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. Some pins such as DIO2,
|
||||
//DIO3, BUZZER may not be in used by this sketch so they do not need to be
|
||||
//connected and should be included and be set to -1.
|
||||
|
||||
#define NSS 10
|
||||
#define RFBUSY 7
|
||||
#define NRESET 9
|
||||
#define LED1 8
|
||||
#define DIO1 3
|
||||
#define DIO2 -1 //not used
|
||||
#define DIO3 -1 //not used
|
||||
#define RX_EN -1 //pin for RX enable, used on some SX1280 devices, set to -1 if not used
|
||||
#define TX_EN -1 //pin for TX enable, used on some SX1280 devices, set to -1 if not used
|
||||
#define BUZZER -1 //pin for BUZZER, set to -1 if not used
|
||||
|
||||
#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 uint8_t TXpower = 10; //Power for transmissions in dBm
|
||||
|
||||
const uint16_t packet_delay = 1000; //mS delay between packets
|
||||
|
||||
#define RXBUFFER_SIZE 32 //RX buffer size
|
||||
|
||||
@@ -0,0 +1,282 @@
|
||||
/*******************************************************************************************************
|
||||
Programs for Arduino - Copyright of the author Stuart Robinson - 15/05/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 is a program that can be used to test the throughput of a LoRa transmitter.
|
||||
Whilst the various LoRa calculators tell you the on air data rate, in practice the achievable data
|
||||
rate will be less than that due to the overhead of the software routines to load and send a packet
|
||||
and internal delays in the LoRa device itself.
|
||||
|
||||
A buffer is filled with characters and that buffer is then transmitted. The total time for a number of
|
||||
transmissions is recorded and the bit rate calculated. The packet size (1 - 255 bytes) and the number of
|
||||
packets to send in the test are specified in the 'Settings.h' file, see the 'Setup packet parameters Here !'
|
||||
section. The setting file also has the lora settings to use. A lower spreading factors and higher
|
||||
bandwidths will result in higher bitrates.
|
||||
|
||||
There is the option of turning on an a requirement for an acknowledgement from a remote receiver, before
|
||||
the transmitter sends the next packet, set this; 'const bool waitforACK = true;' definition in the
|
||||
settings file. The matching receiver program '43_LoRa_Data_Throughput_Acknowledge_Receiver' does then need
|
||||
to be configured with same lora settings as this transmitter. When this option is set, the program will
|
||||
keep running until the number of transmissions and acknowledgements has completed without any timeouts
|
||||
in order to produce a valid average.
|
||||
|
||||
The results of the test are printed out thus;
|
||||
|
||||
SX1280,434000000hz,SF7,BW500000,CR4:5,LDRO_Off,SyncWord_0x12,IQNormal,Preamble_8
|
||||
Total transmit time 100 packets = 1382mS
|
||||
Average 16 byte packet transmit time = 13.82mS
|
||||
Packets per second 72.36
|
||||
Bits per packet sent = 128
|
||||
Data rate = 9262bps
|
||||
|
||||
|
||||
Serial monitor baud rate is set at 9600
|
||||
*******************************************************************************************************/
|
||||
|
||||
#define Program_Version "V1.0"
|
||||
|
||||
#include <SPI.h> //the lora device is SPI based so load the SPI library
|
||||
#include <SX128XLT.h> //include the appropriate library
|
||||
#include <ProgramLT_Definitions.h>
|
||||
#include "Settings.h" //include the setiings file, frequencies, LoRa settings etc
|
||||
|
||||
SX128XLT LT; //create a library class instance called LT
|
||||
|
||||
uint32_t startmS, endmS, sendtimemS, bitspersecond, bitsPerpacket;
|
||||
uint32_t TXPacketCount;
|
||||
float averagePacketTime;
|
||||
uint8_t packetNumber;
|
||||
uint8_t RXPacketL; //length of received packet
|
||||
uint8_t PacketType; //for packet addressing, identifies packet type received
|
||||
uint32_t packetCheck;
|
||||
bool loopFail = false;
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
uint16_t index, index2;
|
||||
uint8_t TXBUFFER[TXPacketL + 1]; //create buffer for transmitted packet
|
||||
loopFail = false;
|
||||
|
||||
Serial.println(F("Start transmit test"));
|
||||
|
||||
startmS = millis(); //start transmit timer
|
||||
|
||||
for (index = 0; index < numberPackets; index++)
|
||||
{
|
||||
//fill the buffer
|
||||
for (index2 = 0; index2 < TXPacketL; index2++)
|
||||
{
|
||||
TXBUFFER[index2] = index2;
|
||||
}
|
||||
|
||||
TXBUFFER[0] = TestPacket; //set first byte to identify this test packet
|
||||
TXBUFFER[1] = index; //put the index as packet number in second byte of packet
|
||||
Serial.print(index); //print number of packet sent
|
||||
|
||||
if (waitforACK)
|
||||
{
|
||||
packetCheck = ( (uint32_t) TXBUFFER[4] << 24) + ( (uint32_t) TXBUFFER[3] << 16) + ( (uint32_t) TXBUFFER[2] << 8) + (uint32_t) TXBUFFER[1];
|
||||
Serial.print(F(",Checkvalue,"));
|
||||
Serial.print(packetCheck, HEX);
|
||||
Serial.print(F(","));
|
||||
}
|
||||
|
||||
digitalWrite(LED1, HIGH);
|
||||
|
||||
if (LT.transmit(TXBUFFER, TXPacketL, 10000, TXpower, WAIT_TX)) //will return 0 if transmit error
|
||||
{
|
||||
digitalWrite(LED1, LOW);
|
||||
|
||||
if (waitforACK)
|
||||
{
|
||||
if (!waitAck(packetCheck))
|
||||
{
|
||||
Serial.print(F("NoACKreceived,"));
|
||||
loopFail = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
packet_is_Error(); //transmit packet returned 0, there was an error
|
||||
loopFail = true;
|
||||
}
|
||||
|
||||
Serial.println();
|
||||
|
||||
}
|
||||
|
||||
if (!loopFail)
|
||||
{
|
||||
endmS = millis(); //all packets sent, note end time
|
||||
digitalWrite(LED1, LOW);
|
||||
Serial.println();
|
||||
LT.printModemSettings();
|
||||
sendtimemS = endmS - startmS;
|
||||
Serial.println();
|
||||
Serial.print(F("Total transmit time "));
|
||||
Serial.print(numberPackets);
|
||||
Serial.print(F(" packets = "));
|
||||
Serial.print(sendtimemS);
|
||||
Serial.println(F("mS"));
|
||||
|
||||
averagePacketTime = (float) ((endmS - startmS) / numberPackets);
|
||||
|
||||
if (waitforACK)
|
||||
{
|
||||
Serial.print(F("Average "));
|
||||
Serial.print(TXPacketL);
|
||||
Serial.print(F(" byte packet transmit and acknowledge time = "));
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.print(F("Average "));
|
||||
Serial.print(TXPacketL);
|
||||
Serial.print(F(" byte packet transmit time = "));
|
||||
}
|
||||
|
||||
Serial.print(averagePacketTime, 2);
|
||||
Serial.println(F("mS"));
|
||||
Serial.print(F("Packets per second "));
|
||||
Serial.println((float) (1000/averagePacketTime));
|
||||
bitsPerpacket = (uint32_t) (TXPacketL * 8);
|
||||
Serial.print(F("Bits per packet sent = "));
|
||||
Serial.println(bitsPerpacket);
|
||||
|
||||
Serial.print(F("Data rate = "));
|
||||
Serial.print((bitsPerpacket / (averagePacketTime / 1000)), 0);
|
||||
Serial.print(F("bps"));
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
delay(10000); //have a delay between loops so we can see result
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println(F("Transmit test failed, trying again"));
|
||||
Serial.println();
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool waitAck(uint32_t TXnum)
|
||||
{
|
||||
uint32_t RXnum;
|
||||
uint16_t IRQStatus;
|
||||
|
||||
RXPacketL = LT.receiveSXBuffer(0, 1000, WAIT_RX); //returns 0 if packet error of some sort
|
||||
|
||||
IRQStatus = LT.readIrqStatus(); //read the LoRa device IRQ status register
|
||||
|
||||
if (IRQStatus & IRQ_RX_TIMEOUT) //check for an RX timeout
|
||||
{
|
||||
Serial.print(F("RXTimeout,"));
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.print(F("ACKRX,"));
|
||||
}
|
||||
|
||||
LT.startReadSXBuffer(0);
|
||||
PacketType = LT.readUint8();
|
||||
RXnum = LT.readUint32();
|
||||
RXPacketL = LT.endReadSXBuffer();
|
||||
|
||||
if ( (PacketType != ACK) || (RXnum != TXnum))
|
||||
{
|
||||
Serial.print(F("NotValidACK,"));
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.print(RXnum, HEX);
|
||||
Serial.print(F(",OK"));
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void packet_is_Error()
|
||||
{
|
||||
//if here there was an error transmitting packet
|
||||
uint16_t IRQStatus;
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
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.print(F(__TIME__));
|
||||
Serial.print(F(" "));
|
||||
Serial.println(F(__DATE__));
|
||||
Serial.println(F(Program_Version));
|
||||
Serial.println();
|
||||
Serial.println(F("42_LoRa_Data_Throughput_Test_Transmitter Starting"));
|
||||
|
||||
SPI.begin();
|
||||
|
||||
//setup hardware pins used by device, then check if device is found
|
||||
if (LT.begin(NSS, NRESET, RFBUSY, DIO1, LORA_DEVICE))
|
||||
{
|
||||
Serial.println(F("LoRa Device found"));
|
||||
led_Flash(2, 125); //two further quick LED flashes to indicate device found
|
||||
delay(1000);
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println(F("No device responding"));
|
||||
while (1)
|
||||
{
|
||||
led_Flash(50, 50); //long fast speed LED 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();
|
||||
Serial.println();
|
||||
|
||||
Serial.print(F("Transmitter ready"));
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
/*******************************************************************************************************
|
||||
Programs for Arduino - Copyright of the author Stuart Robinson - 26/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. Some pins such as DIO1,
|
||||
//DIO2, BUZZER are not used by this sketch so they do not need to be connected and
|
||||
//should be set to -1.
|
||||
|
||||
#define NSS 10 //select pin on LoRa device
|
||||
#define NRESET 9 //reset pin on LoRa device
|
||||
#define RFBUSY 7 //RFBUSY pin on LoRa device
|
||||
#define LED1 8 //on board LED, high for on
|
||||
#define DIO1 3 //DIO0 pin on LoRa device, used for RX and TX done
|
||||
|
||||
#define LORA_DEVICE DEVICE_SX1280 //we need to define the device we are using
|
||||
|
||||
|
||||
//******* Setup LoRa Parameters Here ! ***************
|
||||
|
||||
//LoRa Modem Parameters
|
||||
#define Frequency 2445000000 //frequency of transmissions
|
||||
#define Offset 0 //offset frequency for calibration purposes
|
||||
|
||||
#define Bandwidth LORA_BW_1600 //LoRa bandwidth
|
||||
#define SpreadingFactor LORA_SF5 //LoRa spreading factor
|
||||
#define CodeRate LORA_CR_4_5 //LoRa coding rate
|
||||
|
||||
const int8_t TXpower = 10; //LoRa transmit power in dBm
|
||||
|
||||
|
||||
//******* Setup packet parameters Here ! ***************
|
||||
const uint8_t numberPackets = 50; //number of packets to send in transmit loop
|
||||
const uint8_t TXPacketL = 16; //length of packet to send
|
||||
const bool waitforACK = false; //set to true to have transmit wait for ack before continuing
|
||||
|
||||
|
||||
@@ -0,0 +1,294 @@
|
||||
/*******************************************************************************************************
|
||||
Programs for Arduino - Copyright of the author Stuart Robinson - 15/05/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 is a program that can be used to test the throughput of a LoRa transmitter.
|
||||
Whilst the various LoRa calculators tell you the on air data rate, in practice the achievable data
|
||||
rate will be less than that due to the overhead of the software routines to load and send a packet
|
||||
and internal delays in the LoRa device itself.
|
||||
|
||||
A buffer is filled with characters and that buffer is then transmitted. The total time for a number of
|
||||
transmissions is recorded and the bit rate calculated. The packet size (1 - 255 bytes) and the number of
|
||||
packets to send in the test are specified in the 'Settings.h' file, see the 'Setup packet parameters Here !'
|
||||
section. The setting file also has the lora settings to use. A lower spreading factors and higher
|
||||
bandwidths will result in higher bitrates.
|
||||
|
||||
There is the option of turning on an a requirement for an acknowledgement from a remote receiver, before
|
||||
the transmitter sends the next packet, set this; 'const bool waitforACK = true;' definition in the
|
||||
settings file. The matching receiver program '43_LoRa_Data_Throughput_Acknowledge_Receiver' does then need
|
||||
to be configured with same lora settings as this transmitter. When this option is set, the program will
|
||||
keep running until the number of transmissions and acknowledgements has completed without any timeouts
|
||||
in order to produce a valid average.
|
||||
|
||||
The results of the test are printed out thus;
|
||||
|
||||
SX1280,434000000hz,SF7,BW500000,CR4:5,LDRO_Off,SyncWord_0x12,IQNormal,Preamble_8
|
||||
Total transmit time 100 packets = 1382mS
|
||||
Average 16 byte packet transmit time = 13.82mS
|
||||
Packets per second 72.36
|
||||
Bits per packet sent = 128
|
||||
Data rate = 9262bps
|
||||
|
||||
|
||||
Serial monitor baud rate is set at 9600
|
||||
*******************************************************************************************************/
|
||||
|
||||
#define Program_Version "V1.0"
|
||||
|
||||
#include <SPI.h> //the lora device is SPI based so load the SPI library
|
||||
#include <SX128XLT.h> //include the appropriate library
|
||||
#include <ProgramLT_Definitions.h>
|
||||
#include "Settings.h" //include the setiings file, frequencies, LoRa settings etc
|
||||
|
||||
SX128XLT LT; //create a library class instance called LT
|
||||
|
||||
uint32_t startmS, endmS, sendtimemS, bitspersecond, bitsPerpacket;
|
||||
uint32_t TXPacketCount;
|
||||
float averagePacketTime;
|
||||
uint8_t packetNumber;
|
||||
uint8_t RXPacketL; //length of received packet
|
||||
uint8_t PacketType; //for packet addressing, identifies packet type received
|
||||
uint32_t packetCheck;
|
||||
bool loopFail = false;
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
uint16_t index, index2;
|
||||
uint8_t TXBUFFER[TXPacketL + 1]; //create buffer for transmitted packet
|
||||
loopFail = false;
|
||||
|
||||
Serial.println(F("Start transmit test"));
|
||||
|
||||
startmS = millis(); //start transmit timer
|
||||
|
||||
for (index = 0; index < numberPackets; index++)
|
||||
{
|
||||
//fill the buffer
|
||||
for (index2 = 0; index2 < TXPacketL; index2++)
|
||||
{
|
||||
TXBUFFER[index2] = index2;
|
||||
}
|
||||
|
||||
TXBUFFER[0] = TestPacket; //set first byte to identify this test packet
|
||||
TXBUFFER[1] = index; //put the index as packet number in second byte of packet
|
||||
Serial.print(index); //print number of packet sent
|
||||
|
||||
if (waitforACK)
|
||||
{
|
||||
packetCheck = ( (uint32_t) TXBUFFER[4] << 24) + ( (uint32_t) TXBUFFER[3] << 16) + ( (uint32_t) TXBUFFER[2] << 8) + (uint32_t) TXBUFFER[1];
|
||||
Serial.print(F(",Checkvalue,"));
|
||||
Serial.print(packetCheck, HEX);
|
||||
Serial.print(F(","));
|
||||
}
|
||||
|
||||
digitalWrite(LED1, HIGH);
|
||||
|
||||
if (LT.transmit(TXBUFFER, TXPacketL, 10000, TXpower, WAIT_TX)) //will return 0 if transmit error
|
||||
{
|
||||
digitalWrite(LED1, LOW);
|
||||
|
||||
if (waitforACK)
|
||||
{
|
||||
if (!waitAck(packetCheck))
|
||||
{
|
||||
Serial.print(F("NoACKreceived,"));
|
||||
loopFail = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
packet_is_Error(); //transmit packet returned 0, there was an error
|
||||
loopFail = true;
|
||||
}
|
||||
|
||||
Serial.println();
|
||||
|
||||
}
|
||||
|
||||
if (!loopFail)
|
||||
{
|
||||
endmS = millis(); //all packets sent, note end time
|
||||
digitalWrite(LED1, LOW);
|
||||
Serial.println();
|
||||
LT.printModemSettings();
|
||||
sendtimemS = endmS - startmS;
|
||||
Serial.println();
|
||||
Serial.print(F("Total transmit time "));
|
||||
Serial.print(numberPackets);
|
||||
Serial.print(F(" packets = "));
|
||||
Serial.print(sendtimemS);
|
||||
Serial.println(F("mS"));
|
||||
|
||||
averagePacketTime = (float) ((endmS - startmS) / numberPackets);
|
||||
|
||||
if (waitforACK)
|
||||
{
|
||||
Serial.print(F("Average "));
|
||||
Serial.print(TXPacketL);
|
||||
Serial.print(F(" byte packet transmit and acknowledge time = "));
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.print(F("Average "));
|
||||
Serial.print(TXPacketL);
|
||||
Serial.print(F(" byte packet transmit time = "));
|
||||
}
|
||||
|
||||
Serial.print(averagePacketTime, 2);
|
||||
Serial.println(F("mS"));
|
||||
Serial.print(F("Packets per second "));
|
||||
Serial.println((float) (1000/averagePacketTime));
|
||||
bitsPerpacket = (uint32_t) (TXPacketL * 8);
|
||||
Serial.print(F("Bits per packet sent = "));
|
||||
Serial.println(bitsPerpacket);
|
||||
|
||||
Serial.print(F("Data rate = "));
|
||||
Serial.print((bitsPerpacket / (averagePacketTime / 1000)), 0);
|
||||
Serial.print(F("bps"));
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
delay(10000); //have a delay between loops so we can see result
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println(F("Transmit test failed, trying again"));
|
||||
Serial.println();
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool waitAck(uint32_t TXnum)
|
||||
{
|
||||
uint32_t RXnum;
|
||||
uint16_t IRQStatus;
|
||||
|
||||
RXPacketL = LT.receiveSXBuffer(0, 1000, WAIT_RX); //returns 0 if packet error of some sort
|
||||
|
||||
IRQStatus = LT.readIrqStatus(); //read the LoRa device IRQ status register
|
||||
|
||||
if (IRQStatus & IRQ_RX_TIMEOUT) //check for an RX timeout
|
||||
{
|
||||
Serial.print(F("RXTimeout,"));
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.print(F("ACKRX,"));
|
||||
}
|
||||
|
||||
LT.startReadSXBuffer(0);
|
||||
PacketType = LT.readUint8();
|
||||
RXnum = LT.readUint32();
|
||||
RXPacketL = LT.endReadSXBuffer();
|
||||
|
||||
if ( (PacketType != ACK) || (RXnum != TXnum))
|
||||
{
|
||||
Serial.print(F("NotValidACK,"));
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.print(RXnum, HEX);
|
||||
Serial.print(F(",OK"));
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void packet_is_Error()
|
||||
{
|
||||
//if here there was an error transmitting packet
|
||||
uint16_t IRQStatus;
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
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.print(F(__TIME__));
|
||||
Serial.print(F(" "));
|
||||
Serial.println(F(__DATE__));
|
||||
Serial.println(F(Program_Version));
|
||||
Serial.println();
|
||||
Serial.println(F("42_LoRa_Data_Throughput_Test_Transmitter_FLRC Starting"));
|
||||
|
||||
SPI.begin();
|
||||
|
||||
//setup hardware pins used by device, then check if device is found
|
||||
if (LT.begin(NSS, NRESET, RFBUSY, DIO1, LORA_DEVICE))
|
||||
{
|
||||
Serial.println(F("LoRa Device found"));
|
||||
led_Flash(2, 125); //two further quick LED flashes to indicate device found
|
||||
delay(1000);
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println(F("No device responding"));
|
||||
while (1)
|
||||
{
|
||||
led_Flash(50, 50); //long fast speed LED flash indicates device error
|
||||
}
|
||||
}
|
||||
|
||||
//***************************************************************************************************
|
||||
//Setup FLRC
|
||||
//***************************************************************************************************
|
||||
LT.setMode(MODE_STDBY_RC);
|
||||
LT.setRegulatorMode(USE_LDO);
|
||||
LT.setPacketType(PACKET_TYPE_FLRC);
|
||||
LT.setRfFrequency(Frequency, Offset);
|
||||
LT.setBufferBaseAddress(0, 0);
|
||||
LT.setModulationParams(BandwidthBitRate, CodingRate, BT);
|
||||
LT.setPacketParams(PREAMBLE_LENGTH_32_BITS, FLRC_SYNC_WORD_LEN_P32S, RADIO_RX_MATCH_SYNCWORD_1, RADIO_PACKET_VARIABLE_LENGTH, 127, RADIO_CRC_3_BYTES, RADIO_WHITENING_OFF);
|
||||
LT.setDioIrqParams(IRQ_RADIO_ALL, (IRQ_TX_DONE + IRQ_RX_TX_TIMEOUT), 0, 0); //set for IRQ on TX done and timeout on DIO1
|
||||
LT.setSyncWord1(Sample_Syncword);
|
||||
//***************************************************************************************************
|
||||
|
||||
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();
|
||||
Serial.println();
|
||||
|
||||
Serial.print(F("Transmitter ready"));
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
/*******************************************************************************************************
|
||||
Programs for Arduino - Copyright of the author Stuart Robinson - 26/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. Some pins such as DIO1,
|
||||
//DIO2, BUZZER are not used by this sketch so they do not need to be connected and
|
||||
//should be set to -1.
|
||||
|
||||
#define NSS 10 //select pin on LoRa device
|
||||
#define NRESET 9 //reset pin on LoRa device
|
||||
#define RFBUSY 7 //RFBUSY pin on LoRa device
|
||||
#define LED1 8 //on board LED, high for on
|
||||
#define DIO1 3 //DIO0 pin on LoRa device, used for RX and TX done
|
||||
|
||||
#define LORA_DEVICE DEVICE_SX1280 //we need to define the device we are using
|
||||
|
||||
|
||||
//******* Setup LoRa Parameters Here ! ***************
|
||||
|
||||
//LoRa Modem Parameters
|
||||
#define Frequency 2445000000 //frequency of transmissions
|
||||
#define Offset 0 //offset frequency for calibration purposes
|
||||
|
||||
const uint8_t BandwidthBitRate = FLRC_BR_1_300_BW_1_2; //FLRC bandwidth and bit rate, 1.3Mbs
|
||||
const uint8_t CodingRate = FLRC_CR_1_2; //FLRC coding rate
|
||||
const uint8_t BT = RADIO_MOD_SHAPING_BT_1_0; //FLRC BT
|
||||
const uint32_t Sample_Syncword = 0x01234567; //FLRC uses syncword
|
||||
const int8_t TXpower = 10; //LoRa transmit power in dBm
|
||||
|
||||
|
||||
//******* Setup packet parameters Here ! ***************
|
||||
const uint8_t numberPackets = 50; //number of packets to send in transmit loop
|
||||
const uint8_t TXPacketL = 16; //length of packet to send
|
||||
const bool waitforACK = false; //set to true to have transmit wait for ack before continuing
|
||||
|
||||
|
||||
@@ -0,0 +1,183 @@
|
||||
/*******************************************************************************************************
|
||||
Programs for Arduino - Copyright of the author Stuart Robinson - 04/04/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 is a program that demonstrates the detailed setup of a LoRa test transmitter.
|
||||
A packet containing ASCII text is sent according to the frequency and LoRa settings specified in the
|
||||
'Settings.h' file. The pins to access the lora device need to be defined in the 'Settings.h' file also.
|
||||
|
||||
The details of the packet sent and any errors are shown on the Arduino IDE Serial Monitor, together with
|
||||
the transmit power used, the packet length and the CRC of the packet. The matching receive program,
|
||||
'104_LoRa_Receiver' can be used to check the packets are being sent correctly, the frequency and LoRa
|
||||
settings (in Settings.h) must be the same for the transmitter and receiver programs. Sample Serial
|
||||
Monitor output;
|
||||
|
||||
10dBm Packet> Hello World 1234567890* BytesSent,23 CRC,DAAB TransmitTime,64mS PacketsSent,2
|
||||
|
||||
Serial monitor baud rate is set at 9600
|
||||
*******************************************************************************************************/
|
||||
|
||||
#define Program_Version "V1.1"
|
||||
|
||||
#include <SPI.h> //the lora device is SPI based so load the SPI library
|
||||
#include <SX128XLT.h> //include the appropriate library
|
||||
#include "Settings.h" //include the setiings file, frequencies, LoRa settings etc
|
||||
|
||||
SX128XLT LT; //create a library class instance called LT
|
||||
|
||||
uint8_t TXPacketL;
|
||||
uint32_t TXPacketCount, startmS, endmS;
|
||||
|
||||
uint8_t buff[] = "Hello World 1234567890";
|
||||
|
||||
void loop()
|
||||
{
|
||||
Serial.print(TXpower); //print the transmit power defined
|
||||
Serial.print(F("dBm "));
|
||||
Serial.print(F("Packet> "));
|
||||
Serial.flush();
|
||||
|
||||
TXPacketL = sizeof(buff); //set TXPacketL to length of array
|
||||
buff[TXPacketL - 1] = '*'; //replace null character at buffer end so its visible on reciver
|
||||
|
||||
LT.printASCIIPacket(buff, TXPacketL); //print the buffer (the sent packet) as ASCII
|
||||
|
||||
digitalWrite(LED1, HIGH);
|
||||
startmS = millis(); //start transmit timer
|
||||
if (LT.transmit(buff, TXPacketL, 10000, TXpower, WAIT_TX)) //will return packet length sent if OK, otherwise 0 if transmit error
|
||||
{
|
||||
endmS = millis(); //packet sent, note end time
|
||||
TXPacketCount++;
|
||||
packet_is_OK();
|
||||
}
|
||||
else
|
||||
{
|
||||
packet_is_Error(); //transmit packet returned 0, there was an error
|
||||
}
|
||||
|
||||
digitalWrite(LED1, LOW);
|
||||
Serial.println();
|
||||
delay(packet_delay); //have a delay between packets
|
||||
}
|
||||
|
||||
|
||||
void packet_is_OK()
|
||||
{
|
||||
//if here packet has been sent OK
|
||||
uint16_t localCRC;
|
||||
|
||||
Serial.print(F(" BytesSent,"));
|
||||
Serial.print(TXPacketL); //print transmitted packet length
|
||||
localCRC = LT.CRCCCITT(buff, TXPacketL, 0xFFFF);
|
||||
Serial.print(F(" CRC,"));
|
||||
Serial.print(localCRC, HEX); //print CRC of transmitted packet
|
||||
Serial.print(F(" TransmitTime,"));
|
||||
Serial.print(endmS - startmS); //print transmit time of packet
|
||||
Serial.print(F("mS"));
|
||||
Serial.print(F(" PacketsSent,"));
|
||||
Serial.print(TXPacketCount); //print total of packets sent OK
|
||||
}
|
||||
|
||||
|
||||
void packet_is_Error()
|
||||
{
|
||||
//if here there was an error transmitting packet
|
||||
uint16_t IRQStatus;
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
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.print(F(__TIME__));
|
||||
Serial.print(F(" "));
|
||||
Serial.println(F(__DATE__));
|
||||
Serial.println(F(Program_Version));
|
||||
Serial.println();
|
||||
Serial.println(F("103_LoRa_Transmitter_Detailed_Setup Starting"));
|
||||
|
||||
SPI.begin();
|
||||
|
||||
//SPI beginTranscation is normally part of library routines, but if it is disabled in library
|
||||
//a single instance is needed here, so uncomment the program line below
|
||||
//SPI.beginTransaction(SPISettings(8000000, MSBFIRST, SPI_MODE0));
|
||||
|
||||
//setup hardware pins used by device, then check if device is found
|
||||
if (LT.begin(NSS, NRESET, RFBUSY, DIO1, DIO2, DIO3, RX_EN, TX_EN, LORA_DEVICE))
|
||||
{
|
||||
Serial.println(F("LoRa Device found"));
|
||||
led_Flash(2, 125); //two further quick LED flashes to indicate device found
|
||||
delay(1000);
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println(F("No device responding"));
|
||||
while (1)
|
||||
{
|
||||
led_Flash(50, 50); //long fast speed LED flash indicates device error
|
||||
}
|
||||
}
|
||||
|
||||
//The function call list below shows the complete setup for the LoRa device using the information defined in the
|
||||
//Settings.h file.
|
||||
//The 'Setup LoRa device' list below can be replaced with a single function call;
|
||||
//LT.setupLoRa(Frequency, Offset, SpreadingFactor, Bandwidth, CodeRate);
|
||||
|
||||
|
||||
//***************************************************************************************************
|
||||
//Setup LoRa device
|
||||
//***************************************************************************************************
|
||||
LT.setMode(MODE_STDBY_RC);
|
||||
LT.setRegulatorMode(USE_LDO);
|
||||
LT.setPacketType(PACKET_TYPE_LORA);
|
||||
LT.setRfFrequency(Frequency, Offset);
|
||||
LT.setBufferBaseAddress(0, 0);
|
||||
LT.setModulationParams(SpreadingFactor, Bandwidth, CodeRate);
|
||||
LT.setPacketParams(12, LORA_PACKET_VARIABLE_LENGTH, 255, LORA_CRC_ON, LORA_IQ_NORMAL, 0, 0);
|
||||
LT.setDioIrqParams(IRQ_RADIO_ALL, (IRQ_TX_DONE + IRQ_RX_TX_TIMEOUT), 0, 0);
|
||||
//***************************************************************************************************
|
||||
|
||||
|
||||
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();
|
||||
Serial.println();
|
||||
LT.printRegisters(0x900, 0x9FF); //print contents of device registers, normally 0x900 to 0x9FF
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
|
||||
Serial.print(F("Transmitter ready"));
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
/*******************************************************************************************************
|
||||
Programs for Arduino - Copyright of the author Stuart Robinson - 02/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, a ESP32 shield base with BBF board shield on
|
||||
//top. Be sure to change the definitions to match your own setup. Some pins such as DIO2, DIO3, BUZZER
|
||||
//may not be in used by this sketch so they do not need to be connected and should be included and 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 RFBUSY 25 //busy line
|
||||
|
||||
#define LED1 2 //on board LED, high for on
|
||||
#define DIO1 35 //DIO1 pin on LoRa device, used for RX and TX done
|
||||
#define DIO2 -1 //DIO2 pin on LoRa device, normally not used so set to -1
|
||||
#define DIO3 -1 //DIO3 pin on LoRa device, normally not used so set to -1
|
||||
#define RX_EN -1 //pin for RX enable, used on some SX128X devices, set to -1 if not used
|
||||
#define TX_EN -1 //pin for TX enable, used on some SX128X devices, set to -1 if not used
|
||||
#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_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_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; //LoRa transmit power in dBm
|
||||
|
||||
const uint16_t packet_delay = 1000; //mS delay between packets
|
||||
|
||||
@@ -0,0 +1,247 @@
|
||||
/*******************************************************************************************************
|
||||
Programs for Arduino - Copyright of the author Stuart Robinson - 04/04/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 is a program that demonstrates the detailed setup of a LoRa test receiver.
|
||||
The program listens for incoming packets using the LoRa settings in the 'Settings.h' file. The pins
|
||||
to access the lora device need to be defined in the 'Settings.h' file also.
|
||||
|
||||
There is a printout on the Arduino IDE Serial Monitor of the valid packets received, the packet is
|
||||
assumed to be in ASCII printable text, if it's not ASCII text characters from 0x20 to 0x7F, expect
|
||||
weird things to happen on the Serial Monitor. The LED will flash for each packet received and the
|
||||
buzzer will sound, if fitted.
|
||||
|
||||
Sample serial monitor output;
|
||||
|
||||
7s Hello World 1234567890*,CRC,DAAB,RSSI,-52dBm,SNR,9dB,Length,23,Packets,5,Errors,0,IRQreg,50
|
||||
|
||||
If there is a packet error it might look like this, which is showing a CRC error,
|
||||
|
||||
968s PacketError,RSSI,-87dBm,SNR,-11dB,Length,23,Packets,613,Errors,2,IRQreg,70,IRQ_HEADER_VALID,IRQ_CRC_ERROR,IRQ_RX_DONE
|
||||
|
||||
Serial monitor baud rate is set at 9600.
|
||||
*******************************************************************************************************/
|
||||
|
||||
#define Program_Version "V1.1"
|
||||
|
||||
#include <SPI.h> //the lora device is SPI based so load the SPI library
|
||||
#include <SX128XLT.h> //include the appropriate library
|
||||
#include "Settings.h" //include the setiings file, frequencies, LoRa settings etc
|
||||
|
||||
SX128XLT LT; //create a library class instance called LT
|
||||
|
||||
uint32_t RXpacketCount;
|
||||
uint32_t errors;
|
||||
|
||||
uint8_t RXBUFFER[RXBUFFER_SIZE]; //create the buffer that received packets are copied into
|
||||
|
||||
uint8_t RXPacketL; //stores length of packet received
|
||||
int8_t PacketRSSI; //stores RSSI of received packet
|
||||
int8_t PacketSNR; //stores signal to noise ratio (SNR) of received packet
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
RXPacketL = LT.receive(RXBUFFER, RXBUFFER_SIZE, 60000, WAIT_RX); //wait for a packet to arrive with 60seconds (60000mS) timeout
|
||||
|
||||
digitalWrite(LED1, HIGH); //something has happened
|
||||
|
||||
if (BUZZER > 0) //turn buzzer on
|
||||
{
|
||||
digitalWrite(BUZZER, HIGH);
|
||||
}
|
||||
|
||||
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 is 0
|
||||
{
|
||||
packet_is_Error();
|
||||
}
|
||||
else
|
||||
{
|
||||
packet_is_OK();
|
||||
}
|
||||
|
||||
if (BUZZER > 0)
|
||||
{
|
||||
digitalWrite(BUZZER, LOW); //buzzer off
|
||||
}
|
||||
|
||||
digitalWrite(LED1, LOW); //LED off
|
||||
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
|
||||
void packet_is_OK()
|
||||
{
|
||||
uint16_t IRQStatus, localCRC;
|
||||
|
||||
IRQStatus = LT.readIrqStatus(); //read the LoRa device IRQ status register
|
||||
|
||||
RXpacketCount++;
|
||||
|
||||
printElapsedTime(); //print elapsed time to Serial Monitor
|
||||
Serial.print(F(" "));
|
||||
LT.printASCIIPacket(RXBUFFER, RXPacketL); //print the packet as ASCII characters
|
||||
|
||||
localCRC = LT.CRCCCITT(RXBUFFER, RXPacketL, 0xFFFF); //calculate the CRC, this is the external CRC calculation of the RXBUFFER
|
||||
Serial.print(F(",CRC,")); //contents, not the LoRa device internal CRC
|
||||
Serial.print(localCRC, HEX);
|
||||
Serial.print(F(",RSSI,"));
|
||||
Serial.print(PacketRSSI);
|
||||
Serial.print(F("dBm,SNR,"));
|
||||
Serial.print(PacketSNR);
|
||||
Serial.print(F("dB,Length,"));
|
||||
Serial.print(RXPacketL);
|
||||
Serial.print(F(",Packets,"));
|
||||
Serial.print(RXpacketCount);
|
||||
Serial.print(F(",Errors,"));
|
||||
Serial.print(errors);
|
||||
Serial.print(F(",IRQreg,"));
|
||||
Serial.print(IRQStatus, HEX);
|
||||
}
|
||||
|
||||
|
||||
void packet_is_Error()
|
||||
{
|
||||
uint16_t IRQStatus;
|
||||
IRQStatus = LT.readIrqStatus(); //read the LoRa device IRQ status register
|
||||
|
||||
printElapsedTime(); //print elapsed time to Serial Monitor
|
||||
|
||||
if (IRQStatus & IRQ_RX_TIMEOUT) //check for an RX timeout
|
||||
{
|
||||
Serial.print(F(" RXTimeout"));
|
||||
}
|
||||
else
|
||||
{
|
||||
errors++;
|
||||
Serial.print(F(" PacketError"));
|
||||
Serial.print(F(",RSSI,"));
|
||||
Serial.print(PacketRSSI);
|
||||
Serial.print(F("dBm,SNR,"));
|
||||
Serial.print(PacketSNR);
|
||||
Serial.print(F("dB,Length,"));
|
||||
Serial.print(LT.readRXPacketL()); //get the device packet length
|
||||
Serial.print(F(",Packets,"));
|
||||
Serial.print(RXpacketCount);
|
||||
Serial.print(F(",Errors,"));
|
||||
Serial.print(errors);
|
||||
Serial.print(F(",IRQreg,"));
|
||||
Serial.print(IRQStatus, HEX);
|
||||
LT.printIrqStatus(); //print the names of the IRQ registers set
|
||||
}
|
||||
|
||||
delay(250); //gives a longer buzzer and LED flash for error
|
||||
|
||||
}
|
||||
|
||||
|
||||
void printElapsedTime()
|
||||
{
|
||||
float seconds;
|
||||
seconds = millis() / 1000;
|
||||
Serial.print(seconds, 0);
|
||||
Serial.print(F("s"));
|
||||
}
|
||||
|
||||
|
||||
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.print(F(__TIME__));
|
||||
Serial.print(F(" "));
|
||||
Serial.println(F(__DATE__));
|
||||
Serial.println(F(Program_Version));
|
||||
Serial.println();
|
||||
Serial.println(F("104_LoRa_Receiver_Detailed_Setup_ESP32 Starting"));
|
||||
Serial.println();
|
||||
|
||||
if (BUZZER > 0)
|
||||
{
|
||||
pinMode(BUZZER, OUTPUT);
|
||||
digitalWrite(BUZZER, HIGH);
|
||||
delay(50);
|
||||
digitalWrite(BUZZER, LOW);
|
||||
}
|
||||
|
||||
SPI.begin();
|
||||
|
||||
//SPI beginTranscation is normally part of library routines, but if it is disabled in the library
|
||||
//a single instance is needed here, so uncomment the program line below
|
||||
//SPI.beginTransaction(SPISettings(8000000, MSBFIRST, SPI_MODE0));
|
||||
|
||||
//setup hardware pins used by device, then check if device is found
|
||||
if (LT.begin(NSS, NRESET, RFBUSY, DIO1, DIO2, DIO3, RX_EN, TX_EN, 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 LED flash indicates device error
|
||||
}
|
||||
}
|
||||
|
||||
//The function call list below shows the complete setup for the LoRa device using the information defined in the
|
||||
//Settings.h file.
|
||||
//The 'Setup LoRa device' list below can be replaced with a single function call;
|
||||
//LT.setupLoRa(Frequency, Offset, SpreadingFactor, Bandwidth, CodeRate);
|
||||
|
||||
//***************************************************************************************************
|
||||
//Setup LoRa device
|
||||
//***************************************************************************************************
|
||||
LT.setMode(MODE_STDBY_RC);
|
||||
LT.setRegulatorMode(USE_LDO);
|
||||
LT.setPacketType(PACKET_TYPE_LORA);
|
||||
LT.setRfFrequency(Frequency, Offset);
|
||||
LT.setBufferBaseAddress(0, 0);
|
||||
LT.setModulationParams(SpreadingFactor, Bandwidth, CodeRate);
|
||||
LT.setPacketParams(12, LORA_PACKET_VARIABLE_LENGTH, 255, LORA_CRC_ON, LORA_IQ_NORMAL, 0, 0);
|
||||
LT.setDioIrqParams(IRQ_RADIO_ALL, (IRQ_TX_DONE + IRQ_RX_TX_TIMEOUT), 0, 0);
|
||||
//***************************************************************************************************
|
||||
|
||||
|
||||
Serial.println();
|
||||
LT.printModemSettings(); //reads and prints the configured LoRa settings, useful check
|
||||
Serial.println();
|
||||
LT.printOperatingSettings(); //reads and prints the configured operting settings, useful check
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
LT.printRegisters(0x900, 0x9FF); //print contents of device registers, normally 0x900 to 0x9FF
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
|
||||
Serial.print(F("Receiver ready - RXBUFFER_SIZE "));
|
||||
Serial.println(RXBUFFER_SIZE);
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
/*******************************************************************************************************
|
||||
Programs for Arduino - Copyright of the author Stuart Robinson - 04/04/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, a ESP32 shield base with BBF board shield on
|
||||
//top. Be sure to change the definitions to match your own setup. Some pins such as DIO2, DIO3, BUZZER
|
||||
//may not be in used by this sketch so they do not need to be connected and should be included and 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 RFBUSY 25 //busy line
|
||||
|
||||
#define LED1 2 //on board LED, high for on
|
||||
#define DIO1 35 //DIO1 pin on LoRa device, used for RX and TX done
|
||||
#define DIO2 -1 //DIO2 pin on LoRa device, normally not used so set to -1
|
||||
#define DIO3 -1 //DIO3 pin on LoRa device, normally not used so set to -1
|
||||
#define RX_EN -1 //pin for RX enable, used on some SX128X devices, set to -1 if not used
|
||||
#define TX_EN -1 //pin for TX enable, used on some SX128X devices, set to -1 if not used
|
||||
#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_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_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; //LoRa transmit power in dBm
|
||||
|
||||
const uint16_t packet_delay = 1000; //mS delay between packets
|
||||
|
||||
#define RXBUFFER_SIZE 32 //RX buffer size
|
||||
|
||||
|
||||
|
||||
|
After Width: | Height: | Size: 38 KiB |
|
After Width: | Height: | Size: 88 KiB |
111
lib/SX12XX-LoRa/examples/SX128x_examples/ESP32/ReadMe.md
Normal file
@@ -0,0 +1,111 @@
|
||||
## ESP32 - SX12XX Library Example Programs
|
||||
|
||||
Having originally tested the SX127X part of the library on a ATMega328P based micro controller I decided to check that the library was code compatible with another popular processor that can be programmed in the Arduino IDE, the ESP32.
|
||||
|
||||
Unfortunately there is frequently a misunderstanding about what an 'ESP32' is. The ESP32 is a single surface mountable module to which you need to add various components to make a usable board. However the many different types of 'ESP32' boards may use different types of components and connections which could conflict with the pins used in the library examples here. It is not practical to test the examples on all possible permutations of 'ESP32' assembled boards, there are over 60 different boards supported by the Arduino IDE and I would go poor buying them all.
|
||||
|
||||
Thus the ESP32 examples presented here have been tested against a known standard which is an actual ESP32 Wroom module with no additional hardware, apart from the components shown in the schematic below. It is possible that the examples will not work against your particular 'ESP32' assembled board. If the example programs do not work for you, it is not an issue with the library but a difference between the reference hardware and your particular setup. I am not in a position to assist in resolving issues with particular ESP32 board versions.
|
||||
|
||||

|
||||
|
||||
|
||||
As well as testing against the bare bones ESP32 schematic shown above, some of the examples will have been tested on a small portable unit I built which follows the same principles of the bare bones schematic. This PCB was developed to create a PCB that could be used for a small ESP32 based GPS tracker node, initially for use on The Things Network. The board has a GPS, I2C SSD1306 OLED and RFM98 lora device. There are options for a micro SD card, DS18B20 temperature sensor and a I2C FRAM. With it all assembled, the node consumes around 31uA in deep sleep with all devices connected. The 'Micro\_Node' contains additional circuitry to power off devices such as the lora module and GPS. Its highly unlikely that a standard ESP32 board will achieve a sleep current anywhere near the 'Micro_Node', this unit is pictured below;
|
||||
|
||||

|
||||
|
||||
|
||||
### ESP32 Deep Sleep
|
||||
|
||||
The ESP32 does some things with I\O pins when going into deep sleep that you might not expect. There are functions in this SX12XX library for putting the LoRa device into deep sleep, whilst still preserving register settings. The current then taken by the lora device is circa 0.5uA. However these functions will likely not work directly with most ESP32 boards due to the way the ESP32 handles the I\O pins in deep sleep mode.
|
||||
|
||||
When designing a board where a very low deep sleep current it is important, you need to build the design in stages, checking the deep sleep current after adding each component. Debugging a high deep sleep current on a fully assembled board can be from extremely difficult to impossible. Achieving a low deep sleep current for particular ESP32 boards is well outside the scope of this SX12xx library.
|
||||
|
||||
<br>
|
||||
|
||||
**3\_LoRa\_Transmitter and 4\_LoRa\_Receiver example programs**
|
||||
|
||||
These example programs work when used with the ESP32 'bare bones' schematic shown earlier and the 'ESP32 Dev Module' board type selected in the Arduino IDE.
|
||||
|
||||
The pins used for SPI were;
|
||||
|
||||
SCK 18
|
||||
MISO 19
|
||||
MOSI 23
|
||||
NSS 5
|
||||
NRESET 27
|
||||
RFBUSY 25 (SX126X and SX128X devices only)
|
||||
DIOX 35 (DIOX is DIO0 on the SX127X devices and DIO1 on SX126X and SX128X devices)
|
||||
|
||||
In the example programs for ESP32, you can start the SPI with;
|
||||
|
||||
SPI.begin();
|
||||
|
||||
And the default SPI pin outs for the ESP32 module shown above will be used.
|
||||
|
||||
Alternatively you can uses this format to start SPI;
|
||||
|
||||
SPI.begin(SCK, MISO, MOSI, NSS);
|
||||
|
||||
And the pin definitions will be taken from those specified in the 'Settings.h' file. If you change these pin allocations from the defaults given you will need to be sure they are valid for your particular ESP32 board.
|
||||
|
||||
|
||||
The SX12XX example programs are specifically written for and and tested on ATmega processors such as 328,1284 and 2560. However most will work, with minor modification, on the ESP32.
|
||||
|
||||
This is a run through of the changes that were needed to have the tracker receiver examples; **25\_GPS\_Tracker\_Receiver\_With\_Display\_and\_GPS**, written for the ATmega328P run on the ESP32 bare bones type boards described above.
|
||||
|
||||
The original SX12XX tracker program uses the SPI interface to talk to the lora device, I2C to talk to the OLED display and software serial to talk to the GPS.
|
||||
|
||||
The pins used for SPI were;
|
||||
|
||||
SCK 18
|
||||
MISO 19
|
||||
MOSI 23
|
||||
NSS 5
|
||||
NRESET 27
|
||||
RFBUSY 25 (SX126X and SX128X devices only)
|
||||
DIOX 35 (DIOX is DIO0 on the SX127X devices and DIO1 on SX126X and SX128X devices)
|
||||
|
||||
The ESP32 I2C pin connections were;
|
||||
|
||||
SDA 21
|
||||
SCL 22
|
||||
|
||||
There is no need for software serial on the ESP32 as it has an available hardware serial port. These are the pin connections used;
|
||||
|
||||
GPSTX 16 //this is data out from the GPS into the ESP32
|
||||
GPSRX 17 //this is data out from the ESP32 into the GPS
|
||||
|
||||
The other pins used were;
|
||||
|
||||
LED1 2 //On board indicator LED, logic high for on
|
||||
GPSPOWER 26 //Pin that controls power to GPS, set to -1 if not used
|
||||
|
||||
The only software changes required were to change the lines in the Settings.h file from;
|
||||
|
||||
#define USE_SOFTSERIAL_GPS
|
||||
#define HardwareSerialPort Serial2
|
||||
|
||||
to;
|
||||
|
||||
//#define USE_SOFTSERIAL_GPS
|
||||
#define HardwareSerialPort Serial2
|
||||
|
||||
This removes the definition USE\_SOFTSERIAL\_GPS from the sketch and the effect of this change is then to remove these two lines from the Sketch;
|
||||
|
||||
#include <SoftwareSerial.h>
|
||||
SoftwareSerial GPSserial(RXpin, Txpin);
|
||||
|
||||
And include this one;
|
||||
|
||||
#define GPSserial HardwareSerialPort
|
||||
|
||||
Which sets the commands to read data from the GPS such as GPSserial.read() to be in effect Serial2.read(), which is the ESP32 hardware serial port used.
|
||||
|
||||
|
||||
**Note:** The provided lora settings (in the Settings.h file) may not be optimised for long distance. See the 'What is LoRa' document for information on how LoRa settings affect range.
|
||||
|
||||
|
||||
### Stuart Robinson
|
||||
|
||||
### April 2020
|
||||
|
||||
@@ -0,0 +1,154 @@
|
||||
/*******************************************************************************************************
|
||||
Programs for Arduino - Copyright of the author Stuart Robinson - 08/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 packet without using a processor buffer, the LoRa device
|
||||
internal buffer is filled direct with variables. The program is a simulation of the type of packet
|
||||
that might be sent from a GPS tracker. Note that in this example a buffer of text is part of the
|
||||
transmitted packet, this does need a processor buffer which is used to fill the LoRa device internal
|
||||
buffer, if you don't need to transmit text then the uint8_t trackerID[] = "Tracker1"; definition
|
||||
can be ommited.
|
||||
|
||||
The matching receiving program '9_LoRa_LowMemory_RX' can be used to receive and display the packet,
|
||||
though the program '15_LoRa_RX_Structure' should receive it as well, since the packet contents are
|
||||
the same.
|
||||
|
||||
The contents of the packet received, and printed to serial monitor, should be;
|
||||
|
||||
"tracker1" (buffer) - trackerID
|
||||
1+ (uint32_t) - packet count
|
||||
51.23456 (float) - latitude
|
||||
-3.12345 (float) - longitude
|
||||
199 (uint16_t) - altitude
|
||||
8 (uint8_t) - number of satellites
|
||||
3999 (uint16_t) - battery voltage
|
||||
-9 (int8_t) - temperature
|
||||
|
||||
Serial monitor baud rate is set at 9600.
|
||||
|
||||
*******************************************************************************************************/
|
||||
|
||||
#include <SPI.h>
|
||||
#include <SX128XLT.h>
|
||||
#include "Settings.h"
|
||||
|
||||
SX128XLT LT;
|
||||
|
||||
uint32_t TXpacketCount = 0;
|
||||
uint8_t TXPacketL;
|
||||
uint32_t startmS, endmS;
|
||||
|
||||
void loop()
|
||||
{
|
||||
TXpacketCount++;
|
||||
|
||||
if (Send_Test_Packet())
|
||||
{
|
||||
Serial.print(TXpacketCount);
|
||||
Serial.print(F(" "));
|
||||
Serial.print(TXPacketL);
|
||||
Serial.print(F(" Bytes Sent"));
|
||||
Serial.print(F(" "));
|
||||
Serial.print(endmS - startmS);
|
||||
Serial.print(F("mS"));
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.print(F("Send Error - IRQreg,"));
|
||||
Serial.print(LT.readIrqStatus(), HEX);
|
||||
}
|
||||
|
||||
Serial.println();
|
||||
delay(packet_delay);
|
||||
}
|
||||
|
||||
|
||||
uint8_t Send_Test_Packet()
|
||||
{
|
||||
//The SX12XX buffer is filled with variables of a known type and order. Make sure the receiver
|
||||
//uses the same variable type and order to read variables out of the receive buffer.
|
||||
|
||||
float latitude, longitude;
|
||||
uint16_t altitude, voltage;
|
||||
uint8_t satellites;
|
||||
int16_t temperature;
|
||||
uint8_t len;
|
||||
|
||||
//test data
|
||||
uint8_t trackerID[] = "tracker1";
|
||||
latitude = 51.23456;
|
||||
longitude = -3.12345;
|
||||
altitude = 199;
|
||||
satellites = 9;
|
||||
voltage = 3999;
|
||||
temperature = -9;
|
||||
|
||||
LT.startWriteSXBuffer(0); //start the write at location 0
|
||||
LT.writeBuffer(trackerID, sizeof(trackerID)); //= 13 bytes (12 characters plus null (0) at end)
|
||||
LT.writeUint32(TXpacketCount); //+4 = 17 bytes
|
||||
LT.writeFloat(latitude); //+4 = 21 bytes
|
||||
LT.writeFloat(longitude); //+4 = 25 bytes
|
||||
LT.writeUint16(altitude); //+2 = 27 bytes
|
||||
LT.writeUint8(satellites); //+1 = 28 bytes
|
||||
LT.writeUint16(voltage); //+2 = 30 bytes
|
||||
LT.writeInt8(temperature); //+1 = 31 bytes total to send
|
||||
len = LT.endWriteSXBuffer();
|
||||
|
||||
digitalWrite(LED1, HIGH);
|
||||
startmS = millis();
|
||||
|
||||
TXPacketL = LT.transmitSXBuffer(0, len, 5000, TXpower, WAIT_TX); //set a TX timeout of 5000mS
|
||||
|
||||
endmS = millis();
|
||||
|
||||
digitalWrite(LED1, LOW);
|
||||
|
||||
return TXPacketL;
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
|
||||
SPI.begin();
|
||||
|
||||
if (LT.begin(NSS, NRESET, RFBUSY, DIO1, DIO2, DIO3, RX_EN, TX_EN, 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.println(F("Transmitter ready"));
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/*******************************************************************************************************
|
||||
Programs for Arduino - Copyright of the author Stuart Robinson - 06/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. Some pins such as DIO2,
|
||||
//DIO3, BUZZER may not be in used by this sketch so they do not need to be
|
||||
//connected and should be included and be set to -1.
|
||||
|
||||
#define NSS 10
|
||||
#define RFBUSY 7
|
||||
#define NRESET 9
|
||||
#define LED1 8
|
||||
#define DIO1 3
|
||||
#define DIO2 -1 //not used
|
||||
#define DIO3 -1 //not used
|
||||
#define RX_EN -1 //pin for RX enable, used on some SX1280 devices, set to -1 if not used
|
||||
#define TX_EN -1 //pin for TX enable, used on some SX1280 devices, set to -1 if not used
|
||||
#define BUZZER -1 //connect a buzzer here if wanted
|
||||
|
||||
#define LORA_DEVICE DEVICE_SX1280 //we need to define the device we are using
|
||||
|
||||
//LoRa Modem Parameters
|
||||
#define Frequency 2445000000 //frequency of transmissions
|
||||
#define Offset 0 //offset frequency for calibration purposes
|
||||
#define Bandwidth LORA_BW_0400 //LoRa bandwidth
|
||||
#define SpreadingFactor LORA_SF7 //LoRa spreading factor
|
||||
#define CodeRate LORA_CR_4_5 //LoRa coding rate
|
||||
|
||||
#define TXpower 10 //power for transmissions in dBm
|
||||
|
||||
#define packet_delay 1000 //mS delay between packets
|
||||
|
||||
@@ -0,0 +1,195 @@
|
||||
/*******************************************************************************************************
|
||||
Programs for Arduino - Copyright of the author Stuart Robinson - 08/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 packet without using a processor buffer, the LoRa device
|
||||
internal buffer is read direct and copied to variables. The program is a simulation of the type of packet
|
||||
that might be received from a GPS tracker. Note that in this example a buffer of text is part of the
|
||||
received packet, this does need a processor buffer which is filled with data from the LoRa device internal
|
||||
buffer, if you don't need to send and receive text then the uint8_t receivebuffer[32]; definition can be
|
||||
ommited.
|
||||
|
||||
The contents of the packet received, and printed to serial monitor, should be;
|
||||
|
||||
"Tracker1" (buffer) - trackerID
|
||||
1+ (uint32_t) - packet count
|
||||
51.23456 (float) - latitude
|
||||
-3.12345 (float) - longitude
|
||||
199 (uint16_t) - altitude
|
||||
8 (uint8_t) - number of satellites
|
||||
3999 (uint16_t) - battery voltage
|
||||
-9 (int8_t) - temperature
|
||||
|
||||
Serial monitor baud rate is set at 9600.
|
||||
|
||||
*******************************************************************************************************/
|
||||
|
||||
#include <SPI.h>
|
||||
#include <SX128XLT.h>
|
||||
#include "Settings.h"
|
||||
|
||||
SX128XLT LT;
|
||||
|
||||
uint32_t RXpacketCount;
|
||||
uint16_t errors;
|
||||
|
||||
uint8_t RXPacketL; //length of received packet
|
||||
int8_t PacketRSSI; //RSSI of received packet
|
||||
int8_t PacketSNR; //signal to noise ratio of received packet
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
|
||||
RXPacketL = LT.receiveSXBuffer(0, 0, WAIT_RX); //returns 0 if packet error of some sort, no timeout
|
||||
|
||||
digitalWrite(LED1, HIGH); //something has happened
|
||||
|
||||
PacketRSSI = LT.readPacketRSSI();
|
||||
PacketSNR = LT.readPacketSNR();
|
||||
|
||||
if (RXPacketL == 0)
|
||||
{
|
||||
packet_is_Error();
|
||||
}
|
||||
else
|
||||
{
|
||||
packet_is_OK();
|
||||
}
|
||||
|
||||
digitalWrite(LED1, LOW);
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
|
||||
uint8_t packet_is_OK()
|
||||
{
|
||||
float latitude, longitude;
|
||||
uint16_t altitude, voltage;
|
||||
uint8_t satellites;
|
||||
int8_t temperature;
|
||||
uint32_t txcount;
|
||||
|
||||
uint8_t receivebuffer[16]; //create receive buffer, make sure this is big enough for buffer sent !!!
|
||||
|
||||
//packet has been received, now read from the SX12xx Buffer using the same variable type and
|
||||
//order as the transmit side used.
|
||||
|
||||
RXpacketCount++;
|
||||
Serial.print(RXpacketCount);
|
||||
Serial.print(F(" "));
|
||||
|
||||
LT.startReadSXBuffer(0); //start buffer read at location 0
|
||||
LT.readBuffer(receivebuffer); //read in the character buffer
|
||||
txcount = LT.readUint32(); //read in the TXCount
|
||||
latitude = LT.readFloat(); //read in the latitude
|
||||
longitude = LT.readFloat(); //read in the longitude
|
||||
altitude = LT.readUint16(); //read in the altitude
|
||||
satellites = LT.readUint8(); //read in the number of satellites
|
||||
voltage = LT.readUint16(); //read in the voltage
|
||||
temperature = LT.readInt8(); //read in the temperature
|
||||
RXPacketL = LT.endReadSXBuffer();
|
||||
|
||||
Serial.print((char*)receivebuffer); //print the received buffer, cast to char needed
|
||||
Serial.print(F(","));
|
||||
Serial.print(txcount);
|
||||
Serial.print(F(","));
|
||||
Serial.print(latitude, 5);
|
||||
Serial.print(F(","));
|
||||
Serial.print(longitude, 5);
|
||||
Serial.print(F(","));
|
||||
Serial.print(altitude);
|
||||
Serial.print(F("m,"));
|
||||
Serial.print(satellites);
|
||||
Serial.print(F("sats,"));
|
||||
Serial.print(voltage);
|
||||
Serial.print(F("mV,"));
|
||||
Serial.print(temperature);
|
||||
Serial.print(F("c "));
|
||||
Serial.print(F(" RSSI"));
|
||||
Serial.print(PacketRSSI);
|
||||
Serial.print(F("dBm,SNR,"));
|
||||
Serial.print(PacketSNR);
|
||||
Serial.print(F("dB"));
|
||||
return RXPacketL;
|
||||
}
|
||||
|
||||
|
||||
void packet_is_Error()
|
||||
{
|
||||
uint16_t IRQStatus;
|
||||
IRQStatus = LT.readIrqStatus();
|
||||
|
||||
if (IRQStatus & IRQ_RX_TIMEOUT)
|
||||
{
|
||||
Serial.print(F("RXTimeout"));
|
||||
}
|
||||
else
|
||||
{
|
||||
errors++;
|
||||
Serial.print(F("PacketError"));
|
||||
printpacketDetails();
|
||||
Serial.print(F("IRQreg,"));
|
||||
Serial.print(IRQStatus, HEX);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void printpacketDetails()
|
||||
{
|
||||
Serial.print(F(" RSSI,"));
|
||||
Serial.print(PacketRSSI);
|
||||
Serial.print(F("dBm,SNR,"));
|
||||
Serial.print(PacketSNR);
|
||||
Serial.print(F("dB"));
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
|
||||
SPI.begin();
|
||||
|
||||
if (LT.begin(NSS, NRESET, RFBUSY, DIO1, DIO2, DIO3, RX_EN, TX_EN, 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.println(F("Receiver ready"));
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
/*******************************************************************************************************
|
||||
Programs for Arduino - Copyright of the author Stuart Robinson - 06/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. Some pins such as DIO2,
|
||||
//DIO3, BUZZER may not be in used by this sketch so they do not need to be
|
||||
//connected and should be included and be set to -1.
|
||||
|
||||
#define NSS 10
|
||||
#define RFBUSY 7
|
||||
#define NRESET 9
|
||||
#define LED1 8
|
||||
#define DIO1 3
|
||||
#define DIO2 -1 //not used
|
||||
#define DIO3 -1 //not used
|
||||
#define RX_EN -1 //pin for RX enable, used on some SX1280 devices, set to -1 if not used
|
||||
#define TX_EN -1 //pin for TX enable, used on some SX1280 devices, set to -1 if not used
|
||||
#define BUZZER -1 //connect a buzzer here if wanted
|
||||
|
||||
#define LORA_DEVICE DEVICE_SX1280 //we need to define the device we are using
|
||||
|
||||
//LoRa Modem Parameters
|
||||
#define Frequency 2445000000 //frequency of transmissions
|
||||
#define Offset 0 //offset frequency for calibration purposes
|
||||
#define Bandwidth LORA_BW_0400 //LoRa bandwidth
|
||||
#define SpreadingFactor LORA_SF7 //LoRa spreading factor
|
||||
#define CodeRate LORA_CR_4_5 //LoRa coding rate
|
||||
|
||||
#define TXpower 10 //power for transmissions in dBm
|
||||
|
||||
#define packet_delay 1000 //mS delay between packets
|
||||
|
||||
#define RXBUFFER_SIZE 255 //RX buffer size, not used in this program
|
||||
|
||||
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 222 KiB |
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 18 KiB |
@@ -0,0 +1,212 @@
|
||||
/*****************************************************************************************************
|
||||
Programs for Arduino - Copyright of the author Stuart Robinson - 16/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.
|
||||
*******************************************************************************************************/
|
||||
|
||||
#define Program_Version "V1.0"
|
||||
|
||||
#include <SPI.h>
|
||||
#include <SX128XLT.h>
|
||||
#include "Settings.h"
|
||||
|
||||
SX128XLT LT;
|
||||
|
||||
|
||||
#ifdef ENABLEOLED
|
||||
#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
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
uint16_t rangeing_errors, rangeings_valid, rangeing_results;
|
||||
uint16_t IrqStatus;
|
||||
uint32_t endwaitmS, startrangingmS, range_result_sum, range_result_average;
|
||||
float distance, distance_sum, distance_average;
|
||||
bool ranging_error;
|
||||
int32_t range_result;
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
uint8_t index;
|
||||
distance_sum = 0;
|
||||
range_result_sum = 0;
|
||||
rangeing_results = 0; //count of valid results in each loop
|
||||
|
||||
for (index = 1; index <= rangeingcount; index++)
|
||||
{
|
||||
|
||||
startrangingmS = millis();
|
||||
|
||||
LT.transmitRanging(RangingAddress, TXtimeoutmS, RangingTXPower, WAIT_TX);
|
||||
|
||||
IrqStatus = LT.readIrqStatus();
|
||||
|
||||
if (IrqStatus & IRQ_RANGING_MASTER_RESULT_VALID)
|
||||
{
|
||||
rangeing_results++;
|
||||
rangeings_valid++;
|
||||
digitalWrite(LED1, HIGH);
|
||||
Serial.print(F("Valid"));
|
||||
range_result = LT.getRangingResultRegValue(RANGING_RESULT_RAW);
|
||||
Serial.print(F(",Register,"));
|
||||
Serial.print(range_result);
|
||||
|
||||
if (range_result > 800000)
|
||||
{
|
||||
range_result = 0;
|
||||
}
|
||||
range_result_sum = range_result_sum + range_result;
|
||||
|
||||
distance = LT.getRangingDistance(RANGING_RESULT_RAW, range_result, distance_adjustment);
|
||||
distance_sum = distance_sum + distance;
|
||||
|
||||
Serial.print(F(",Distance,"));
|
||||
Serial.print(distance, 1);
|
||||
digitalWrite(LED1, LOW);
|
||||
}
|
||||
else
|
||||
{
|
||||
rangeing_errors++;
|
||||
distance = 0;
|
||||
range_result = 0;
|
||||
Serial.print(F("NotValid"));
|
||||
Serial.print(F(",Irq,"));
|
||||
Serial.print(IrqStatus, HEX);
|
||||
}
|
||||
delay(packet_delaymS);
|
||||
|
||||
if (index == rangeingcount)
|
||||
{
|
||||
range_result_average = (range_result_sum / rangeing_results);
|
||||
|
||||
if (rangeing_results == 0)
|
||||
{
|
||||
distance_average = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
distance_average = (distance_sum / rangeing_results);
|
||||
}
|
||||
|
||||
Serial.print(F(",TotalValid,"));
|
||||
Serial.print(rangeings_valid);
|
||||
Serial.print(F(",TotalErrors,"));
|
||||
Serial.print(rangeing_errors);
|
||||
Serial.print(F(",AverageRAWResult,"));
|
||||
Serial.print(range_result_average);
|
||||
Serial.print(F(",AverageDistance,"));
|
||||
Serial.print(distance_average, 1);
|
||||
|
||||
#ifdef ENABLEDISPLAY
|
||||
display_screen1();
|
||||
#endif
|
||||
|
||||
delay(2000);
|
||||
|
||||
}
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#ifdef ENABLEDISPLAY
|
||||
void display_screen1()
|
||||
{
|
||||
disp.clear();
|
||||
disp.setCursor(0, 0);
|
||||
disp.print(F("Distance "));
|
||||
disp.print(distance_average, 1);
|
||||
disp.print(F("m"));
|
||||
disp.setCursor(0, 2);
|
||||
disp.print(F("OK,"));
|
||||
disp.print(rangeings_valid);
|
||||
disp.print(F(",Err,"));
|
||||
disp.print(rangeing_errors);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
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(4, 125); //two quick LED flashes to indicate program start
|
||||
|
||||
Serial.begin(9600);
|
||||
Serial.println();
|
||||
Serial.print(F(__TIME__));
|
||||
Serial.print(F(" "));
|
||||
Serial.println(F(__DATE__));
|
||||
Serial.println(F(Program_Version));
|
||||
Serial.println();
|
||||
Serial.println(F("54_Ranging_Master Starting"));
|
||||
|
||||
SPI.begin();
|
||||
|
||||
led_Flash(2, 125);
|
||||
|
||||
if (LT.begin(NSS, NRESET, RFBUSY, DIO1, LORA_DEVICE))
|
||||
{
|
||||
Serial.println(F("Device found"));
|
||||
led_Flash(2, 125);
|
||||
delay(1000);
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println(F("No device responding"));
|
||||
while (1)
|
||||
{
|
||||
led_Flash(50, 50); //long fast flash indicates device error
|
||||
}
|
||||
}
|
||||
|
||||
LT.setupRanging(Frequency, Offset, SpreadingFactor, Bandwidth, CodeRate, RangingAddress, RANGING_MASTER);
|
||||
|
||||
//LT.setRangingCalibration(Calibration); //override automatic lookup of calibration value from library table
|
||||
|
||||
#ifdef ENABLEDISPLAY
|
||||
Serial.println("Display Enabled");
|
||||
disp.begin();
|
||||
disp.setFont(u8x8_font_chroma48medium8_r);
|
||||
disp.setCursor(0, 0);
|
||||
disp.print(F("Ranging RAW Ready"));
|
||||
disp.setCursor(0, 1);
|
||||
disp.print(F("Power "));
|
||||
disp.print(RangingTXPower);
|
||||
disp.print(F("dBm"));
|
||||
disp.setCursor(0, 2);
|
||||
disp.print(F("Cal "));
|
||||
disp.print(Calibration);
|
||||
disp.setCursor(0, 3);
|
||||
disp.print(F("Adjust "));
|
||||
disp.print(distance_adjustment, 4);
|
||||
#endif
|
||||
|
||||
|
||||
Serial.print(F("Address "));
|
||||
Serial.println(RangingAddress);
|
||||
Serial.print(F("CalibrationValue "));
|
||||
Serial.println(LT.getSetCalibrationValue());
|
||||
Serial.println(F("Ranging master RAW ready"));
|
||||
|
||||
delay(2000);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
/*****************************************************************************************************
|
||||
Programs for Arduino - Copyright of the author Stuart Robinson - 16/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. Some pins such as DIO2,
|
||||
//DIO3, BUZZER may not be in used by this sketch so they do not need to be
|
||||
//connected and should be included and be set to -1.
|
||||
|
||||
|
||||
#define NSS 10
|
||||
#define RFBUSY 7
|
||||
#define NRESET 9
|
||||
#define LED1 8
|
||||
#define DIO1 3
|
||||
|
||||
#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 in hz
|
||||
const int32_t Offset = 0; //offset frequency in hz for calibration purposes
|
||||
const uint8_t Bandwidth = LORA_BW_0800; //LoRa bandwidth
|
||||
const uint8_t SpreadingFactor = LORA_SF8; //LoRa spreading factor
|
||||
const uint8_t CodeRate = LORA_CR_4_5; //LoRa coding rate
|
||||
const uint16_t Calibration = 11350; //Manual Ranging calibrarion value
|
||||
|
||||
const uint8_t RangingTXPower = 10; //Transmit power used
|
||||
const uint32_t RangingAddress = 16; //must match address in recever
|
||||
|
||||
const uint16_t waittimemS = 10000; //wait this long in mS for packet before assuming timeout
|
||||
const uint16_t TXtimeoutmS = 5000; //ranging TX timeout in mS
|
||||
const uint16_t packet_delaymS = 0; //forced extra delay in mS between ranging requests
|
||||
const uint16_t rangeingcount = 5; //number of times ranging is cqarried out for each distance measurment
|
||||
float distance_adjustment = 1.0000; //adjustment factor to calculated distance
|
||||
|
||||
|
||||
#define ENABLEOLED //enable this define to use display
|
||||
#define ENABLEDISPLAY //enable this define to use display
|
||||
|
||||
|
||||
@@ -0,0 +1,147 @@
|
||||
/*******************************************************************************************************
|
||||
Programs for Arduino - Copyright of the author Stuart Robinson - 16/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
|
||||
*******************************************************************************************************/
|
||||
|
||||
#define programversion "V1.0"
|
||||
|
||||
#include <SPI.h>
|
||||
#include <SX128XLT.h>
|
||||
#include "Settings.h"
|
||||
|
||||
SX128XLT LT;
|
||||
|
||||
uint32_t endwaitmS;
|
||||
uint16_t IrqStatus;
|
||||
uint32_t response_sent;
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
LT.receiveRanging(RangingAddress, 0, TXpower, NO_WAIT);
|
||||
|
||||
endwaitmS = millis() + rangingRXTimeoutmS;
|
||||
|
||||
while (!digitalRead(DIO1) && (millis() <= endwaitmS)); //wait for Ranging valid or timeout
|
||||
|
||||
if (millis() >= endwaitmS)
|
||||
{
|
||||
Serial.println("Error - Ranging Receive Timeout!!");
|
||||
led_Flash(2, 100); //single flash to indicate timeout
|
||||
}
|
||||
else
|
||||
{
|
||||
IrqStatus = LT.readIrqStatus();
|
||||
digitalWrite(LED1, HIGH);
|
||||
|
||||
if (IrqStatus & IRQ_RANGING_SLAVE_RESPONSE_DONE)
|
||||
{
|
||||
response_sent++;
|
||||
Serial.print(response_sent);
|
||||
Serial.print(" Response sent");
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.print("Slave error,");
|
||||
Serial.print(",Irq,");
|
||||
Serial.print(IrqStatus, HEX);
|
||||
LT.printIrqStatus();
|
||||
}
|
||||
digitalWrite(LED1, LOW);
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void led_Flash(unsigned int flashes, unsigned int delaymS)
|
||||
{
|
||||
//flash LED to show board is alive
|
||||
unsigned int index;
|
||||
|
||||
for (index = 1; index <= flashes; index++)
|
||||
{
|
||||
digitalWrite(LED1, HIGH);
|
||||
delay(delaymS);
|
||||
digitalWrite(LED1, LOW);
|
||||
delay(delaymS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(9600); //setup Serial console ouput
|
||||
Serial.println();
|
||||
Serial.println(__FILE__);
|
||||
Serial.print(F("Compiled "));
|
||||
Serial.print(__TIME__);
|
||||
Serial.print(F(" "));
|
||||
Serial.println(__DATE__);
|
||||
Serial.println(F(programversion));
|
||||
Serial.println(F("Stuart Robinson"));
|
||||
Serial.println();
|
||||
|
||||
Serial.println("55_Ranging_Slave Starting");
|
||||
|
||||
pinMode(LED1, OUTPUT);
|
||||
led_Flash(2, 125);
|
||||
|
||||
SPI.begin();
|
||||
|
||||
if (LT.begin(NSS, NRESET, RFBUSY, DIO1, LORA_DEVICE))
|
||||
{
|
||||
Serial.println(F("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
|
||||
}
|
||||
}
|
||||
|
||||
//The function call list below shows the complete setup for the LoRa device for ranging using the information
|
||||
//defined in the Settings.h file.
|
||||
//The 'Setup LoRa device for Ranging' list below can be replaced with a single function call, note that
|
||||
//the calibration value will be loaded automatically from the table in the library;
|
||||
//LT.setupRanging(Frequency, Offset, SpreadingFactor, Bandwidth, CodeRate, RangingAddress, RangingRole);
|
||||
|
||||
LT.setupRanging(Frequency, Offset, SpreadingFactor, Bandwidth, CodeRate, RangingAddress, RANGING_SLAVE);
|
||||
|
||||
//***************************************************************************************************
|
||||
//Setup LoRa device for Ranging Slave
|
||||
//***************************************************************************************************
|
||||
LT.setMode(MODE_STDBY_RC);
|
||||
LT.setPacketType(PACKET_TYPE_RANGING);
|
||||
LT.setModulationParams(SpreadingFactor, Bandwidth, CodeRate);
|
||||
LT.setPacketParams(12, LORA_PACKET_VARIABLE_LENGTH, 0, LORA_CRC_ON, LORA_IQ_NORMAL, 0, 0);
|
||||
LT.setRfFrequency(Frequency, Offset);
|
||||
LT.setTxParams(TXpower, RADIO_RAMP_02_US);
|
||||
LT.setRangingMasterAddress(RangingAddress);
|
||||
LT.setRangingSlaveAddress(RangingAddress);
|
||||
LT.setRangingCalibration(LT.lookupCalibrationValue(SpreadingFactor, Bandwidth));
|
||||
LT.setRangingRole(RANGING_SLAVE);
|
||||
LT.writeRegister(REG_RANGING_FILTER_WINDOW_SIZE, 8); //set up window size for ranging averaging
|
||||
LT.setHighSensitivity();
|
||||
//***************************************************************************************************
|
||||
|
||||
LT.setRangingCalibration(11300); //override automatic lookup of calibration value from library table
|
||||
|
||||
Serial.print(F("Calibration,"));
|
||||
Serial.println(LT.getSetCalibrationValue()); //reads the calibratuion value currently set
|
||||
delay(2000);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/*****************************************************************************************************
|
||||
Programs for Arduino - Copyright of the author Stuart Robinson - 16/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. Some pins such as DIO2,
|
||||
//DIO3, BUZZER may not be in used by this sketch so they do not need to be
|
||||
//connected and should be included and be set to -1.
|
||||
|
||||
|
||||
#define NSS 10
|
||||
#define RFBUSY 7
|
||||
#define NRESET 9
|
||||
#define LED1 8
|
||||
#define DIO1 3
|
||||
|
||||
#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 in hz
|
||||
const int32_t Offset = 0; //offset frequency in hz for calibration purposes
|
||||
const uint8_t Bandwidth = LORA_BW_0800; //LoRa bandwidth
|
||||
const uint8_t SpreadingFactor = LORA_SF8; //LoRa spreading factor
|
||||
const uint8_t CodeRate = LORA_CR_4_5; //LoRa coding rate
|
||||
const uint16_t Calibration = 11350; //Manual Ranging calibrarion value
|
||||
|
||||
const uint8_t TXpower = 10; //Transmit power used
|
||||
const uint32_t RangingAddress = 16; //must match address in recever
|
||||
|
||||
const uint16_t rangingRXTimeoutmS = 0xFFFF; //ranging RX timeout in mS
|
||||
|
||||
@@ -0,0 +1,204 @@
|
||||
/*****************************************************************************************************
|
||||
Programs for Arduino - Copyright of the author Stuart Robinson - 17/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.
|
||||
*******************************************************************************************************/
|
||||
|
||||
#define programversion "V1.1"
|
||||
#define Serial_Monitor_Baud 9600
|
||||
|
||||
#include <SPI.h>
|
||||
#include <SX128XLT.h>
|
||||
SX128XLT LT;
|
||||
#include "Settings.h"
|
||||
|
||||
uint8_t distance_zero_count;
|
||||
uint16_t calvalue, calibrationstart, calibrationend;
|
||||
uint16_t rangeing_error_count, rangeing_valid_count;
|
||||
uint16_t IrqStatus;
|
||||
uint32_t endwaitmS, startrangingmS, range_result;
|
||||
float distance;
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
uint16_t index;
|
||||
distance_zero_count = 0;
|
||||
|
||||
for (index = calibrationstart; index <= calibrationend; index = index + 10)
|
||||
{
|
||||
digitalWrite(LED1, HIGH);
|
||||
LT.setRangingCalibration(index);
|
||||
Serial.print(F("TransmitRanging,Calibration,"));
|
||||
Serial.print(index);
|
||||
LT.transmitRanging(RangingAddress, TXtimeoutmS, TXpower, NO_WAIT);
|
||||
digitalWrite(LED1, LOW);
|
||||
|
||||
endwaitmS = millis() + waittimemS;
|
||||
startrangingmS = millis();
|
||||
|
||||
while (!(digitalRead(DIO1)) && (millis() < endwaitmS)); //wait for Ranging valid or timeout
|
||||
|
||||
delay(10);
|
||||
|
||||
IrqStatus = LT.readIrqStatus();
|
||||
Serial.print(F(",IRQ,"));
|
||||
Serial.print(IrqStatus, HEX);
|
||||
|
||||
if (IrqStatus & IRQ_RANGING_MASTER_RESULT_TIMEOUT)
|
||||
{
|
||||
rangeing_error_count++;
|
||||
Serial.print(F(", RangingTimeout! "));
|
||||
}
|
||||
|
||||
if (millis() > endwaitmS)
|
||||
{
|
||||
Serial.print(F(",ProgramTimeout"));
|
||||
}
|
||||
|
||||
if (IrqStatus & IRQ_RANGING_MASTER_RESULT_VALID)
|
||||
{
|
||||
rangeing_valid_count++;
|
||||
digitalWrite(LED1, HIGH);
|
||||
Serial.print(F(",Valid"));
|
||||
range_result = LT.getRangingResultRegValue(RANGING_RESULT_RAW);
|
||||
Serial.print(F(",RAW,"));
|
||||
Serial.print(range_result, HEX);
|
||||
|
||||
distance = LT.getRangingDistance(RANGING_RESULT_RAW, range_result, 1);
|
||||
|
||||
Serial.print(F(",Distance,"));
|
||||
Serial.print(distance, 1);
|
||||
Serial.print(F("m"));
|
||||
Serial.print(F(",Time,"));
|
||||
Serial.print(millis() - startrangingmS);
|
||||
Serial.print("mS");
|
||||
digitalWrite(LED1, LOW);
|
||||
}
|
||||
|
||||
Serial.print(F(",OKCount,"));
|
||||
Serial.print(rangeing_valid_count);
|
||||
Serial.print(F(",ErrorCount,"));
|
||||
Serial.print(rangeing_error_count);
|
||||
|
||||
if (distance == 0)
|
||||
{
|
||||
Serial.print(F(", Distance is Zero!"));
|
||||
distance_zero_count++;
|
||||
}
|
||||
|
||||
if (distance_zero_count >= 3)
|
||||
{
|
||||
delay(5000);
|
||||
break;
|
||||
}
|
||||
|
||||
Serial.println();
|
||||
delay(packet_delaymS);
|
||||
|
||||
}
|
||||
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
|
||||
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 setup()
|
||||
{
|
||||
uint16_t Remainder;
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
Serial.begin(Serial_Monitor_Baud); //setup Serial console ouput
|
||||
Serial.println();
|
||||
Serial.println(__FILE__);
|
||||
Serial.print(F("Compiled "));
|
||||
Serial.print(__TIME__);
|
||||
Serial.print(F(" "));
|
||||
Serial.println(__DATE__);
|
||||
Serial.println(F(programversion));
|
||||
Serial.println(F("Stuart Robinson"));
|
||||
Serial.println();
|
||||
|
||||
Serial.println(F("56_Ranging_Calibration_Checker Starting"));
|
||||
|
||||
pinMode(LED1, OUTPUT);
|
||||
|
||||
led_Flash(2, 125);
|
||||
|
||||
Serial.println(F("Checking device"));
|
||||
|
||||
SPI.begin();
|
||||
|
||||
if (LT.begin(NSS, NRESET, RFBUSY, DIO1, DIO2, DIO3, RX_EN, TX_EN, LORA_DEVICE))
|
||||
{
|
||||
Serial.println(F("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
|
||||
}
|
||||
}
|
||||
|
||||
//The function call list below shows the complete setup for the LoRa device for ranging using the information
|
||||
//defined in the Settings.h file.
|
||||
//The 'Setup LoRa device for Ranging' list below can be replaced with a single function call, note that
|
||||
//the calibration value will be loaded automatically from the table in the library;
|
||||
|
||||
//LT.setupRanging(Frequency, Offset, SpreadingFactor, Bandwidth, CodeRate, RangingAddress, RangingRole);
|
||||
|
||||
//***************************************************************************************************
|
||||
//Setup LoRa device for Ranging Master
|
||||
//***************************************************************************************************
|
||||
LT.setMode(MODE_STDBY_RC);
|
||||
LT.setPacketType(PACKET_TYPE_RANGING);
|
||||
LT.setModulationParams(SpreadingFactor, Bandwidth, CodeRate);
|
||||
LT.setPacketParams(12, LORA_PACKET_VARIABLE_LENGTH, 0, LORA_CRC_ON, LORA_IQ_NORMAL, 0, 0);
|
||||
LT.setRfFrequency(Frequency, Offset);
|
||||
LT.setTxParams(TXpower, RADIO_RAMP_02_US);
|
||||
LT.setRangingMasterAddress(RangingAddress);
|
||||
LT.setRangingSlaveAddress(RangingAddress);
|
||||
LT.setDioIrqParams(IRQ_RADIO_ALL, (IRQ_TX_DONE + IRQ_RANGING_MASTER_RESULT_VALID + IRQ_RANGING_MASTER_RESULT_TIMEOUT), 0, 0); //set for IRQ on RX done
|
||||
LT.setRangingCalibration(LT.lookupCalibrationValue(SpreadingFactor, Bandwidth));
|
||||
LT.setRangingRole(RANGING_MASTER);
|
||||
LT.writeRegister(REG_RANGING_FILTER_WINDOW_SIZE, 8); //set up window size for ranging averaging
|
||||
LT.setHighSensitivity();
|
||||
//***************************************************************************************************
|
||||
|
||||
//LT.setRangingCalibration(Calibration); //override automatic lookup of calibration value from library table
|
||||
|
||||
calvalue = LT.getSetCalibrationValue();
|
||||
Remainder = calvalue / 10;
|
||||
calibrationstart = (Remainder * 10) - 1000;
|
||||
calibrationend = (Remainder * 10) + 1000;
|
||||
Serial.print(F("CalibrationStart,"));
|
||||
Serial.print(calibrationstart);
|
||||
Serial.print(F(",CalibrationEnd,"));
|
||||
Serial.println(calibrationend);
|
||||
Serial.println();
|
||||
|
||||
delay(2000);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
/*****************************************************************************************************
|
||||
Programs for Arduino - Copyright of the author Stuart Robinson - 17/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. Some pins such as DIO2,
|
||||
//DIO3, BUZZER may not be in used by this sketch so they do not need to be
|
||||
//connected and should be included and be set to -1.
|
||||
|
||||
|
||||
#define NSS 10
|
||||
#define RFBUSY 7
|
||||
#define NRESET 9
|
||||
#define LED1 8
|
||||
#define DIO1 3
|
||||
#define DIO2 -1 //not used
|
||||
#define DIO3 -1 //not used
|
||||
|
||||
#define RX_EN -1 //pin for RX enable, used on some SX1280 devices, set to -1 if not used
|
||||
#define TX_EN -1 //pin for TX enable, used on some SX1280 devices, set to -1 if not used
|
||||
|
||||
#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 in hz
|
||||
const int32_t Offset = 0; //offset frequency in hz for calibration purposes
|
||||
const uint8_t Bandwidth = LORA_BW_0800; //LoRa bandwidth
|
||||
const uint8_t SpreadingFactor = LORA_SF8; //LoRa spreading factor
|
||||
const uint8_t CodeRate = LORA_CR_4_5; //LoRa coding rate
|
||||
const uint16_t Calibration = 11426; //Manual Ranging calibrarion value
|
||||
|
||||
const uint8_t RangingRole = RANGING_SLAVE; //Ranging role, RANGING_MASTER or RANGING_SLAVE
|
||||
const uint8_t TXpower = 10; //Transmit power used
|
||||
const uint32_t RangingAddress = 16; //must match address in recever
|
||||
|
||||
const uint16_t waittimemS = 10000; //wait this long in mS for packet before assuming timeout
|
||||
const uint16_t TXtimeoutmS = 5000; //ranging TX timeout in mS
|
||||
const uint16_t RXtimeoutmS = 0xFFFF; //ranging RX timeout in mS
|
||||
const uint16_t packet_delaymS = 250; //forced extra delay in mS between ranging requests
|
||||
const uint16_t rangeingcount = 5; //number of times ranging is cqarried out for each distance measurment
|
||||
float distance_adjustment = 1; //adjustment factor to calculated distance
|
||||
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 222 KiB |
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 18 KiB |
113
lib/SX12XX-LoRa/examples/SX128x_examples/Ranging/ReadMe.md
Normal file
@@ -0,0 +1,113 @@
|
||||
## Ranging Calibration
|
||||
|
||||
**Note:** The ranging feature of the SX128X is not supported if the module uses external RX and TX switching.
|
||||
|
||||
To measure a distance the master device transmits a ranging request which a slave receives and then sends a response, if the request was for that particular slave. The master receives the slaves response and knows by use of a timer how long the master slave response exchange took.
|
||||
|
||||
The total time for the master slave exchange includes a fixed processing time for the master and slave to transmit and receive the appropriate packets. This fixed time should be static and should be the same no matter how far apart the master initiator and slave receiver are.
|
||||
|
||||
This fixed time then needs to be subtracted from the total round trip time. The remainder of the time is then proportional to the distance in a linear way.
|
||||
|
||||
Thus the ranging function needs a calibration value (the fixed time mentioned above) which changes according to the bandwidth and spreading factor used. Bandwidths of 400khz, 800khz and 1600khz are supported for ranging. The calibration value can also vary slightly between different modules or antennas used. So for the best results its suggested to calibrate a pair of modules together. The SX128XLT library does, by default, do a lookup from a pre-determined range of calibration values.
|
||||
|
||||
Its been noticed in testing that variations in distance measurements of +\-10m are not unusual and this is typically the sort of adjustment that calibration might correct for. If your using the SX128x to measure long distances, into several kilometres, then the standard values provided by the library are probably accurate enough, a variation of 10m over 4km is hardly significant.
|
||||
|
||||
There is a calibration method described in a Semtech document;
|
||||
|
||||
[Introduction to Ranging](https://semtech.my.salesforce.com/sfc/p/#E0000000JelG/a/44000000MDiH/OF02Lve2RzM6pUw9gNgSJXbDNaQJ_NtQ555rLzY3UvY)
|
||||
|
||||
My own approach to the ranging calibration has been simplified. The starting base for the calibration numbers was this table produced by Semtech;
|
||||
|
||||

|
||||
|
||||
After running some checks on my own set-ups, I came up with the following set of values, and the ranging programs pick up these numbers by default, you can of course use your own.
|
||||
|
||||

|
||||
|
||||
|
||||
To check the the calibration values from the library a ranging slave was programmed with the **'55\_Ranging\_Slave'** program. Normally the ranging example programs automatically lookup the calibration value from a table in the file 'SX128XLT_Definitions.h'. However the value can be manually configured using the command;
|
||||
|
||||
setRangingCalibration(Calibration);
|
||||
|
||||
where Calibration is the value to use, normally in the range of 10,000 to 13,500.
|
||||
|
||||
Lets follow and example of testing the calibration of the modules for ranging at spreading factor 8, bandwidth 800khz. From the initial table shown above, the calibration value is around 11350. Set the appropriate LoRa settings in the 'Settings.h' file for the slave and ranging calibration programs to;
|
||||
|
||||
const uint8_t Bandwidth = LORA_BW_0800; //LoRa bandwidth
|
||||
const uint8_t SpreadingFactor = LORA_SF8; //LoRa spreading factor
|
||||
const uint8_t CodeRate = LORA_CR_4_5; //LoRa coding rate
|
||||
|
||||
|
||||
Program the slave device and at start-up the serial monitor should show;
|
||||
|
||||
55_Ranging_Slave Starting
|
||||
Device found
|
||||
Calibration,11350
|
||||
RangingListen,
|
||||
|
||||
The example program **'56\_Ranging\_Calibration\_Checker'** varies the calibration value for each master ranging measurement starting at a value 1000 less than the calibration value provided and changing it in steps to a value that is 1000 more than the mid value. At each change of calibration value the distance is measured and sent to the serial monitor. When the distance goes to zero 3 times in a row the process stops. You can then see on the serial monitor which calibration value gives close to a 0m reading.
|
||||
|
||||
When the ranging calibration program starts you should see this;
|
||||
|
||||
56_Ranging_Calibration_Checker Starting
|
||||
Checking device
|
||||
Device found
|
||||
CalibrationStart,10350,CalibrationEnd,12350
|
||||
|
||||
After a while the program reported this;
|
||||
TransmitRanging,Calibration,11220,IRQ,200,Valid,RAW,47,Distance,3.2m,Time,33mS,OKCount,88,ErrorCount,0
|
||||
TransmitRanging,Calibration,11230,IRQ,200,Valid,RAW,1F,Distance,1.4m,Time,31mS,OKCount,89,ErrorCount,0
|
||||
TransmitRanging,Calibration,11240,IRQ,200,Valid,RAW,19,Distance,1.1m,Time,31mS,OKCount,90,ErrorCount,0
|
||||
TransmitRanging,Calibration,11250,IRQ,200,Valid,RAW,36,Distance,2.4m,Time,30mS,OKCount,91,ErrorCount,0
|
||||
TransmitRanging,Calibration,11260,IRQ,200,Valid,RAW,FFFFFF,Distance,0.0m,Time,31mS,OKCount,92,ErrorCount,0, Distance is Zero!
|
||||
TransmitRanging,Calibration,11270,IRQ,200,Valid,RAW,2B,Distance,1.9m,Time,33mS,OKCount,93,ErrorCount,0
|
||||
TransmitRanging,Calibration,11280,IRQ,200,Valid,RAW,1D,Distance,1.3m,Time,30mS,OKCount,94,ErrorCount,0
|
||||
TransmitRanging,Calibration,11290,IRQ,200,Valid,RAW,0,Distance,0.0m,Time,31mS,OKCount,95,ErrorCount,0, Distance is Zero!
|
||||
TransmitRanging,Calibration,11300,IRQ,200,Valid,RAW,FFFFD7,Distance,0.0m,Time,33mS,OKCount,96,ErrorCount,0, Distance is Zero!
|
||||
|
||||
|
||||
So with the slave using an initial calibration value of 11350 the master got to around 0m at a calibration value of 11300. Lets re-program the slave with a calibration value of 11300. To override the automatic lookup of the calibration value from the table in SX128XLT_Definitions.h ensure this command is enabled in setup() function after the main sequence functions calls configuring the SX128X device;
|
||||
|
||||
**LT.setRangingCalibration(11300); //override automatic lookup of calibration value from library table**
|
||||
|
||||
|
||||
The ranging calibration program then produced these results;
|
||||
|
||||
TransmitRanging,Calibration,11300,IRQ,400, RangingTimeout! ,OKCount,94,ErrorCount,2
|
||||
TransmitRanging,Calibration,11310,IRQ,200,Valid,RAW,73,Distance,5.2m,Time,31mS,OKCount,95,ErrorCount,2
|
||||
TransmitRanging,Calibration,11320,IRQ,200,Valid,RAW,59,Distance,4.0m,Time,31mS,OKCount,96,ErrorCount,2
|
||||
TransmitRanging,Calibration,11330,IRQ,200,Valid,RAW,FFFF46,Distance,0.0m,Time,30mS,OKCount,97,ErrorCount,2, Distance is Zero!
|
||||
TransmitRanging,Calibration,11340,IRQ,200,Valid,RAW,FFFFD0,Distance,0.0m,Time,33mS,OKCount,98,ErrorCount,2, Distance is Zero!
|
||||
TransmitRanging,Calibration,11350,IRQ,200,Valid,RAW,FFFFCB,Distance,0.0m,Time,33mS,OKCount,99,ErrorCount,2, Distance is Zero!
|
||||
|
||||
|
||||
So a calibration value of maybe 11320 seems about right. This value can then be used to manually configure a particular set-up.
|
||||
|
||||
The example program **54_Ranging_Master** can then be programmed with the same calibration value just determined. This program will carry out 5 ranging attempts and average the results to a distance shown on the serial monitor. This program will also drive a SSD1306 OLED for use as a portable distance measuring device.
|
||||
|
||||
The master ranging programs calculates the distance and then adjusts the measured value with this setting in the Settings.h file;
|
||||
|
||||
**const float distance_adjustment = 1.0; //adjustment to calculated distance**
|
||||
|
||||
The adjustment value need to be determined by using the ranging programs to measure the distance over a long known path. I used a location when the master has line of sight over a long path, 4.405km in this case. This distance measurement was obtained from the 1:25000 Ordnance Survey map.
|
||||
|
||||
Over this long path the average distance reported by the SX1280 4.424km, so the adjustment factor is 4.405/4.424 = 0.99571
|
||||
|
||||
|
||||
### Variances at short distances.
|
||||
|
||||
Regardless of the derived calibration value the conversion of the time of flight result from the values reported in the SX1280 registers to distance is a linear one, so any variation in register value over a fixed distance will represent a distance variation. Whilst you can average results the distance variations will be down to the limitations of the internal timing measurements that the SX128x takes.
|
||||
|
||||
I set-up a outdoor test in a large open areas, my local playing field. The slave was placed on a pole about 1.8M off the ground and I stood with the master hand-held, away from my body, at 100m distance. The calibration and adjustment values were determined as mentioned above, so the master ought to be recoding a distance of 100m. The results of around 140 ranging measurements are below;
|
||||
|
||||
|
||||

|
||||
|
||||
You can see a variation in distance of +\- 10m at 100m distance is not unusual. Apart from long term averaging its difficult to see what can be done to reduce these variances.
|
||||
|
||||
It has also been noted that where there is a possibility of reflections such as in urban areas, larger variances than this have been seen particularly if the antenna orientations are moving or otherwise changed.
|
||||
|
||||
|
||||
|
||||
### Stuart Robinson
|
||||
### March 2020
|
||||
88
lib/SX12XX-LoRa/examples/SX128x_examples/ReadMe.md
Normal file
@@ -0,0 +1,88 @@
|
||||
# SX128X Library
|
||||
<cr>
|
||||
|
||||
|
||||
This part of the SX12XX library supports the SX1280 and SX1281 2.4Ghz LoRa modules.
|
||||
|
||||
The objective of the SX12XX library is to allow the same program sketches to be used across the range of UHF LoRa modules SX126x and SX127x (UHF) as well as the 2.4Ghz SX128x modules.
|
||||
|
||||
|
||||
###SX128X Considerations for pin usage
|
||||
|
||||
There is a range of SX128X modules available and they have slightly different pins usage.
|
||||
|
||||
The library only supports the SPI based LoRa modules and these all require that the SPI bus pins, SCK, MOSI and MISO are connected. All modules also need a NSS (chip select pin) and NRESET (reset) pin. All devices need the RFBUSY pin to be used also.
|
||||
|
||||
The basic SX1280 modules from NiceRF and Ebyte were used to test the examples in this library. There may be newer devices out there that have additional features, such as TCXOs, that may require different set-ups or pin usage.
|
||||
|
||||
Of the LoRa devices DIO pins the SX128X library in standard form only uses DIO1. Some SX128x modules have RX and TX enable pins that need to be appropriately activated when receiving or transmitting.
|
||||
|
||||
Thus a begin function that initialised all possible permutations of pins would look like this;
|
||||
|
||||
begin(NSS, NRESET, RFBUSY, DIO1, DIO2, DIO3, RX\_EN, TX\_EN, LORA\_DEVICE);
|
||||
|
||||
Clearly the above begin statement is somewhat cumbersome and could potentially be shortened for the NiceRF SX128X devices to;
|
||||
|
||||
begin(NSS, NRESET, RFBUSY, DIO1, LORA\_DEVICE);
|
||||
|
||||
And shortened for the Ebyte devices to;
|
||||
|
||||
begin(NSS, NRESET, RFBUSY, DIO1, RX\_EN, TX\_EN, LORA\_DEVICE);
|
||||
|
||||
Which is a lot more manageable.
|
||||
|
||||
You can use the shorter formats of the begin commands can be used in your own programs if you have the appropriate module, NiceRF or Ebyte.
|
||||
|
||||
The full format of begin, see above, is still valid and is used in most of the example programs. If you have written your own programs using the earlier library these programs do not need changing. You could not have used the newer constructs of the begin command (to support the newer devices) in your programs since the newer constructs did not exist in the older version library.
|
||||
|
||||
Valid values for LORA_DEVICE are DEVICE_SX1280 and DEVICE_SX1281.
|
||||
|
||||
Accepted its all a bit confusing, but regrettably module manufacturers have different ideas about design.
|
||||
|
||||
# SX128X Library - LoRa Settings
|
||||
|
||||
In the setModulationParams() function the Spreading factor, Bandwidth, CodeRate LoRa parameters can be set;
|
||||
|
||||
//LoRa Spreading factors
|
||||
LORA_SF5
|
||||
LORA_SF6
|
||||
LORA_SF7
|
||||
LORA_SF8
|
||||
LORA_SF9
|
||||
LORA_SF10
|
||||
LORA_SF11
|
||||
LORA_SF12
|
||||
|
||||
//LoRa Bandwidths
|
||||
LORA_BW_0200 //actually 203125hz
|
||||
LORA_BW_0400 //actually 406250hz
|
||||
LORA_BW_0800 //actually 812500hz
|
||||
LORA_BW_1600 //actually 1625000hz
|
||||
|
||||
//LoRa Coding rates
|
||||
LORA_CR_4_5
|
||||
LORA_CR_4_6
|
||||
LORA_CR_4_7
|
||||
LORA_CR_4_8
|
||||
|
||||
|
||||
The device types for the SX128X part of the library are;
|
||||
|
||||
DEVICE_SX1280
|
||||
DEVICE_SX1281
|
||||
|
||||
In the transmit() function the TXpower can be set from -18dBm to +12dBm.
|
||||
|
||||
In the setPacketType() function valid packet type are;
|
||||
|
||||
PACKET_TYPE_LORA
|
||||
PACKET_TYPE_FLRC
|
||||
PACKET_TYPE_RANGING
|
||||
PACKET_TYPE_BLE (not implemented)
|
||||
PACKET_TYPE_NONE
|
||||
|
||||
|
||||
### Stuart Robinson
|
||||
|
||||
### April 2020
|
||||
|
||||
@@ -0,0 +1,307 @@
|
||||
/*******************************************************************************************************
|
||||
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 is a remote control transmitter. When one of four switches are made
|
||||
(shorted to ground) a packet is transmitted with single byte indicating the state of Switch0 as bit 0,
|
||||
Switch1 as bit 1 and Switch2 as bit 2. To prevent false triggering at the receiver the packet contains a
|
||||
32 bit number called the TXIdentity which in this example is set to 1234554321. The receiver will only
|
||||
act on, change the state of the outputs, if the identity set in the receiver matches that of the
|
||||
transmitter. The chance of a false trigger is fairly remote.
|
||||
|
||||
Between switch presses the LoRa device and Atmel microcontroller are put to sleep. A switch press wakes
|
||||
up the processor from sleep, the switches are read and a packet sent. On a 'bare bones' Arduino setup
|
||||
the transmitter has a sleep current of approx 2.2uA, so it's ideal for a battery powered remote control
|
||||
with a potential range of many kilometres.
|
||||
|
||||
The pin definitions, LoRa frequency and LoRa modem settings are in the Settings.h file. These settings
|
||||
are not necessarily optimised for long range.
|
||||
|
||||
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, integral to Arduino IDE
|
||||
#include <avr/sleep.h> //watchdog timer library, integral to Arduino IDE
|
||||
#include "PinChangeInterrupt.h" //get the library here; https://github.com/NicoHood/PinChangeInterrupt
|
||||
|
||||
SX128XLT LT;
|
||||
|
||||
uint32_t TXpacketCount;
|
||||
uint8_t TXPacketL;
|
||||
|
||||
volatile bool switch0flag = false;
|
||||
volatile bool switch1flag = false;
|
||||
volatile bool switch2flag = false;
|
||||
volatile bool switch3flag = false;
|
||||
|
||||
void loop()
|
||||
{
|
||||
uint8_t switches;
|
||||
|
||||
digitalWrite(LED1, LOW); //turn off indicator LED
|
||||
Serial.print(F("Sleeping zzzz"));
|
||||
Serial.flush(); //make sure all serial output has gone
|
||||
|
||||
LT.setSleep(CONFIGURATION_RETENTION); //sleep LoRa device, keeping register settings in sleep.
|
||||
sleep_permanent(); //sleep Atmel processor permanently for switch wakeup only
|
||||
LT.wake(); //wake up the lora device - nicely
|
||||
|
||||
digitalWrite(LED1, HIGH);
|
||||
|
||||
Serial.println(F(" - Awake !!")); //the processor has woken up
|
||||
switches = readSwitches(); //read the state of the switches
|
||||
|
||||
TXpacketCount++;
|
||||
Serial.print(TXpacketCount); //print the numbers of sends
|
||||
Serial.print(F(" Sending > "));
|
||||
|
||||
Serial.print(switches, BIN);
|
||||
|
||||
if (sendSwitchPacket(switches))
|
||||
{
|
||||
Serial.println(F(" SentOK"));
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.print(F("Send Error - IRQreg,"));
|
||||
Serial.print(LT.readIrqStatus(), HEX);
|
||||
}
|
||||
|
||||
Serial.println();
|
||||
delay(500);
|
||||
}
|
||||
|
||||
|
||||
uint8_t sendSwitchPacket(uint8_t switches)
|
||||
{
|
||||
//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(RControl1); //this byte identifies the type of packet
|
||||
LT.writeUint32(TXIdentity); //this 32bit integer defines the Identity of the transmiter
|
||||
LT.writeUint8(switches); //this byte contains the 8 switch values to be sent
|
||||
len = LT.endWriteSXBuffer(); //close the packet, get the length of data to be sent
|
||||
|
||||
//now transmit the packet, 10 second timeout, and wait for it to complete sending
|
||||
TXPacketL = LT.transmitSXBuffer(0, len, 10000, TXpower, WAIT_TX);
|
||||
|
||||
return TXPacketL; //TXPacketL will be 0 if there was an error sending
|
||||
}
|
||||
|
||||
|
||||
void sleep_permanent()
|
||||
{
|
||||
attachInterrupts();
|
||||
|
||||
ADCSRA = 0; //disable ADC
|
||||
set_sleep_mode (SLEEP_MODE_PWR_DOWN);
|
||||
noInterrupts (); //timed sequence follows
|
||||
sleep_enable();
|
||||
|
||||
// turn off brown-out enable in software
|
||||
MCUCR = bit (BODS) | bit (BODSE); //turn on brown-out enable select
|
||||
MCUCR = bit (BODS); //this must be done within 4 clock cycles of above
|
||||
interrupts (); //guarantees next instruction executed
|
||||
|
||||
sleep_cpu (); //sleep within 3 clock cycles of above
|
||||
|
||||
/* wake up here */
|
||||
|
||||
sleep_disable();
|
||||
|
||||
detachInterrupts();
|
||||
}
|
||||
|
||||
|
||||
void attachInterrupts()
|
||||
{
|
||||
if (SWITCH0 >= 0)
|
||||
{
|
||||
attachPCINT(digitalPinToPCINT(SWITCH0), wake0, FALLING);
|
||||
switch0flag = false;
|
||||
}
|
||||
|
||||
if (SWITCH1 >= 0)
|
||||
{
|
||||
attachPCINT(digitalPinToPCINT(SWITCH1), wake1, FALLING);
|
||||
switch1flag = false;
|
||||
}
|
||||
|
||||
if (SWITCH2 >= 0)
|
||||
{
|
||||
attachPCINT(digitalPinToPCINT(SWITCH2), wake2, FALLING);
|
||||
switch2flag = false;
|
||||
}
|
||||
|
||||
if (SWITCH3 >= 0)
|
||||
{
|
||||
attachPCINT(digitalPinToPCINT(SWITCH3), wake3, FALLING);
|
||||
switch3flag = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void detachInterrupts()
|
||||
{
|
||||
if (SWITCH0 >= 0)
|
||||
{
|
||||
detachPCINT(digitalPinToPCINT(SWITCH0));
|
||||
}
|
||||
|
||||
if (SWITCH1 >= 0)
|
||||
{
|
||||
detachPCINT(digitalPinToPCINT(SWITCH1));
|
||||
}
|
||||
|
||||
if (SWITCH2 >= 0)
|
||||
{
|
||||
detachPCINT(digitalPinToPCINT(SWITCH2));
|
||||
}
|
||||
|
||||
if (SWITCH3 >= 0)
|
||||
{
|
||||
detachPCINT(digitalPinToPCINT(SWITCH3));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void wake0()
|
||||
{
|
||||
switch0flag = true;
|
||||
}
|
||||
|
||||
|
||||
void wake1()
|
||||
{
|
||||
switch1flag = true;
|
||||
}
|
||||
|
||||
|
||||
void wake2()
|
||||
{
|
||||
switch2flag = true;
|
||||
}
|
||||
|
||||
|
||||
void wake3()
|
||||
{
|
||||
switch3flag = true;
|
||||
}
|
||||
|
||||
|
||||
uint8_t readSwitches()
|
||||
{
|
||||
uint8_t switchByte = 0xFF; //start assuming all switches off
|
||||
|
||||
if (switch0flag)
|
||||
{
|
||||
bitClear(switchByte, 0); //if the flag is set clear the bit
|
||||
Serial.println(F("SWITCH0 pressed"));
|
||||
}
|
||||
|
||||
if (switch1flag)
|
||||
{
|
||||
bitClear(switchByte, 1); //if the flag is set clear the bit
|
||||
Serial.println(F("SWITCH1 pressed"));
|
||||
}
|
||||
|
||||
if (switch2flag)
|
||||
{
|
||||
bitClear(switchByte, 2); //if the flag is set clear the bit
|
||||
Serial.println(F("SWITCH2 pressed"));
|
||||
}
|
||||
|
||||
|
||||
if (switch3flag)
|
||||
{
|
||||
bitClear(switchByte, 3); //if the flag is set clear the bit
|
||||
Serial.println(F("SWITCH3 pressed"));
|
||||
}
|
||||
|
||||
return switchByte;
|
||||
}
|
||||
|
||||
|
||||
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 setupSwitches()
|
||||
{
|
||||
if (SWITCH0 >= 0)
|
||||
{
|
||||
pinMode(SWITCH0, INPUT_PULLUP);
|
||||
}
|
||||
|
||||
if (SWITCH1 >= 0)
|
||||
{
|
||||
pinMode(SWITCH1, INPUT_PULLUP);
|
||||
}
|
||||
|
||||
if (SWITCH2 >= 0)
|
||||
{
|
||||
pinMode(SWITCH2, INPUT_PULLUP);
|
||||
}
|
||||
|
||||
if (SWITCH3 >= 0)
|
||||
{
|
||||
pinMode(SWITCH3, INPUT_PULLUP);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
pinMode(LED1, OUTPUT);
|
||||
led_Flash(2, 125);
|
||||
|
||||
setupSwitches();
|
||||
|
||||
Serial.begin(9600);
|
||||
|
||||
SPI.begin();
|
||||
|
||||
if (LT.begin(NSS, NRESET, RFBUSY, DIO1, DIO2, DIO3, RX_EN, TX_EN, 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);
|
||||
|
||||
Serial.println(F("Transmitter ready"));
|
||||
Serial.println();
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
/*******************************************************************************************************
|
||||
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 definitiosn to match your own setup. Some pins such as DIO2,
|
||||
//DIO3, may not be in used by this sketch so they do not need to be connected and
|
||||
//should be set to -1.
|
||||
|
||||
const int8_t NSS = 10; //select on LoRa device
|
||||
const int8_t NRESET = 9; //reset on LoRa device
|
||||
const int8_t RFBUSY = 7; //RF busy on LoRa device
|
||||
const int8_t DIO1 = 3; //DIO1 on LoRa device, used for RX and TX done
|
||||
const int8_t DIO2 = -1; //DIO2 on LoRa device, normally not used so set to -1
|
||||
const int8_t DIO3 = -1; //DIO3 on LoRa device, normally not used so set to -1
|
||||
const int8_t LED1 = 8; //On board LED, logic high is on
|
||||
const int8_t RX_EN = -1; //pin for RX enable, used on some SX1280 devices, set to -1 if not used
|
||||
const int8_t TX_EN = -1; //pin for TX enable, used on some SX1280 devices, set to -1 if not used
|
||||
|
||||
|
||||
#define LORA_DEVICE DEVICE_SX1280 //this is the device we are using
|
||||
|
||||
const int8_t SWITCH0 = 2;
|
||||
const int8_t SWITCH1 = 4;
|
||||
const int8_t SWITCH2 = A3;
|
||||
const int8_t SWITCH3 = A2;
|
||||
|
||||
const uint32_t TXIdentity = 1234554321; //define an identity number, the receiver must use the same number
|
||||
//range is 0 to 4294967296
|
||||
|
||||
|
||||
|
||||
//******* Setup LoRa Test Parameters Here ! ***************
|
||||
|
||||
//LoRa Modem Parameters
|
||||
#define Frequency 2445000000 //frequency of transmissions
|
||||
#define Offset 0 //offset frequency for calibration purposes
|
||||
#define Bandwidth LORA_BW_0400 //LoRa bandwidth
|
||||
#define SpreadingFactor LORA_SF7 //LoRa spreading factor
|
||||
#define CodeRate LORA_CR_4_5 //LoRa coding rate
|
||||
|
||||
#define TXpower 10 //power for transmissions in dBm
|
||||
|
||||
@@ -0,0 +1,297 @@
|
||||
/*******************************************************************************************************
|
||||
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 is a remote control receiver. When a packet is received an 8 bit byte
|
||||
(SwitchByte) is read and the four outputs (defined in Settings.h) are toggled according to the bits
|
||||
set in this byte. If the Switch1 byte has bit 0 cleared, then OUTPUT0 is toggled. If the Switch1 byte
|
||||
has bit 1 cleared, then OUTPUT1 is toggled. If the Switch1 byte has bit 2 cleared, then OUTPUT2 is toggled.
|
||||
|
||||
To prevent false triggering at the receiver the packet contains also contains a 32 bit number called the
|
||||
TXIdentity which in this example is set to 1234554321. The receiver will only act on, change the state
|
||||
of the outputs, if the identity set in the receiver matches that of the transmitter. The chance of a
|
||||
false trigger is fairly remote.
|
||||
|
||||
The pin definitions, LoRa frequency and LoRa modem settings are in the Settings.h file.
|
||||
|
||||
Serial monitor baud rate is set at 9600.
|
||||
*******************************************************************************************************/
|
||||
|
||||
#define programversion "V1.0"
|
||||
|
||||
#include <SPI.h>
|
||||
#include <SX128XLT.h>
|
||||
#include "Settings.h"
|
||||
#include <ProgramLT_Definitions.h>
|
||||
|
||||
|
||||
SX128XLT LT;
|
||||
|
||||
uint32_t RXpacketCount;
|
||||
uint16_t errors;
|
||||
|
||||
uint8_t RXPacketL; //length of received packet
|
||||
uint8_t RXPacketType; //type of received packet
|
||||
int8_t PacketRSSI; //RSSI of received packet
|
||||
int8_t PacketSNR; //signal to noise ratio of received packet
|
||||
|
||||
uint8_t SwitchByte = 0xFF; //this is the transmitted switch values, bit 0 = Switch0 etc
|
||||
|
||||
void loop()
|
||||
{
|
||||
|
||||
RXPacketL = LT.receiveSXBuffer(0, 0, WAIT_RX); //returns 0 if packet error of some sort, no timeout
|
||||
|
||||
digitalWrite(LED1, HIGH); //something has happened
|
||||
|
||||
PacketRSSI = LT.readPacketRSSI(); //read the signal strength of the received packet
|
||||
PacketSNR = LT.readPacketSNR(); //read the signal to noise ratio of the received packet
|
||||
|
||||
if (RXPacketL == 0)
|
||||
{
|
||||
packet_is_Error();
|
||||
}
|
||||
else
|
||||
{
|
||||
packet_is_OK();
|
||||
}
|
||||
|
||||
digitalWrite(LED1, LOW);
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
|
||||
uint8_t packet_is_OK()
|
||||
{
|
||||
//packet has been received, now read from the SX12xx Buffer using the same variable type and
|
||||
//order as the transmit side used.
|
||||
uint32_t TXIdentity;
|
||||
|
||||
RXpacketCount++;
|
||||
Serial.print(RXpacketCount);
|
||||
Serial.print(F(" Packet Received"));
|
||||
|
||||
LT.startReadSXBuffer(0); //start buffer read at location 0
|
||||
RXPacketType = LT.readUint8(); //read in the packet type
|
||||
TXIdentity = LT.readUint32(); //read in the identity of transmitter
|
||||
SwitchByte = LT.readUint8(); //read in the Switch values
|
||||
RXPacketL = LT.endReadSXBuffer(); //finish buffer read
|
||||
|
||||
printpacketDetails();
|
||||
|
||||
if (RXPacketType != RControl1)
|
||||
{
|
||||
Serial.print(F(" Wrong packet type"));
|
||||
led_Flash(5, 25); //short fast speed flash indicates wrong packet type
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (TXIdentity != RXIdentity)
|
||||
{
|
||||
Serial.print(F(" Transmitter "));
|
||||
Serial.print(TXIdentity);
|
||||
Serial.print(F(" not recognised"));
|
||||
led_Flash(5, 25); //short fast speed flash indicates transmitter not recognised
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (LT.readRXPacketL() != 6)
|
||||
{
|
||||
Serial.print(F(" Wrong Packet Length"));
|
||||
led_Flash(5, 25); //short fast speed flash indicates transmitter not recognised
|
||||
return 0;
|
||||
}
|
||||
|
||||
//if we get to here, then the packet is valid so switch outputs accordingly
|
||||
|
||||
if (BUZZER >= 0)
|
||||
{
|
||||
digitalWrite(BUZZER, HIGH);
|
||||
}
|
||||
|
||||
Serial.print(F(",SwitchByte Received "));
|
||||
Serial.print(SwitchByte, BIN); //print switch values in binary, if a bit is 0, that switch is active
|
||||
actionOutputs(SwitchByte);
|
||||
|
||||
if (BUZZER >= 0)
|
||||
{
|
||||
digitalWrite(BUZZER, LOW);
|
||||
}
|
||||
|
||||
return RXPacketL;
|
||||
}
|
||||
|
||||
|
||||
void packet_is_Error()
|
||||
{
|
||||
uint16_t IRQStatus;
|
||||
IRQStatus = LT.readIrqStatus();
|
||||
|
||||
if (IRQStatus & IRQ_RX_TIMEOUT)
|
||||
{
|
||||
Serial.print(F("RXTimeout"));
|
||||
}
|
||||
else
|
||||
{
|
||||
errors++;
|
||||
Serial.print(F("PacketError"));
|
||||
printpacketDetails();
|
||||
Serial.print(F("IRQreg,"));
|
||||
Serial.print(IRQStatus, HEX);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void printpacketDetails()
|
||||
{
|
||||
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 flashes, uint16_t delaymS)
|
||||
{
|
||||
uint16_t index;
|
||||
|
||||
for (index = 1; index <= flashes; index++)
|
||||
{
|
||||
digitalWrite(LED1, HIGH);
|
||||
delay(delaymS);
|
||||
digitalWrite(LED1, LOW);
|
||||
delay(delaymS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void actionOutputs(uint8_t switches)
|
||||
{
|
||||
//read the recreived switch byte and toggle outputs as required
|
||||
|
||||
if (!bitRead(switches, 0))
|
||||
{
|
||||
//toggle Output state
|
||||
digitalWrite(OUTPUT0, !digitalRead(OUTPUT0)); //toggle Output state
|
||||
}
|
||||
|
||||
if (!bitRead(switches, 1))
|
||||
{
|
||||
digitalWrite(OUTPUT1, !digitalRead(OUTPUT1)); //toggle Output state
|
||||
}
|
||||
|
||||
if (!bitRead(switches, 2))
|
||||
{
|
||||
digitalWrite(OUTPUT2, !digitalRead(OUTPUT2)); //toggle Output state
|
||||
}
|
||||
|
||||
if (!bitRead(switches, 3))
|
||||
{
|
||||
digitalWrite(OUTPUT3, !digitalRead(OUTPUT3)); //toggle Output state
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void setupOutputs()
|
||||
{
|
||||
//configure the output pins, if a pin is defiend in 'Settings.h' as -1, its not configured, so stays as input
|
||||
|
||||
if (OUTPUT0 >= 0)
|
||||
{
|
||||
pinMode(OUTPUT0, OUTPUT);
|
||||
}
|
||||
|
||||
if (OUTPUT1 >= 0)
|
||||
{
|
||||
pinMode(OUTPUT1, OUTPUT);
|
||||
}
|
||||
|
||||
if (OUTPUT2 >= 0)
|
||||
{
|
||||
pinMode(OUTPUT2, OUTPUT);
|
||||
}
|
||||
|
||||
if (OUTPUT3 >= 0)
|
||||
{
|
||||
pinMode(OUTPUT3, OUTPUT);
|
||||
}
|
||||
|
||||
if (BUZZER >= 0)
|
||||
{
|
||||
pinMode(BUZZER, OUTPUT);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void outputCheck(uint8_t number, uint32_t ondelaymS, uint32_t offdelaymS)
|
||||
{
|
||||
uint8_t index;
|
||||
|
||||
Serial.println(F("Toggling outputs"));
|
||||
|
||||
for (index = 1; index <= number; index++)
|
||||
{
|
||||
digitalWrite(OUTPUT0, HIGH);
|
||||
delay(ondelaymS);
|
||||
digitalWrite(OUTPUT0, LOW);
|
||||
delay(offdelaymS);
|
||||
digitalWrite(OUTPUT1, HIGH);
|
||||
delay(ondelaymS);
|
||||
digitalWrite(OUTPUT1, LOW);
|
||||
delay(offdelaymS);
|
||||
digitalWrite(OUTPUT2, HIGH);
|
||||
delay(ondelaymS);
|
||||
digitalWrite(OUTPUT2, LOW);
|
||||
delay(offdelaymS);
|
||||
digitalWrite(OUTPUT3, HIGH);
|
||||
delay(offdelaymS);
|
||||
digitalWrite(OUTPUT3, LOW);
|
||||
delay(offdelaymS);
|
||||
digitalWrite(BUZZER, HIGH);
|
||||
delay(offdelaymS);
|
||||
digitalWrite(BUZZER, LOW);
|
||||
delay(offdelaymS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
pinMode(LED1, OUTPUT);
|
||||
led_Flash(2, 125);
|
||||
|
||||
Serial.begin(9600);
|
||||
|
||||
setupOutputs();
|
||||
|
||||
outputCheck(3, 500, 100);
|
||||
|
||||
SPI.begin();
|
||||
|
||||
if (LT.begin(NSS, NRESET, RFBUSY, DIO1, DIO2, DIO3, RX_EN, TX_EN, 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.println(F("Receiver ready"));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
/*******************************************************************************************************
|
||||
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 definitiosn to match your own setup. Some pins such as DIO2,
|
||||
//DIO3, may not be in used by this sketch so they do not need to be connected and
|
||||
//should be set to -1.
|
||||
|
||||
const int8_t NSS = 10; //select on LoRa device
|
||||
const int8_t NRESET = 9; //reset on LoRa device
|
||||
const int8_t RFBUSY = 7; //RF busy on LoRa device
|
||||
const int8_t DIO1 = 3; //DIO1 on LoRa device, used for RX and TX done
|
||||
const int8_t DIO2 = -1; //DIO2 on LoRa device, normally not used so set to -1
|
||||
const int8_t DIO3 = -1; //DIO3 on LoRa device, normally not used so set to -1
|
||||
const int8_t LED1 = 8; //On board LED, logic high is on
|
||||
const int8_t RX_EN = -1; //pin for RX enable, used on some SX1280 devices, set to -1 if not used
|
||||
const int8_t TX_EN = -1; //pin for TX enable, used on some SX1280 devices, set to -1 if not used
|
||||
const int8_t BUZZER = -1; //pin for buzzer, set to -1 if not used
|
||||
|
||||
#define LORA_DEVICE DEVICE_SX1280 //this is the device we are using
|
||||
|
||||
const int8_t OUTPUT0 = 2;
|
||||
const int8_t OUTPUT1 = 4;
|
||||
const int8_t OUTPUT2 = A3;
|
||||
const int8_t OUTPUT3 = A2;
|
||||
|
||||
const uint32_t RXIdentity = 1234554321; //define an identity number, the receiver must use the same number
|
||||
//range is 0 to 4294967296
|
||||
|
||||
|
||||
|
||||
//******* Setup LoRa Test Parameters Here ! ***************
|
||||
|
||||
//LoRa Modem Parameters
|
||||
#define Frequency 2445000000 //frequency of transmissions
|
||||
#define Offset 0 //offset frequency for calibration purposes
|
||||
#define Bandwidth LORA_BW_0400 //LoRa bandwidth
|
||||
#define SpreadingFactor LORA_SF7 //LoRa spreading factor
|
||||
#define CodeRate LORA_CR_4_5 //LoRa coding rate
|
||||
|
||||
#define TXpower 10 //power for transmissions in dBm
|
||||
|
||||
@@ -0,0 +1,190 @@
|
||||
/*******************************************************************************************************
|
||||
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 is a remote control transmitter that uses a LoRa link to transmit the positions
|
||||
from a simple joystick to a remote receiver. The receiver uses the sent joystick positions to adjust the
|
||||
positions of servos. The postions of the joysticks potentiometers on the transmitter are read with the
|
||||
analogueRead() function.
|
||||
|
||||
If the joystick has a switch, often made by pressing on the joystick, then this can be used to remote
|
||||
control an output on the receiver. The switch is read by an interrupt, the interrupt routine sets a flag
|
||||
byte which is read in loop().
|
||||
|
||||
The program is intended as a proof of concept demonstration of how to remote control servos, the program
|
||||
is not designed as a practical remote control device for RC model cars for instance.
|
||||
|
||||
To have the transmitter program print out the values read from the joystick, comment in the line;
|
||||
|
||||
//#define DEBUG
|
||||
|
||||
Which is just above the loop() function. With the DEBUG enabled the transmission rate, the rate at which
|
||||
the control packets are transmitted will be slowed down.
|
||||
|
||||
To reduce the risk of the receiver picking up LoRa packets from other sources, the packet sent contains a
|
||||
'TXidentity' number, valid values are 0 - 65535. The receiver must be setup with the matching identity
|
||||
number or the received packets will be ignored.
|
||||
|
||||
The pin definitions, LoRa frequency and LoRa modem settings are in the Settings.h file. These settings
|
||||
are not necessarily optimised for long range.
|
||||
|
||||
Serial monitor baud rate is set at 115200.
|
||||
*******************************************************************************************************/
|
||||
|
||||
#include <SPI.h>
|
||||
#include <SX128XLT.h>
|
||||
#include "Settings.h"
|
||||
#include <ProgramLT_Definitions.h>
|
||||
|
||||
SX128XLT LT;
|
||||
|
||||
#include "PinChangeInterrupt.h" //get the library here; https://github.com/NicoHood/PinChangeInterrupt
|
||||
|
||||
uint32_t TXpacketCount;
|
||||
uint8_t TXPacketL;
|
||||
|
||||
uint8_t joystickX1value; //variable to read the value from the analog pin
|
||||
uint8_t joystickY1value; //variable to read the value from the analog pin
|
||||
|
||||
volatile bool switch1flag = false;
|
||||
|
||||
//#define DEBUG //comment in thie line (remove the two // at the beggining) for debug output
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
uint8_t switchByte = 0xFF;
|
||||
|
||||
joystickX1value = (uint8_t) (analogRead(joystickX1) / 4) ; //read the joystick X1 pot, turn 0-1023 into 0 to 255
|
||||
joystickY1value = (uint8_t) (analogRead(joystickY1) / 4); //read the joystick Y1 pot
|
||||
|
||||
if (switch1flag)
|
||||
{
|
||||
bitClear(switchByte, 1); //if the switch is down clear the bit
|
||||
digitalWrite(LED1, HIGH); //turn on LED as switch indicator
|
||||
switch1flag = false;
|
||||
}
|
||||
|
||||
if (!sendJoystickPacket(joystickX1value, joystickY1value, switchByte))
|
||||
{
|
||||
Serial.print(F("Send Error - IRQreg,"));
|
||||
Serial.print(LT.readIrqStatus(), HEX);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint8_t sendJoystickPacket(uint16_t X1value, uint16_t Y1value, uint8_t switches)
|
||||
{
|
||||
//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.
|
||||
|
||||
LT.startWriteSXBuffer(0); //start the write packet to buffer process
|
||||
LT.writeUint8(RControl1); //this is the packet type
|
||||
LT.writeUint8(TXIdentity); //this value represents the transmitter number
|
||||
LT.writeUint8(X1value); //this byte contains joystick pot AD X1 value to be sent
|
||||
LT.writeUint8(Y1value); //this byte contains joystick pot AD Y1 value to be sent
|
||||
LT.writeUint8(switches); //switches value
|
||||
LT.endWriteSXBuffer(); //close the packet, thee are 5 bytes to send
|
||||
|
||||
//now transmit the packet, 10 second timeout, and wait for it to complete sending
|
||||
TXPacketL = LT.transmitSXBuffer(0, PacketLength, 10000, TXpower, WAIT_TX);
|
||||
|
||||
#ifdef DEBUG
|
||||
Serial.print(TXIdentity);
|
||||
Serial.print(F(",X1,"));
|
||||
Serial.print(joystickX1value);
|
||||
Serial.print(F(",Y1,"));
|
||||
Serial.print(joystickY1value);
|
||||
Serial.print(F(","));
|
||||
Serial.print(switches, BIN);
|
||||
Serial.println();
|
||||
#endif
|
||||
|
||||
digitalWrite(LED1, LOW); //LED off, may have been on due to switch press
|
||||
|
||||
return TXPacketL; //TXPacketL will be 0 if there was an error sending
|
||||
}
|
||||
|
||||
|
||||
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 attachInterrupts()
|
||||
{
|
||||
if (SWITCH1 >= 0)
|
||||
{
|
||||
attachPCINT(digitalPinToPCINT(SWITCH1), wake1, FALLING);
|
||||
switch1flag = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void detachInterrupts()
|
||||
{
|
||||
if (SWITCH1 >= 0)
|
||||
{
|
||||
detachPCINT(digitalPinToPCINT(SWITCH1));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void wake1()
|
||||
{
|
||||
switch1flag = true;
|
||||
}
|
||||
|
||||
|
||||
void setupSwitches()
|
||||
{
|
||||
if (SWITCH1 >= 0)
|
||||
{
|
||||
pinMode(SWITCH1, INPUT_PULLUP);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
pinMode(LED1, OUTPUT);
|
||||
led_Flash(2, 125);
|
||||
|
||||
setupSwitches();
|
||||
|
||||
Serial.begin(115200);
|
||||
|
||||
SPI.begin();
|
||||
|
||||
if (LT.begin(NSS, NRESET, RFBUSY, DIO1, DIO2, DIO3, RX_EN, TX_EN, LORA_DEVICE))
|
||||
{
|
||||
led_Flash(2, 125);
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println(F("Device error"));
|
||||
while (1)
|
||||
{
|
||||
led_Flash(50, 50);
|
||||
}
|
||||
}
|
||||
|
||||
LT.setupLoRa(Frequency, Offset, SpreadingFactor, Bandwidth, CodeRate);
|
||||
|
||||
attachInterrupts();
|
||||
|
||||
Serial.println(F("35_Remote_Control_Servo_Transmitter ready"));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
/*******************************************************************************************************
|
||||
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 definitiosn to match your own setup. Some pins such as DIO2,
|
||||
//DIO3, may not be in used by this sketch so they do not need to be connected and
|
||||
//should be set to -1.
|
||||
|
||||
const int8_t NSS = 10; //select on LoRa device
|
||||
const int8_t NRESET = 9; //reset on LoRa device
|
||||
const int8_t RFBUSY = 7; //RF busy on LoRa device
|
||||
const int8_t DIO1 = 3; //DIO1 on LoRa device, used for RX and TX done
|
||||
const int8_t DIO2 = -1; //DIO2 on LoRa device, normally not used so set to -1
|
||||
const int8_t DIO3 = -1; //DIO3 on LoRa device, normally not used so set to -1
|
||||
const int8_t LED1 = 8; //On board LED, logic high is on
|
||||
const int8_t RX_EN = -1; //pin for RX enable, used on some SX1280 devices, set to -1 if not used
|
||||
const int8_t TX_EN = -1; //pin for TX enable, used on some SX1280 devices, set to -1 if not used
|
||||
|
||||
|
||||
#define LORA_DEVICE DEVICE_SX1280 //this is the device we are using
|
||||
|
||||
const int8_t joystickX1 = A2; //analog pin for the joystick 1 X pot
|
||||
const int8_t joystickY1 = A3; //analog pin for the joystick 1 Y pot
|
||||
const int8_t SWITCH1 = 2; //switch on joystick, set to -1 if not used
|
||||
|
||||
const uint32_t TXIdentity = 123 ; //define a transmitter number, the receiver must use the same number
|
||||
//range is 0 to 255
|
||||
|
||||
|
||||
|
||||
//******* Setup LoRa Test Parameters Here ! ***************
|
||||
|
||||
//LoRa Modem Parameters
|
||||
#define Frequency 2445000000 //frequency of transmissions
|
||||
#define Offset 0 //offset frequency for calibration purposes
|
||||
#define Bandwidth LORA_BW_0400 //LoRa bandwidth
|
||||
#define SpreadingFactor LORA_SF7 //LoRa spreading factor
|
||||
#define CodeRate LORA_CR_4_5 //LoRa coding rate
|
||||
|
||||
const uint8_t PacketLength = 5; //packet length is fixed
|
||||
const int8_t TXpower = 10; //LoRa transmit power in dBm
|
||||
|
||||
@@ -0,0 +1,256 @@
|
||||
/*******************************************************************************************************
|
||||
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 is a remote control receiver that uses a LoRa link to control the positions of
|
||||
servos sent from a remote transmitter.
|
||||
|
||||
If the ttransmitter joystick has a switch, often made by pressing on the joystick, then this can be used
|
||||
to remote control an output on the receiver.
|
||||
|
||||
The program is intended as a proof of concept demonstration of how to remote control servos, the program
|
||||
is not designed as a practical remote control device for RC model cars for instance.
|
||||
|
||||
It would be straight forward to make the transmitter program send packets continuously, but in most places
|
||||
in the world that would break a normal limitation of 10% duty cycle for unlicensed use. Therefore the
|
||||
program was designed to only transmit at a 10% duty cycle. Thus the fastest (lowest air time) packets are
|
||||
used, spreading factor 6 at a bandwidth of 500khz. This results in an air time for the 5 byte control
|
||||
packet of around 4mS, so there are around 25 sent per second.
|
||||
|
||||
To have the receiver program print out the joystick values (0-255) read from the received packet, comment
|
||||
in the line;
|
||||
|
||||
//#define DEBUG
|
||||
|
||||
Which is just above the loop() function. With the DEBUG enabled then there is a possibility that some
|
||||
transmitted packets will be missed. With the DEBUG line enabled to servos should also sweep to and fro 3
|
||||
times at program start-up.
|
||||
|
||||
To reduce the risk of the receiver picking up LoRa packets from other sources, the packet sent contains a
|
||||
'TXidentity' number, valid values are 0 - 255. The receiver must be setup with the matching RXIdentity
|
||||
number in Settings.h or the received packets will be ignored.
|
||||
|
||||
The pin definitions, LoRa frequency and LoRa modem settings are in the Settings.h file. These settings
|
||||
are not necessarily optimised for long range.
|
||||
|
||||
Serial monitor baud rate is set at 115200.
|
||||
*******************************************************************************************************/
|
||||
|
||||
#define programversion "V1.0"
|
||||
|
||||
#include <SPI.h>
|
||||
#include <SX128XLT.h>
|
||||
#include "Settings.h"
|
||||
#include <ProgramLT_Definitions.h>
|
||||
|
||||
SX128XLT LT;
|
||||
|
||||
#include <Servo.h>
|
||||
Servo ServoX1; //create the servo object
|
||||
Servo ServoY1; //create the servo object
|
||||
|
||||
uint8_t joystickX1value; //variable to read the value from the analog pin
|
||||
uint8_t joystickY1value; //variable to read the value from the analog pin
|
||||
uint8_t RXPacketL; //length of received packet
|
||||
uint8_t RXPacketType; //type of received packet
|
||||
|
||||
//#define DEBUG
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
uint16_t IRQStatus;
|
||||
|
||||
RXPacketL = LT.receiveSXBuffer(0, 0, WAIT_RX); //returns 0 if packet error of some sort
|
||||
|
||||
while (!digitalRead(DIO1)); //wait for DIO1 to go high
|
||||
|
||||
IRQStatus = LT.readIrqStatus();
|
||||
|
||||
if (IRQStatus & (IRQ_RX_DONE + IRQ_HEADER_VALID) )
|
||||
{
|
||||
packet_is_OK();
|
||||
}
|
||||
else
|
||||
{
|
||||
packet_is_Error();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
uint8_t packet_is_OK()
|
||||
{
|
||||
//packet has been received, now read from the SX12xx Buffer using the same variable type and
|
||||
//order as the transmit side used.
|
||||
uint8_t TXIdentity;
|
||||
uint16_t pulseX1, pulseY1;
|
||||
uint8_t switchByte = 0xFF; //this is the transmitted switch values, bit 0 = Switch0 etc
|
||||
|
||||
LT.startReadSXBuffer(0); //start buffer read at location 0
|
||||
RXPacketType = LT.readUint8(); //read in the packet type
|
||||
TXIdentity = LT.readUint8(); //read in the transmitter number
|
||||
joystickX1value = LT.readUint8(); //this byte contains joystick pot AD X1 value sent
|
||||
joystickY1value = LT.readUint8(); //this byte contains joystick pot AD Y1 value sent
|
||||
switchByte = LT.readUint8(); //read in the Switch values
|
||||
RXPacketL = LT.endReadSXBuffer(); //end buffer read
|
||||
|
||||
#ifdef DEBUG
|
||||
Serial.print(TXIdentity);
|
||||
Serial.print(F(",X1,"));
|
||||
Serial.print(joystickX1value);
|
||||
Serial.print(F(",Y1,"));
|
||||
Serial.print(joystickY1value);
|
||||
Serial.print(F(","));
|
||||
Serial.print(switchByte, BIN);
|
||||
Serial.println();
|
||||
#endif
|
||||
|
||||
|
||||
if (RXPacketType != RControl1)
|
||||
{
|
||||
Serial.print(F("Packet type "));
|
||||
Serial.println(RXPacketType);
|
||||
led_Flash(5, 25); //short fast speed flash indicates wrong packet type
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
if (TXIdentity != RXIdentity)
|
||||
{
|
||||
Serial.print(F("TX"));
|
||||
Serial.print(TXIdentity);
|
||||
Serial.println(F("?"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
//actionServos
|
||||
pulseX1 = map(joystickX1value, 0, 255, 1000, 2000); //scale the numbers from the joystick
|
||||
ServoX1.writeMicroseconds(pulseX1);
|
||||
pulseY1 = map(joystickY1value, 0, 255, 1000, 2000); //scale the numbers from the joystick
|
||||
ServoY1.writeMicroseconds(pulseY1); //move the servo to position
|
||||
|
||||
//actionOutputs
|
||||
if (!bitRead(switchByte, 1))
|
||||
{
|
||||
digitalWrite(OUTPUT1, !digitalRead(OUTPUT1)); //Toggle Output state
|
||||
}
|
||||
|
||||
return RXPacketL;
|
||||
}
|
||||
|
||||
|
||||
void packet_is_Error()
|
||||
{
|
||||
uint16_t IRQStatus;
|
||||
int8_t PacketRSSI;
|
||||
IRQStatus = LT.readIrqStatus();
|
||||
|
||||
if (IRQStatus & IRQ_RX_TIMEOUT)
|
||||
{
|
||||
Serial.print(F("RXTimeout"));
|
||||
}
|
||||
else
|
||||
{
|
||||
PacketRSSI = LT.readPacketRSSI(); //read the signal strength of the received packet
|
||||
Serial.print(F("Err,"));
|
||||
Serial.print(PacketRSSI);
|
||||
Serial.print(F("dBm"));
|
||||
}
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
|
||||
void setupOutputs()
|
||||
{
|
||||
//configure the output pins, if a pin is defiend in 'Settings.h' as -1, its not configured, so stays as input
|
||||
if (OUTPUT1 >= 0)
|
||||
{
|
||||
pinMode(OUTPUT1, OUTPUT);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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 sweepTest(uint8_t num)
|
||||
{
|
||||
uint16_t index1, index2;
|
||||
for (index1 = 1; index1 <= num; index1++)
|
||||
{
|
||||
for (index2 = 900; index2 <= 2100; index2++)
|
||||
{
|
||||
ServoX1.writeMicroseconds(index2);
|
||||
ServoY1.writeMicroseconds(index2);
|
||||
}
|
||||
|
||||
delay(1000);
|
||||
|
||||
for (index2 = 2100; index2 >= 900; index2--)
|
||||
{
|
||||
ServoX1.writeMicroseconds(index2);
|
||||
ServoY1.writeMicroseconds(index2);
|
||||
}
|
||||
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
pinMode(LED1, OUTPUT);
|
||||
led_Flash(2, 125);
|
||||
|
||||
setupOutputs();
|
||||
|
||||
Serial.begin(115200);
|
||||
|
||||
ServoX1.attach(pinservoX1); //connect pin pinservoX1 to ServoX1 object
|
||||
ServoY1.attach(pinservoY1); //connect pin pinservoY1 to ServoY1 object
|
||||
|
||||
#ifdef DEBUG
|
||||
Serial.println(F("Servo sweep test"));
|
||||
sweepTest(3);
|
||||
#endif
|
||||
|
||||
SPI.begin();
|
||||
|
||||
if (LT.begin(NSS, NRESET, RFBUSY, DIO1, DIO2, DIO3, RX_EN, TX_EN, 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.println(F("36_Remote_Control_Servo_Receiver ready"));
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
/*******************************************************************************************************
|
||||
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 definitiosn to match your own setup. Some pins such as DIO2,
|
||||
//DIO3, may not be in used by this sketch so they do not need to be connected and
|
||||
//should be set to -1.
|
||||
|
||||
const int8_t NSS = 10; //select on LoRa device
|
||||
const int8_t NRESET = 9; //reset on LoRa device
|
||||
const int8_t RFBUSY = 7; //RF busy on LoRa device
|
||||
const int8_t DIO1 = 3; //DIO1 on LoRa device, used for RX and TX done
|
||||
const int8_t DIO2 = -1; //DIO2 on LoRa device, normally not used so set to -1
|
||||
const int8_t DIO3 = -1; //DIO3 on LoRa device, normally not used so set to -1
|
||||
const int8_t LED1 = 8; //On board LED, logic high is on
|
||||
const int8_t RX_EN = -1; //pin for RX enable, used on some SX1280 devices, set to -1 if not used
|
||||
const int8_t TX_EN = -1; //pin for TX enable, used on some SX1280 devices, set to -1 if not used
|
||||
|
||||
#define LORA_DEVICE DEVICE_SX1280 //this is the device we are using
|
||||
|
||||
const int8_t pinservoX1 = 2; //pin for controlling servo X1
|
||||
const int8_t pinservoY1 = 4; //pin for controlling servo Y1
|
||||
const int8_t OUTPUT1 = 8; //this output toggles when joystick switch is pressed on receiver
|
||||
|
||||
const uint16_t RXIdentity = 123; //define a receiver number, the transmitter must use the same number
|
||||
//range is 0 to 255
|
||||
|
||||
//******* Setup LoRa Test Parameters Here ! ***************
|
||||
|
||||
//LoRa Modem Parameters
|
||||
#define Frequency 2445000000 //frequency of transmissions
|
||||
#define Offset 0 //offset frequency for calibration purposes
|
||||
#define Bandwidth LORA_BW_0400 //LoRa bandwidth
|
||||
#define SpreadingFactor LORA_SF7 //LoRa spreading factor
|
||||
#define CodeRate LORA_CR_4_5 //LoRa coding rate
|
||||
|
||||
const uint8_t PacketLength = 5; //packet length is fixed
|
||||
|
||||
@@ -0,0 +1,315 @@
|
||||
/*******************************************************************************************************
|
||||
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 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, 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, DIO2, DIO3, RX_EN, TX_EN, 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,45 @@
|
||||
/*******************************************************************************************************
|
||||
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. Some pins such as DIO2,
|
||||
//DIO3, BUZZER may not be in used by this sketch so they do not need to be
|
||||
//connected and should be included and be set to -1.
|
||||
|
||||
#define NSS 10
|
||||
#define RFBUSY 7
|
||||
#define NRESET 9
|
||||
#define LED1 8
|
||||
#define DIO1 3
|
||||
#define DIO2 -1 //not used
|
||||
#define DIO3 -1 //not used
|
||||
#define RX_EN -1 //pin for RX enable, used on some SX1280 devices, set to -1 if not used
|
||||
#define TX_EN -1 //pin for TX enable, used on some SX1280 devices, set to -1 if not used
|
||||
#define BUZZER -1 //pin for BUZZER, set to -1 if not used
|
||||
|
||||
#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 uint8_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,358 @@
|
||||
/*******************************************************************************************************
|
||||
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
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
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, DIO2, DIO3, RX_EN, TX_EN, 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,46 @@
|
||||
/*******************************************************************************************************
|
||||
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. Some pins such as DIO2,
|
||||
//DIO3, 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 10
|
||||
#define RFBUSY 7
|
||||
#define NRESET 9
|
||||
#define LED1 8
|
||||
#define DIO1 3
|
||||
#define DIO2 -1 //not used
|
||||
#define DIO3 -1 //not used
|
||||
#define RX_EN -1 //pin for RX enable, used on some SX1280 devices, set to -1 if not used
|
||||
#define TX_EN -1 //pin for TX enable, used on some SX1280 devices, set to -1 if not used
|
||||
#define BUZZER -1 //pin for BUZZER, set to -1 if not used
|
||||
|
||||
#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 uint8_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
|
||||
|
||||
@@ -0,0 +1,242 @@
|
||||
/*******************************************************************************************************
|
||||
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 - This program tests the sleep mode and register retention of the lora device in sleep
|
||||
mode, it assumes an Atmel ATMega328P processor is in use. The LoRa settings to use are specified in the
|
||||
'Settings.h' file.
|
||||
|
||||
A packet is sent, containing the text 'Before Device Sleep' and the LoRa device and Atmel processor are put
|
||||
to sleep. The processor watchdog timer should wakeup the processor in 15 seconds (approx) and register
|
||||
values should be retained. The device then attempts to transmit another packet 'After Device Sleep'
|
||||
without re-loading all the LoRa settings. The receiver should see 'After Device Sleep' for the first
|
||||
packet and 'After Device Sleep' for the second.
|
||||
|
||||
Tested on a 'bare bones' ATmega328P board, the current in sleep mode was 12.2uA.
|
||||
|
||||
Serial monitor baud rate is set at 9600.
|
||||
*******************************************************************************************************/
|
||||
|
||||
#define Program_Version "V1.0"
|
||||
|
||||
#include <avr/wdt.h> //watchdog timer library, integral to Arduino IDE
|
||||
#include <SPI.h>
|
||||
#include <LowPower.h> //get the library here; https://github.com/rocketscream/Low-Power
|
||||
|
||||
#include <SX128XLT.h>
|
||||
#include "Settings.h"
|
||||
|
||||
SX128XLT LT;
|
||||
|
||||
boolean SendOK;
|
||||
int8_t TestPower;
|
||||
uint8_t TXPacketL;
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
digitalWrite(LED1, HIGH);
|
||||
Serial.print(TXpower);
|
||||
Serial.print(F("dBm "));
|
||||
Serial.print(F("TestPacket1> "));
|
||||
Serial.flush();
|
||||
|
||||
if (Send_Test_Packet1())
|
||||
{
|
||||
packet_is_OK();
|
||||
}
|
||||
else
|
||||
{
|
||||
packet_is_Error();
|
||||
}
|
||||
Serial.println();
|
||||
delay(packet_delay);
|
||||
|
||||
LT.setSleep(CONFIGURATION_RETENTION); //preserve register settings in sleep.
|
||||
Serial.println(F("Sleeping zzzzz...."));
|
||||
Serial.println();
|
||||
Serial.flush();
|
||||
digitalWrite(LED1, LOW);
|
||||
|
||||
sleep1second(15); //goto sleep for 15 seconds
|
||||
|
||||
Serial.println(F("Awake !"));
|
||||
Serial.flush();
|
||||
digitalWrite(LED1, HIGH);
|
||||
LT.wake();
|
||||
|
||||
Serial.print(TXpower);
|
||||
Serial.print(F("dBm "));
|
||||
Serial.print(F("TestPacket2> "));
|
||||
Serial.flush();
|
||||
|
||||
if (Send_Test_Packet2())
|
||||
{
|
||||
packet_is_OK();
|
||||
}
|
||||
else
|
||||
{
|
||||
packet_is_Error();
|
||||
}
|
||||
Serial.println();
|
||||
delay(packet_delay);
|
||||
}
|
||||
|
||||
|
||||
void sleep1second(uint32_t sleeps)
|
||||
{
|
||||
//uses the lowpower library
|
||||
uint32_t index;
|
||||
|
||||
for (index = 1; index <= sleeps; index++)
|
||||
{
|
||||
LowPower.powerDown(SLEEP_1S, ADC_OFF, BOD_OFF); //sleep in 1 second steps
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void packet_is_OK()
|
||||
{
|
||||
Serial.print(F(" "));
|
||||
Serial.print(TXPacketL);
|
||||
Serial.print(F(" Bytes SentOK"));
|
||||
}
|
||||
|
||||
|
||||
void packet_is_Error()
|
||||
{
|
||||
uint16_t IRQStatus;
|
||||
IRQStatus = LT.readIrqStatus(); //get the IRQ status
|
||||
Serial.print(F("SendError,"));
|
||||
Serial.print(F("Length,"));
|
||||
Serial.print(TXPacketL);
|
||||
Serial.print(F(",IRQreg,"));
|
||||
Serial.print(IRQStatus, HEX);
|
||||
LT.printIrqStatus();
|
||||
digitalWrite(LED1, LOW); //this leaves the LED on slightly longer for a packet error
|
||||
}
|
||||
|
||||
|
||||
bool Send_Test_Packet1()
|
||||
{
|
||||
uint8_t bufffersize;
|
||||
|
||||
uint8_t buff[] = "Before Device Sleep";
|
||||
TXPacketL = sizeof(buff);
|
||||
buff[TXPacketL - 1] = '*';
|
||||
|
||||
if (sizeof(buff) > TXBUFFER_SIZE) //check that defined buffer is not larger than TX_BUFFER
|
||||
{
|
||||
bufffersize = TXBUFFER_SIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
bufffersize = sizeof(buff);
|
||||
}
|
||||
|
||||
TXPacketL = bufffersize;
|
||||
|
||||
LT.printASCIIPacket( (uint8_t*) buff, bufffersize);
|
||||
digitalWrite(LED1, HIGH);
|
||||
|
||||
if (LT.transmit( (uint8_t*) buff, TXPacketL, 10000, TXpower, WAIT_TX))
|
||||
{
|
||||
digitalWrite(LED1, LOW);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool Send_Test_Packet2()
|
||||
{
|
||||
uint8_t bufffersize;
|
||||
|
||||
uint8_t buff[] = "After Device Sleep";
|
||||
TXPacketL = sizeof(buff);
|
||||
buff[TXPacketL - 1] = '*';
|
||||
|
||||
if (sizeof(buff) > TXBUFFER_SIZE) //check that defined buffer is not larger than TX_BUFFER
|
||||
{
|
||||
bufffersize = TXBUFFER_SIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
bufffersize = sizeof(buff);
|
||||
}
|
||||
|
||||
TXPacketL = bufffersize;
|
||||
|
||||
LT.printASCIIPacket( (uint8_t*) buff, bufffersize);
|
||||
digitalWrite(LED1, HIGH);
|
||||
|
||||
if (LT.transmit( (uint8_t*) buff, TXPacketL, 10000, TXpower, WAIT_TX))
|
||||
{
|
||||
digitalWrite(LED1, LOW);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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.print(__TIME__);
|
||||
Serial.print(F(" "));
|
||||
Serial.println(__DATE__);
|
||||
Serial.println(F(Program_Version));
|
||||
Serial.println();
|
||||
Serial.println(F("5_LoRa_TX_Sleep_Timed_Wakeup_Atmel Starting"));
|
||||
|
||||
SPI.begin();
|
||||
|
||||
if (LT.begin(NSS, NRESET, RFBUSY, DIO1, DIO2, DIO3, RX_EN, TX_EN, 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.print(F("Transmitter ready - TXBUFFER_SIZE "));
|
||||
Serial.println(TXBUFFER_SIZE);
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
/*******************************************************************************************************
|
||||
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. Some pins such as DIO2,
|
||||
//DIO3, BUZZER may not be in used by this sketch so they do not need to be
|
||||
//connected and should be included and be set to -1.
|
||||
|
||||
#define NSS 10
|
||||
#define RFBUSY 7
|
||||
#define NRESET 9
|
||||
#define LED1 8
|
||||
#define DIO1 3
|
||||
#define DIO2 -1 //not used
|
||||
#define DIO3 -1 //not used
|
||||
#define RX_EN -1 //pin for RX enable, used on some SX1280 devices, set to -1 if not used
|
||||
#define TX_EN -1 //pin for TX enable, used on some SX1280 devices, set to -1 if not used
|
||||
#define BUZZER -1 //pin for BUZZER, set to -1 if not used
|
||||
|
||||
#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 uint8_t TXpower = 10; //Power for transmissions in dBm
|
||||
const uint16_t packet_delay = 1000; //mS delay between packets
|
||||
|
||||
#define TXBUFFER_SIZE 32 //RX buffer size
|
||||
|
||||
|
||||
@@ -0,0 +1,407 @@
|
||||
/*******************************************************************************************************
|
||||
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.
|
||||
*******************************************************************************************************/
|
||||
|
||||
#define Program_Version "V1.1"
|
||||
#define authorname "Stuart Robinson"
|
||||
|
||||
#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.print(F(__TIME__));
|
||||
Serial.print(F(" "));
|
||||
Serial.println(F(__DATE__));
|
||||
Serial.println(F(Program_Version));
|
||||
Serial.println();
|
||||
|
||||
Serial.println(F("23_GPS_Tracker_Transmitter Starting"));
|
||||
|
||||
SPI.begin();
|
||||
|
||||
if (LT.begin(NSS, NRESET, RFBUSY, DIO1, RX_EN, TX_EN, 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,67 @@
|
||||
/*******************************************************************************************************
|
||||
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 definitiosn to match your own setup.
|
||||
|
||||
#define NSS 10 //select on LoRa device
|
||||
#define NRESET 9 //reset on LoRa device
|
||||
#define RFBUSY 7 //SX126X busy pin
|
||||
#define DIO1 3 //DIO1 on LoRa device, used for RX and TX done
|
||||
#define RX_EN -1 //pin for RX enable, used on some SX1280 devices, set to -1 if not used
|
||||
#define TX_EN -1 //pin for TX enable, used on some SX1280 devices, set to -1 if not used
|
||||
|
||||
#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 uint8_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,322 @@
|
||||
/*******************************************************************************************************
|
||||
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.
|
||||
*******************************************************************************************************/
|
||||
|
||||
#define Program_Version "V1.1"
|
||||
|
||||
#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
|
||||
int8_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.print(F(__TIME__));
|
||||
Serial.print(F(" "));
|
||||
Serial.println(F(__DATE__));
|
||||
Serial.println(F(Program_Version));
|
||||
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, RX_EN, TX_EN, 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,44 @@
|
||||
/*******************************************************************************************************
|
||||
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 definitiosn 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 RX_EN -1 //pin for RX enable, used on some SX1280 devices, set to -1 if not used
|
||||
#define TX_EN -1 //pin for TX enable, used on some SX1280 devices, set to -1 if not used
|
||||
|
||||
#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,624 @@
|
||||
/*******************************************************************************************************
|
||||
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.
|
||||
*******************************************************************************************************/
|
||||
|
||||
|
||||
#define Program_Version "V1.1"
|
||||
|
||||
#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
|
||||
int8_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.print(F(__TIME__));
|
||||
Serial.print(F(" "));
|
||||
Serial.println(F(__DATE__));
|
||||
Serial.println(F(Program_Version));
|
||||
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, RX_EN, TX_EN, 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,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 definitiosn to match your own setup. Some pins such as DIO1,
|
||||
//DIO2, BUZZER SWITCH1 may not be in used by this sketch so they do not need to be
|
||||
//connected and should be set to -1.
|
||||
|
||||
//These are the pin definitions for one of my own boards, the Easy Pro Mini,
|
||||
//be sure to change the definitiosn 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 RX_EN -1 //pin for RX enable, used on some SX1280 devices, set to -1 if not used
|
||||
#define TX_EN -1 //pin for TX enable, used on some SX1280 devices, set to -1 if not used
|
||||
#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
|
||||
|
||||
|
||||
@@ -0,0 +1,173 @@
|
||||
/*******************************************************************************************************
|
||||
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.
|
||||
|
||||
For an example of the use of such a program see this report;
|
||||
|
||||
How to Search 500 Square Kilometres in 10 minutes.pdf in the libraries 'Test_Reports' folder.
|
||||
|
||||
Serial monitor baud rate is set at 9600.
|
||||
|
||||
*******************************************************************************************************/
|
||||
|
||||
|
||||
#include <SPI.h>
|
||||
#include <SX128XLT.h>
|
||||
#include "Settings.h"
|
||||
|
||||
SX128XLT LT;
|
||||
|
||||
uint8_t RXPacketL, TXPacketL;
|
||||
int8_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
|
||||
|
||||
if (BUZZER > 0) //turn buzzer on
|
||||
{
|
||||
digitalWrite(BUZZER, HIGH);
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
if (BUZZER > 0)
|
||||
{
|
||||
digitalWrite(BUZZER, LOW); //buzzer off
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
/*******************************************************************************************************
|
||||
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 definitiosn 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 SW -1 //SW pin on Dorji devices is used to turn RF switch on\off, set to -1 if not used
|
||||
#define LED1 8 //On board LED, high for on
|
||||
#define BUZZER -1 //normally not used so set to -1
|
||||
|
||||
#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
|
||||
|
||||
//LoRa relay (re-transmitting) 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
|
||||
|
||||