first commit

This commit is contained in:
2021-05-11 20:43:42 +03:00
commit 9f3ffaba30
381 changed files with 69596 additions and 0 deletions

View File

@@ -0,0 +1,266 @@
/*******************************************************************************************************
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 - 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 <SX126XLT.h>
#include <ProgramLT_Definitions.h>
#include "Settings.h"
SX126XLT 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, SW, 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, Optimisation);
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(0x00, 0x4F); //print contents of device registers
Serial.println();
Serial.println();
Serial.print(F("Transmitter ready"));
Serial.println();
}

View File

@@ -0,0 +1,52 @@
/*******************************************************************************************************
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 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 //SX126X 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 SW -1 //SW pin on Dorji devices is used to turn RF switch on\off, set to -1 if not used
#define RX_EN -1 //pin for RX enable, used on some SX126X devices, set to -1 if not used
#define TX_EN -1 //pin for TX enable, used on some SX126X devices, set to -1 if not used
#define LORA_DEVICE DEVICE_SX1262 //this is the device we are using
//******* Setup LoRa Test Parameters Here ! ***************
//LoRa Modem Parameters
const uint32_t Frequency = 434000000; //frequency of transmissions
const uint32_t Offset = 0; //offset frequency for calibration purposes
const uint8_t Bandwidth = LORA_BW_125; //LoRa bandwidth
const uint8_t SpreadingFactor = LORA_SF7; //LoRa spreading factor
const uint8_t CodeRate = LORA_CR_4_5; //LoRa coding rate
const uint8_t Optimisation = LDRO_AUTO; //low data rate optimisation setting
//for SX1262, SX1268 power range is +22dBm to -9dBm
//for SX1261, power range is +15dBm t0 -9dBm
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
const int8_t end_power = -8; //and ends at this power
const uint8_t ThisNode = 'T'; //this identifies the node in transmissions
#define packet_delay 1000 //mS delay between packets
#define mode_delaymS 2000 //mS delay after sending start test sequence

View File

@@ -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 <SX126XLT.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
SX126XLT 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, SW, 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, Optimisation);
Serial.println();
LT.printModemSettings();
Serial.println();
LT.printOperatingSettings();
Serial.println();
Serial.println();
printtime();
Serial.print(F(" Receiver ready"));
Serial.println();
}

View File

@@ -0,0 +1,42 @@
/*******************************************************************************************************
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 DIO1,
//DIO2, 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 //select on LoRa device
#define NRESET 9 //reset on LoRa device
#define RFBUSY 7 //SX12XX busy pin
#define DIO1 3 //DIO1 on LoRa device, used for RX and TX done
#define DIO2 -1 //DIO2 on LoRa device, normally not used so set to -1
#define DIO3 -1 //DIO3 on LoRa device, normally not used so set to -1
#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_SX1262 //this is the device we are using
//******* Setup LoRa Test Parameters Here ! ***************
//LoRa Modem Parameters
const uint32_t Frequency = 434000000; //frequency of transmissions
const uint32_t Offset = 0; //offset frequency for calibration purposes
const uint8_t Bandwidth = LORA_BW_125; //LoRa bandwidth
const uint8_t SpreadingFactor = LORA_SF7; //LoRa spreading factor
const uint8_t CodeRate = LORA_CR_4_5; //LoRa coding rate
const uint8_t Optimisation = LDRO_AUTO; //low data rate optimisation setting
const int8_t TXpower = 2; //LoRa TX power
#define packet_delay 1000 //mS delay between packets

View File

@@ -0,0 +1,190 @@
/*******************************************************************************************************
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'.
Checked for correct operation with lora bandwidths of 500000hz, 125000 and 7800hz. At higher bandwidths
the reported frequency errors can be within 10-20hz at minimum bandwidth, 7800hz, the reported frequency
can be circa 100hz out.
Note: Semtech appear to have stated that the frequency error function that this example uses, is not
supported for SX126X, for reasons that have not been given, so use at your own risk.
Serial monitor baud rate is set at 9600.
*******************************************************************************************************/
#define Program_Version "V1.0"
#include <SPI.h>
#include <SX126XLT.h>
#include "Settings.h"
SX126XLT 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, SW, 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, Optimisation);
Serial.println(F("Receiver ready"));
Serial.println();
}

View File

@@ -0,0 +1,47 @@
/*******************************************************************************************************
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 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.
#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 //SX126X 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 SW -1 //SW pin on Dorji devices is used to turn RF switch on\off, set to -1 if not used
#define RX_EN -1 //pin for RX enable, used on some SX126X devices, set to -1 if not used
#define TX_EN -1 //pin for TX enable, used on some SX126X devices, set to -1 if not used
#define LORA_DEVICE DEVICE_SX1262 //we need to define the device we are using
//******* Setup LoRa Test Parameters Here ! ***************
//LoRa Modem Parameters
const uint32_t Frequency = 434000000; //frequency of transmissions
const uint32_t Offset = 0; //offset frequency for calibration purposes
const uint8_t Bandwidth = LORA_BW_125; //LoRa bandwidth
const uint8_t SpreadingFactor = LORA_SF7; //LoRa spreading factor
const uint8_t CodeRate = LORA_CR_4_5; //LoRa coding rate
const uint8_t Optimisation = LDRO_AUTO; //low data rate optimisation setting
const int8_t TXpower = 10; //LoRa TX power
#define packet_delay 1000 //mS delay between packets
#define RXBUFFER_SIZE 32 //RX buffer size

View File

@@ -0,0 +1,317 @@
/*******************************************************************************************************
Programs for Arduino - Copyright of the author Stuart Robinson - 31/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 - 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.1"
#include <SPI.h> //the lora device is SPI based so load the SPI library
#include <SX126XLT.h> //include the appropriate library
#include "Settings.h" //include the setiings file, frequencies, LoRa settings etc
#include <ProgramLT_Definitions.h>
SX126XLT 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[34]; //buffer where counts of received packets are stored, -9dbm to +22dBm
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+9]);
Test1Count[lTXpower+9] = 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 = 31; index >= 0; index--)
{
Serial.print(index-9);
Serial.print(F("dBm,"));
j = Test1Count[index];
Serial.print(j);
Serial.print(F(" "));
}
Serial.println();
Serial.print(F("CSV"));
for (index = 31; 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, 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, Optimisation);
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();
}

View File

@@ -0,0 +1,42 @@
/*******************************************************************************************************
Programs for Arduino - Copyright of the author Stuart Robinson - 31/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.
*******************************************************************************************************/
//******* 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 pin on LoRa device
#define NRESET 9 //reset pin on LoRa device
#define LED1 8 //on board LED, high for on
#define RFBUSY 7 //SX126X busy pin
#define DIO1 3 //DIO1 pin on LoRa device, used for RX and TX done
#define BUZZER -1 //pin for buzzer, set to -1 if not used
#define LORA_DEVICE DEVICE_SX1262 //this is the device we are using
//******* Setup LoRa Parameters Here ! ***************
//LoRa Modem Parameters
const uint32_t Frequency = 434000000; //frequency of transmissions
const uint32_t Offset = 0; //offset frequency for calibration purposes
const uint8_t Bandwidth = LORA_BW_125; //LoRa bandwidth
const uint8_t SpreadingFactor = LORA_SF7; //LoRa spreading factor
const uint8_t CodeRate = LORA_CR_4_5; //LoRa coding rate
const uint8_t Optimisation = LDRO_AUTO; //low data rate optimisation setting, normally set to auto
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

View File

@@ -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 <SX126XLT.h> //include the appropriate library
#include "Settings.h" //include the setiings file, frequencies, LoRa settings etc
SX126XLT 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, SW, 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, Optimisation);
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(0x00, 0x4F); //print contents of device registers
Serial.println();
Serial.println();
Serial.print(F("Receiver ready - RXBUFFER_SIZE "));
Serial.println(RXBUFFER_SIZE);
Serial.println();
}

View File

@@ -0,0 +1,48 @@
/*******************************************************************************************************
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 DIO1,
//DIO2, 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 //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 //SX126X 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 SW -1 //SW pin on Dorji devices is used to turn RF switch on\off, set to -1 if not used
#define RX_EN -1 //pin for RX enable, used on some SX126X devices, set to -1 if not used
#define TX_EN -1 //pin for TX enable, used on some SX126X devices, set to -1 if not used
#define BUZZER -1 //pin for buzzer, set to -1 if not used
#define LORA_DEVICE DEVICE_SX1262 //we need to define the device we are using
//******* Setup LoRa Parameters Here ! ***************
//LoRa Modem Parameters
const uint32_t Frequency = 434000000; //frequency of transmissions in hertz
const uint32_t Offset = 0; //offset frequency for calibration purposes
const uint8_t Bandwidth = LORA_BW_125; //LoRa bandwidth
const uint8_t SpreadingFactor = LORA_SF7; //LoRa spreading factor
const uint8_t CodeRate = LORA_CR_4_5; //LoRa coding rate
const uint8_t Optimisation = LDRO_AUTO; //low data rate optimisation setting, normally set to auto
const int8_t TXpower = 2; //LoRa transmit power in dBm
const uint16_t packet_delay = 1000; //mS delay between packets
#define RXBUFFER_SIZE 255 //RX buffer size

View File

@@ -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;
SX1262,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 <SX126XLT.h> //include the appropriate library
#include <ProgramLT_Definitions.h>
#include "Settings.h" //include the setiings file, frequencies, LoRa settings etc
SX126XLT 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, Optimisation);
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();
}

View File

@@ -0,0 +1,43 @@
/*******************************************************************************************************
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 //DIO1 pin on LoRa device, used for RX and TX done
#define LORA_DEVICE DEVICE_SX1262 //we need to define the device we are using
//******* Setup LoRa Parameters Here ! ***************
//LoRa Modem Parameters
const uint32_t Frequency = 434000000; //frequency of transmissions in hertz
const uint32_t Offset = 0; //offset frequency for calibration purposes
const uint8_t Bandwidth = LORA_BW_500; //LoRa bandwidth
const uint8_t SpreadingFactor = LORA_SF5; //LoRa spreading factor
const uint8_t CodeRate = LORA_CR_4_5; //LoRa coding rate
const uint8_t Optimisation = LDRO_AUTO; //low data rate optimisation setting, normally set to auto
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 = 4; //length of packet to send
const bool waitforACK = false; //set to true to have transmit wait for ack before continuing

View File

@@ -0,0 +1,252 @@
/*******************************************************************************************************
Programs for Arduino - Copyright of the author Stuart Robinson - 02/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 - 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 and save to SD card 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.
There will be a limit to how fast the logger can receive packets, mainly caused by the delay in writing
to SD card, so at high packet rates, packets will be lost.
Serial monitor baud rate is set at 9600.
*******************************************************************************************************/
#define Program_Version "V1.0"
#include <SPI.h>
#include <SdFat.h> //https://github.com/greiman/SdFat
SdFat SD;
File logFile;
char filename[] = "Log000.txt";
boolean SD_Found = false; //set if SD card found at program startup
uint8_t lognumber;
#include <SX126XLT.h>
SX126XLT LT;
#include "Settings.h"
#include <TimeLib.h> //get the library here; https://github.com/PaulStoffregen/Time
uint32_t RXpacketCount; //count of good packets
uint32_t errors; //count of packet 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
uint16_t IRQStatus; //used to read the IRQ status
int32_t FreqErrror; //frequency error of received packet, in hz
time_t recordtime; //used to record the current time, preventing displayed rollover on printing
uint8_t RXBUFFER[RXBUFFER_SIZE]; //create the buffer that received packets are copied into
#include "SD_Logger_Library.h"
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
recordtime = now(); //stop the time to be displayed rolling over
printtime();
printtimeSD();
PacketRSSI = LT.readPacketRSSI();
PacketSNR = LT.readPacketSNR();
FreqErrror = LT.getFrequencyErrorHz();
IRQStatus = LT.readIrqStatus();
if (RXPacketL == 0)
{
packet_is_Error();
packet_is_ErrorSD();
}
else
{
packet_is_OK();
packet_is_OKSD();
}
digitalWrite(LED1, LOW);
if (BUZZER > 0)
{
delay(50); //lets have a slightly longer beep
digitalWrite(BUZZER, LOW);
}
Serial.println();
}
void packet_is_OK()
{
RXpacketCount++;
if (BUZZER > 0)
{
digitalWrite(BUZZER, HIGH);
}
Serial.print(F(" FreqErrror,"));
Serial.print(FreqErrror);
Serial.print(F("hz "));
LT.printHEXPacket(RXBUFFER, RXPacketL);
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()
{
RXPacketL = LT.readRXPacketL(); //get the real packet length
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(RXPacketL);
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("60_LoRa_Packet_Logger_Receiver_SD 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, SW, 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);
}
}
lognumber = setup_SDLOG() ; //setup SD card
Serial.print(F("Lognumber "));
Serial.println(lognumber);
LT.setupLoRa(Frequency, Offset, SpreadingFactor, Bandwidth, CodeRate, Optimisation);
Serial.println();
LT.printModemSettings();
Serial.println();
printModemSettingsSD();
logFile.println();
LT.printOperatingSettings();
Serial.println();
printOperatingSettingsSD();
logFile.println();
printtime();
Serial.print(F(" Receiver ready"));
Serial.println();
}

View File

@@ -0,0 +1,346 @@
//SD_Logger_Library.h
/*******************************************************************************************************
Programs for Arduino - Copyright of the author Stuart Robinson - 02/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.
*******************************************************************************************************/
void printModemSettingsSD();
void printOperatingSettingsSD();
void printOperatingModeSD(uint8_t opmode);
uint8_t setup_SDLOG();
void printDeviceSD();
void printSXBufferHEXSD(uint8_t start, uint8_t end);
void printHEXByteSD(uint8_t temp);
void packet_is_OKSD();
void packet_is_ErrorSD();
void printDigitsSD(int8_t digits);
void printtimeSD();
void printModemSettingsSD()
{
uint8_t regdata;
uint8_t sf;
uint32_t bandwidth;
uint8_t cr;
uint8_t opt;
uint16_t syncword;
uint8_t invertIQ;
uint16_t preamble;
uint32_t freqint;
//get al the data frome the lora device in one go to avoid swapping
//devices on the SPI bus all the time
regdata = LT.readsavedModParam2();
bandwidth = LT.returnBandwidth(regdata);
freqint = LT.getFreqInt();sf = LT.getLoRaSF();
cr = (LT.getLoRaCodingRate() + 4);
opt = LT.getOptimisation();
syncword = LT.getSyncWord();
invertIQ = LT.getInvertIQ();
preamble = LT.getPreamble();
printDeviceSD();
logFile.print(F(","));
logFile.print(freqint);
logFile.print(F("hz,SF"));
logFile.print(sf);
logFile.print(F(",BW"));
logFile.print(bandwidth);
logFile.print(F(",CR4:"));
logFile.print(cr);
logFile.print(F(",LDRO_"));
if (opt)
{
logFile.print(F("On"));
}
else
{
logFile.print(F("Off"));
}
logFile.print(F(",SyncWord_0x"));
logFile.print(syncword, HEX);
if (invertIQ == LORA_IQ_INVERTED)
{
logFile.print(F(",IQInverted"));
}
else
{
logFile.print(F(",IQNormal"));
}
logFile.print(F(",Preamble_"));
logFile.print(preamble);
logFile.flush();
}
void printOperatingSettingsSD()
{
//get al the data frome the lora device in one go to avoid swapping
//devices on the SPI bus all the time
uint8_t pm = LT.getPacketMode();
uint8_t hm = LT.getHeaderMode();
uint8_t crcm = LT.getCRCMode();
uint8_t lnag = LT.getLNAgain();
uint8_t opmode = LT.getOpmode();
printDeviceSD();
printOperatingModeSD(opmode);
logFile.print(F(",PacketMode_"));
if (pm)
{
logFile.print(F("LoRa"));
}
else
{
logFile.print(F("FSK"));
}
if (hm)
{
logFile.print(F(",Implicit"));
}
else
{
logFile.print(F(",Explicit"));
}
logFile.print(F(",CRC_"));
if (crcm)
{
logFile.print(F("On"));
}
else
{
logFile.print(F("Off"));
}
logFile.print(F(",LNAgain_"));
logFile.print(lnag);
logFile.flush();
}
void printOperatingModeSD(uint8_t opmode)
{
switch (opmode)
{
case 0:
logFile.print(F("SLEEP"));
break;
case 1:
logFile.print(F("STDBY"));
break;
case 2:
logFile.print(F("FSTX"));
break;
case 3:
logFile.print(F("TX"));
break;
case 4:
logFile.print(F("FSRX"));
break;
case 5:
logFile.print(F("RXCONTINUOUS"));
break;
case 6:
logFile.print(F("RXSINGLE"));
break;
case 7:
logFile.print(F("CAD"));
break;
default:
logFile.print(F("NOIDEA"));
break;
}
}
uint8_t setup_SDLOG()
{
//checks if the SD card is present and can be initialised
//returns log number, 1-99, if OK, 0 if not
uint8_t i;
Serial.print(F("SD card..."));
if (!SD.begin(SDCS))
{
Serial.println(F("ERROR SD card fail"));
Serial.println();
SD_Found = false;
return 0;
}
Serial.print(F("Initialized OK - "));
SD_Found = true;
for (i = 1; i < 100; i++) {
filename[4] = i / 10 + '0';
filename[5] = i % 10 + '0';
if (! SD.exists(filename)) {
// only open a new file if it doesn't exist
logFile = SD.open(filename, FILE_WRITE);
break;
}
}
Serial.print(F("Writing to "));
Serial.println(filename);
return i;
}
void printDeviceSD()
{
switch (LORA_DEVICE)
{
case DEVICE_SX1261:
logFile.print(F("SX1261"));
break;
case DEVICE_SX1262:
logFile.print(F("SX1262"));
break;
case DEVICE_SX1268:
logFile.print(F("SX1268"));
break;
default:
logFile.print(F("Unknown Device"));
}
}
void printHEXPacketSD(uint8_t *buffer, uint8_t size)
{
uint8_t index;
for (index = 0; index < size; index++)
{
printHEXByteSD(buffer[index]);
logFile.print(F(" "));
}
}
void printHEXByteSD(uint8_t temp)
{
if (temp < 0x10)
{
logFile.print(F("0"));
}
logFile.print(temp, HEX);
}
void packet_is_OKSD()
{
//uint16_t IRQStatus;
IRQStatus = LT.readIrqStatus();
if (BUZZER > 0)
{
digitalWrite(BUZZER, HIGH);
}
logFile.print(F(" FreqErrror,"));
logFile.print(LT.getFrequencyErrorHz());
logFile.print(F("hz "));
printHEXPacketSD(RXBUFFER, RXPacketL);
logFile.print(F(" RSSI,"));
logFile.print(PacketRSSI);
logFile.print(F("dBm,SNR,"));
logFile.print(PacketSNR);
logFile.print(F("dB,Length,"));
logFile.print(RXPacketL);
logFile.print(F(",Packets,"));
logFile.print(RXpacketCount);
logFile.print(F(",Errors,"));
logFile.print(errors);
logFile.print(F(",IRQreg,"));
logFile.println(IRQStatus, HEX);
logFile.flush();
}
void packet_is_ErrorSD()
{
//uint16_t IRQStatus;
IRQStatus = LT.readIrqStatus(); //get the IRQ status
RXPacketL = LT.readRXPacketL(); //get the real packet length
if (IRQStatus & IRQ_RX_TIMEOUT)
{
logFile.print(F(" RXTimeout"));
}
else
{
logFile.print(F(" PacketError"));
logFile.print(F(",RSSI,"));
logFile.print(PacketRSSI);
logFile.print(F("dBm,SNR,"));
logFile.print(PacketSNR);
logFile.print(F("dB,Length,"));
logFile.print(RXPacketL);
logFile.print(F(",Packets,"));
logFile.print(RXpacketCount);
logFile.print(F(",Errors,"));
logFile.print(errors);
logFile.print(F(",IRQreg,"));
logFile.println(IRQStatus, HEX);
}
logFile.flush();
}
void printDigitsSD(int8_t digits)
{
//utility function for digital clock display: prints preceding colon and leading 0
logFile.print(F(":"));
if (digits < 10)
logFile.print('0');
logFile.print(digits);
}
void printtimeSD()
{
logFile.print(hour(recordtime));
printDigitsSD(minute(recordtime));
printDigitsSD(second(recordtime));
}

View File

@@ -0,0 +1,41 @@
/*******************************************************************************************************
Programs for Arduino - Copyright of the author Stuart Robinson - 02/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, An ATmeag1284P shield base for my BBF modules.
//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 //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 //SX126X busy pin
#define DIO1 3 //DIO1 pin 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 BUZZER 4 //pin for buzzer, on when logic high
#define SDCS 30 //CS pin for SD card
#define LORA_DEVICE DEVICE_SX1262 //we need to define the device we are using
//******* Setup LoRa Test Parameters Here ! ***************
//LoRa Modem Parameters
const uint32_t Frequency = 434000000; //frequency of transmissions
const uint32_t Offset = 0; //offset frequency for calibration purposes
const uint8_t Bandwidth = LORA_BW_125; //LoRa bandwidth
const uint8_t SpreadingFactor = LORA_SF7; //LoRa spreading factor
const uint8_t CodeRate = LORA_CR_4_5; //LoRa coding rate
const uint8_t Optimisation = LDRO_AUTO; //low data rate optimisation setting
const int8_t TXpower = 2; //LoRa TX power
#define packet_delay 1000 //mS delay between packets
#define RXBUFFER_SIZE 255 //RX buffer size