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,112 @@
/*******************************************************************************************************
Programs for Arduino - Copyright of the author Stuart Robinson - 26/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.
*******************************************************************************************************/
/*******************************************************************************************************
Program Operation - This program tests the deep sleep mode and wakeup with a switch of an Atmel 328P or
1284P processor. The program starts, flashes the LED and then puts the processor into permanent sleep.
It can be woken up with a switch press. Used as a base test routine for checking the sleep current of
a board.
Tested on a 'bare bones' ATmega328P board, the current in sleep mode was 1.7uA with a 3.3V MCP1700
regulator being used.
Serial monitor baud rate is set at 9600.
*******************************************************************************************************/
#define Program_Version "V1.0"
#include <avr/sleep.h>
#define LED1 8 //on board LED, high for on
#define SWITCH1 2 //switch used to wake processor up, switch pin connected to
//ground to activate. Define as -1 if switch not used.
uint32_t sleeps;
void loop()
{
digitalWrite(LED1, HIGH);
delay(2000);
sleeps++;
Serial.print(sleeps);
Serial.println(F(" Sleeping zzzzz...."));
Serial.println();
Serial.flush(); //make sure serial out buffer is empty
digitalWrite(LED1, LOW);
attachInterrupt(digitalPinToInterrupt(SWITCH1), wakeUp, FALLING); //This is a hardware interrupt
sleep_permanent(); //goto sleep till woken up by switch press
detachInterrupt(digitalPinToInterrupt(SWITCH1));
Serial.println(F("Awake !"));
digitalWrite(LED1, HIGH);
}
void sleep_permanent()
{
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();
}
void wakeUp()
{
//handler for the interrupt
}
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(SWITCH1, INPUT_PULLUP); //setup switch pin, ground to activate
pinMode(LED1, OUTPUT); //setup pin as output for indicator LED
led_Flash(2, 125); //two quick LED flashes to indicate program start
pinMode(SWITCH1, INPUT_PULLUP); //setup switch pin, connect to ground to activate
Serial.begin(9600);
Serial.println();
Serial.print(__TIME__);
Serial.print(F(" "));
Serial.println(__DATE__);
Serial.println(F(Program_Version));
Serial.println();
Serial.println(F("12_ATmel_Sleep_with_Switch_Wakeup Starting"));
}

View File

@@ -0,0 +1,46 @@
/*******************************************************************************************************
Programs for Arduino - Copyright of the author Stuart Robinson - 24/12/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 program to test a GPS. It reads characters from the GPS using
software serial and sends them (echoes) to the IDE serial monitor. If your ever having problems with
a GPS (or just think you are) use this program first.
If you get no data displayed on the serial monitor, the most likely cause is that you have the receive
data pin into the Arduino (RX) pin connected incorrectly.
GPS baud rate set at 9600 baud, Serial monitor set at 115200 baud. If the data displayed on the serial
terminal appears to be random text with odd symbols its very likely you have the GPS serial baud rate
set incorrectly for the GPS.
Note that not all pins on all Arduinos will work with software serial, see here;
https://www.arduino.cc/en/Reference/softwareSerial
Serial monitor baud rate is set at 115200.
*******************************************************************************************************/
#define RXpin A3 //this is the pin that the Arduino will use to receive data from the GPS
#define TXpin A2 //this is the pin that the Arduino can use to send data (commands) to the GPS - not used
#include <SoftwareSerial.h>
SoftwareSerial GPS(RXpin, TXpin);
void loop()
{
while (GPS.available())
{
Serial.write(GPS.read());
}
}
void setup()
{
GPS.begin(9600);
Serial.begin(115200);
Serial.println("GPS_Echo Starting");
}

View File

@@ -0,0 +1,43 @@
/*******************************************************************************************************
Programs for Arduino - Copyright of the author Stuart Robinson - 14/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.
*******************************************************************************************************/
/*******************************************************************************************************
Program Operation - This is a simple program to test a GPS. It reads characters from the GPS using
a hardware serial port, set to Serial1 as default, and then sends them (echoes) to the Arduino IDE
serial monitor. If your ever having problems with a GPS (or just think you are) use this program first.
If you get no data displayed on the serial monitor, the most likely cause is that you have the receive
data pin into the Arduino (RX) pin connected incorrectly.
At program start you should see '26A_GPS_Echo_Hardware_Serial Starting' in the serial monitor, if you
dont the serial monitor baud rate is probably incorrectly set. If you then see data displayed on the
serial terminal which appears to be random text with odd symbols its very likely you have the GPS
serial baud rate set incorrectly.
Change 'Serial1' in the program to match the hardware serial port you are using, for an Arduino Mega
this would normally be Serial1, Serila2 or Serial3.
Serial monitor baud rate is set at 115200.
*******************************************************************************************************/
void loop()
{
while (Serial3.available())
{
Serial.write(Serial3.read());
}
}
void setup()
{
Serial3.begin(9600);
Serial.begin(115200);
Serial.println();
Serial.println("26B_GPS_Echo_Hardware_Serial Starting");
}

View File

@@ -0,0 +1,45 @@
/*******************************************************************************************************
Programs for Arduino - Copyright of the author Stuart Robinson - 14/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.
*******************************************************************************************************/
/*******************************************************************************************************
Program Operation - This is a simple program to test a UBLOX GPS. It reads characters from the GPS using
the I2C interface and sends them (echoes) to the IDE serial monitor. If your ever having problems with a
GPS (or just think you are) use this program first.
Serial monitor baud rate is set at 115200.
*******************************************************************************************************/
#include <Wire.h>
const uint16_t GPSI2CAddress = 0x42;
void loop()
{
uint8_t GPSByte;
do
{
Wire.requestFrom(GPSI2CAddress, 1);
GPSByte = Wire.read();
if (GPSByte != 0xFF)
{
Serial.write(GPSByte);
}
}
while (true);
}
void setup()
{
Wire.begin();
Serial.begin(115200);
Serial.println();
Serial.println("26C_GPS_Echo_UBLOXI2C Starting");
}

View File

@@ -0,0 +1,48 @@
/*******************************************************************************************************
Programs for Arduino - Copyright of the author Stuart Robinson - 14/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.
*******************************************************************************************************/
/*******************************************************************************************************
Program Operation - This is a simple program to test a GPS. It reads characters from the GPS using
software serial and sends them (echoes) to the IDE serial monitor. If your ever having problems with
a GPS (or just think you are) use this program first.
If you get no data displayed on the serial monitor, the most likely cause is that you have the receive
data pin into the Arduino (RX) pin connected incorrectly.
If the data displayed on the serial terminal appears to be random text with odd symbols its very
likely you have the GPS serial baud rate set incorrectly.
Note that not all pins on all Arduinos will work with software serial, see here;
https://www.arduino.cc/en/Reference/softwareSerial
Serial monitor baud rate is set at 115200.
*******************************************************************************************************/
#define RXpin A3 //this is the pin that the Arduino will use to receive data from the GPS
#define TXpin A2 //this is the pin that the Arduino can use to send data (commands) to the GPS - not used
#include <SoftwareSerial.h>
SoftwareSerial GPS(RXpin, TXpin);
void loop()
{
while (GPS.available())
{
Serial.write(GPS.read());
}
}
void setup()
{
GPS.begin(9600);
Serial.begin(115200);
Serial.println("26_GPS_Echo Starting");
}

View File

@@ -0,0 +1,272 @@
/*******************************************************************************************************
Programs for Arduino - Copyright of the author Stuart Robinson - 24/12/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 portable GPS checker. It reads the GPS for 5 seconds and copies
the characters from the GPS to the serial monitor, this is an example printout from a working GPS that
has just been powered on;
28_GPS_Checker Starting
Wait GPS Fix 5 seconds
Timeout - No GPS Fix 5s
Wait GPS Fix 5 seconds
$PGACK,103*40
$PGACK,105*46
$PMTK011,MTKGPS*08
$PMTK010,001*2E
$PMTK010,00æ*2D
$GPGGA,235942.800,,,,,0,0,,,M,,M,,*4B
$GPGSA,A,1,,,,,,,,,,,,,,,*1E
$GPRMC,235942.800,V,,,,,0.00,0.00,050180,,,N*42
$GPVTG,0.00,T,,M,0.00,N,0.00,K,N*32
$GPGSV,1,1,03,30,,,43,07,,,43,05,,,38*70
Timeout - No GPS Fix 5s
Wait GPS Fix 5 seconds
That printout is from a Meadiatek GPS, the Ublox ones are similar. The data from the GPS is also fed into
the TinyGPS++ library and if there is no fix a message is printed on the serial monitor.
When the program detects that the GPS has a fix, it prints the Latitude, Longitude, Altitude, Number
of satellites in use, the HDOP value, time and date 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; '#define GPSPOWER -1' from -1 to the pin number
being used. Also set the GPSONSTATE and GPSOFFSTATE to the appropriate logic levels.
There is a set of GPS co-ordinates defined, TestLatitude and TestLongitude, when the GPS has its location
fix the distance and direction to the Test location is calculated and shown on the serial monitor.
Serial monitor baud rate is set at 115200.
*******************************************************************************************************/
#define Program_Version "V1.2"
#define authorname "Stuart Robinson"
#include <TinyGPS++.h> //get library here > http://arduiniana.org/libraries/tinygpsplus/
TinyGPSPlus gps; //create the TinyGPS++ object
#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 //pin number for LED, turns on when printing Fix data
#define GPSPOWER -1 //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
#include <SoftwareSerial.h>
SoftwareSerial GPSserial(RXpin, TXpin);
float GPSLat; //Latitude from GPS
float GPSLon; //Longitude from GPS
float GPSAlt; //Altitude from GPS
uint8_t GPSSats; //number of GPS satellites in use
uint32_t GPSHdop; //HDOP from GPS
uint8_t hours, mins, secs, day, month;
uint16_t year;
uint32_t startGetFixmS;
uint32_t endFixmS;
//GPS co-ordinates to use for the test location transmission
const float TestLatitude = 51.48230; //Cardiff castle keep, used for location testing purposes
const float TestLongitude = -3.18136;
void loop()
{
if (gpsWaitFix(5))
{
digitalWrite(LED1, HIGH); //LED on to indicate fix
Serial.println();
Serial.println();
Serial.print(F("Fix time "));
Serial.print(endFixmS - startGetFixmS);
Serial.println(F("mS"));
GPSLat = gps.location.lat();
GPSLon = gps.location.lng();
GPSAlt = gps.altitude.meters();
GPSSats = gps.satellites.value();
GPSHdop = gps.hdop.value();
hours = gps.time.hour();
mins = gps.time.minute();
secs = gps.time.second();
day = gps.date.day();
month = gps.date.month();
year = gps.date.year();
printGPSfix();
startGetFixmS = millis(); //have a fix, next thing that happens is checking for a fix, so restart timer
digitalWrite(LED1, LOW);
}
else
{
Serial.println();
Serial.println();
Serial.print(F("Timeout - No GPS Fix "));
Serial.print( (millis() - startGetFixmS) / 1000 );
Serial.println(F("s"));
}
}
bool gpsWaitFix(uint16_t waitSecs)
{
//waits a specified number of seconds for a fix, returns true for updated fix
uint32_t startmS, waitmS;
uint8_t GPSchar;
Serial.print(F("Wait GPS Fix "));
Serial.print(waitSecs);
Serial.println(F(" seconds"));
waitmS = waitSecs * 1000; //convert seconds wait into mS
startmS = millis();
while ( (uint32_t) (millis() - startmS) < waitmS) //allows for millis() overflow
{
if (GPSserial.available() > 0)
{
GPSchar = GPSserial.read();
gps.encode(GPSchar);
Serial.write(GPSchar);
}
if (gps.location.isUpdated() && gps.altitude.isUpdated() && gps.date.isUpdated())
{
endFixmS = millis(); //record the time when we got a GPS fix
return true;
}
}
return false;
}
void printGPSfix()
{
float tempfloat;
uint32_t distance;
uint16_t direction;
Serial.print(F("New GPS Fix "));
tempfloat = ( (float) GPSHdop / 100);
Serial.print(F("Lat,"));
Serial.print(GPSLat, 6);
Serial.print(F(",Lon,"));
Serial.print(GPSLon, 6);
Serial.print(F(",Alt,"));
Serial.print(GPSAlt, 1);
Serial.print(F("m,Sats,"));
Serial.print(GPSSats);
Serial.print(F(",HDOP,"));
Serial.print(tempfloat, 2);
Serial.print(F(",Time,"));
if (hours < 10)
{
Serial.print(F("0"));
}
Serial.print(hours);
Serial.print(F(":"));
if (mins < 10)
{
Serial.print(F("0"));
}
Serial.print(mins);
Serial.print(F(":"));
if (secs < 10)
{
Serial.print(F("0"));
}
Serial.print(secs);
Serial.print(F(",Date,"));
Serial.print(day);
Serial.print(F("/"));
Serial.print(month);
Serial.print(F("/"));
Serial.print(year);
distance = gps.distanceBetween(GPSLat, GPSLon, TestLatitude, TestLongitude);
direction = gps.courseTo(GPSLat, GPSLon, TestLatitude, TestLongitude);
Serial.println();
Serial.print(F("Distance to Test Location ("));
Serial.print(TestLatitude, 6);
Serial.print((","));
Serial.print(TestLongitude, 6);
Serial.print((") "));
Serial.print(distance);
Serial.print(("m"));
Serial.println();
Serial.print(F("Direction to Test Location ("));
Serial.print(TestLatitude, 6);
Serial.print((","));
Serial.print(TestLongitude, 6);
Serial.print((") "));
Serial.print(direction);
Serial.print(("d"));
Serial.println();
Serial.println();
}
void GPSON()
{
if (GPSPOWER)
{
digitalWrite(GPSPOWER, GPSONSTATE); //power up GPS
}
}
void GPSOFF()
{
if (GPSPOWER)
{
digitalWrite(GPSPOWER, GPSOFFSTATE); //power off GPS
}
}
void setup()
{
pinMode(LED1, OUTPUT);
if (GPSPOWER >= 0)
{
pinMode(GPSPOWER, OUTPUT);
GPSON();
}
GPSserial.begin(9600);
Serial.begin(115200);
Serial.println();
Serial.print(F(__TIME__));
Serial.print(F(" "));
Serial.println(F(__DATE__));
Serial.println(F(Program_Version));
Serial.println();
Serial.println(F("28_GPS_Checker Starting"));
Serial.println();
startGetFixmS = millis();
}

View File

@@ -0,0 +1,335 @@
/*******************************************************************************************************
Programs for Arduino - Copyright of the author Stuart Robinson - 29/12/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 portable GPS checker with display option. It uses an SSD1306 or
SH1106 128x64 I2C OLED display. The program reads the GPS for 5 seconds checking for a fix and copies
the characters from the GPS to the serial monitor so you can see if the GPS is working. This is an example
printout from a working GPS with the program having been just been powered on;
29_GPS_Checker_Display Starting
Wait GPS Fix 5 seconds
$GPGGA,235945.020,,,,,0,0,,,M,,M,,*46
$GPGLL,,,,,235945.020,V,N*74
$GPGSA,A,1,,,,,,,,,,,,,,,*1E
$GPGSV,1,1,01,11,,,33*78
$GPRMC,235945.020,V,,,,,0.00,0.00,050180,,,N*4F
$GPVTG,0.00,T,,M,0.00,N,0.00,K,N*32
$GPGGA,235946.020,,,,,0,0,,,M,,M,,*45
$GPGLL,,,,,235946.020,V,N*77
$GPGSA,A,1,,,,,,,,,,,,,,,*1E
$GPGSV,1,1,02,22,,,36,11,,,33*7E
$GPRMC,235946.020,V,,,,,0.00,0.00,050180,,,N*4C
Timeout - No GPS Fix 5s
Wait GPS Fix 5 seconds
That printout is from a Meadiatek GPS, the Ublox ones are similar. The data from the GPS is also fed into
the TinyGPS++ library and if there is no fix a message is printed on the serial monitor.
When the program detects that the GPS has a fix, it prints the Latitude, Longitude, Altitude, Speed, Number
of satellites in use, the HDOP value, time and date to the serial monitor. If the I2C OLED display is
attached that is updated as well. Display is assumed to be on I2C address 0x3C.
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; '#define GPSPOWER -1' from -1 to the pin number
being used. Also set the GPSONSTATE and GPSOFFSTATE to the appropriate logic levels.
Serial monitor baud rate is set at 115200.
Changes:
290920 - Add speed to serial monitor output and display
*******************************************************************************************************/
#define Program_Version "V1.2"
#define authorname "Stuart Robinson"
#include <TinyGPS++.h> //get library here > http://arduiniana.org/libraries/tinygpsplus/
TinyGPSPlus gps; //create the TinyGPS++ object
#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 -1 //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
#include <SoftwareSerial.h>
SoftwareSerial GPSserial(RXpin, TXpin);
#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
#define DEFAULTFONT u8x8_font_chroma48medium8_r //font used by U8X8 Library
float GPSLat; //Latitude from GPS
float GPSLon; //Longitude from GPS
float GPSAlt; //Altitude from GPS
uint8_t GPSSats; //number of GPS satellites in use
uint32_t GPSHdop; //HDOP from GPS
float GPSSpeed; //Speed of GPS, mph
uint8_t hours, mins, secs, day, month;
uint16_t year;
uint32_t startGetFixmS;
uint32_t endFixmS;
void loop()
{
if (gpsWaitFix(5))
{
Serial.println();
Serial.println();
Serial.print(F("Fix time "));
Serial.print(endFixmS - startGetFixmS);
Serial.println(F("mS"));
GPSLat = gps.location.lat();
GPSLon = gps.location.lng();
GPSAlt = gps.altitude.meters();
GPSSats = gps.satellites.value();
GPSHdop = gps.hdop.value();
GPSSpeed = gps.speed.mph();
hours = gps.time.hour();
mins = gps.time.minute();
secs = gps.time.second();
day = gps.date.day();
month = gps.date.month();
year = gps.date.year();
printGPSfix(); //print GPS data to serial monitor
displayscreen1(); //print GPS data on display
startGetFixmS = millis(); //have a fix, next thing that happens is checking for a fix, so restart timer
}
else
{
disp.clearLine(0);
disp.setCursor(0, 0);
disp.print(F("No GPS Fix "));
disp.print( (millis() - startGetFixmS) / 1000 );
Serial.println();
Serial.println();
Serial.print(F("Timeout - No GPS Fix "));
Serial.print( (millis() - startGetFixmS) / 1000 );
Serial.println(F("s"));
}
}
bool gpsWaitFix(uint16_t waitSecs)
{
//waits a specified number of seconds for a fix, returns true for updated fix
uint32_t startmS, waitmS;
uint8_t GPSchar;
Serial.print(F("Wait GPS Fix "));
Serial.print(waitSecs);
Serial.println(F(" seconds"));
//Serial.print(F("Current millis() "));
//Serial.println(millis());
waitmS = waitSecs * 1000; //convert seconds wait into mS
startmS = millis();
while ( (uint32_t) (millis() - startmS) < waitmS) //allows for millis() overflow
{
if (GPSserial.available() > 0)
{
GPSchar = GPSserial.read();
gps.encode(GPSchar);
Serial.write(GPSchar);
}
if (gps.location.isUpdated() && gps.altitude.isUpdated() && gps.date.isUpdated())
{
endFixmS = millis(); //record the time when we got a GPS fix
return true;
}
}
return false;
}
void printGPSfix()
{
float tempfloat;
Serial.print(F("New GPS Fix "));
tempfloat = ( (float) GPSHdop / 100);
Serial.print(F("Latitude,"));
Serial.print(GPSLat, 6);
Serial.print(F(",Longitude,"));
Serial.print(GPSLon, 6);
Serial.print(F(",Altitude,"));
Serial.print(GPSAlt, 1);
Serial.print(F("m,Speed,"));
Serial.print(GPSSpeed, 1);
Serial.print(F("mph,Sats,"));
Serial.print(GPSSats);
Serial.print(F(",HDOP,"));
Serial.print(tempfloat, 2);
Serial.print(F(",Time,"));
if (hours < 10)
{
Serial.print(F("0"));
}
Serial.print(hours);
Serial.print(F(":"));
if (mins < 10)
{
Serial.print(F("0"));
}
Serial.print(mins);
Serial.print(F(":"));
if (secs < 10)
{
Serial.print(F("0"));
}
Serial.print(secs);
Serial.print(F(",Date,"));
Serial.print(day);
Serial.print(F("/"));
Serial.print(month);
Serial.print(F("/"));
Serial.print(year);
Serial.println();
Serial.println();
}
void displayscreen1()
{
//show GPS data on display
float tempfloat;
tempfloat = ( (float) GPSHdop / 100);
disp.clearLine(0);
disp.setCursor(0, 0);
disp.print(GPSLat, 6);
disp.clearLine(1);
disp.setCursor(0, 1);
disp.print(GPSLon, 6);
disp.clearLine(2);
disp.setCursor(0, 2);
disp.print(GPSAlt,0);
disp.print(F("m"));
disp.clearLine(3);
disp.setCursor(0, 3);
disp.print(GPSSpeed,0);
disp.print(F("mph"));
disp.clearLine(4);
disp.setCursor(0, 4);
disp.print(F("Sats "));
disp.print(GPSSats);
disp.clearLine(5);
disp.setCursor(0, 5);
disp.print(F("HDOP "));
disp.print(tempfloat);
disp.clearLine(6);
disp.setCursor(0, 6);
if (hours < 10)
{
disp.print(F("0"));
}
disp.print(hours);
disp.print(F(":"));
if (mins < 10)
{
disp.print(F("0"));
}
disp.print(mins);
disp.print(F(":"));
if (secs < 10)
{
disp.print(F("0"));
}
disp.print(secs);
disp.print(F(" "));
disp.clearLine(7);
disp.setCursor(0, 7);
disp.print(day);
disp.print(F("/"));
disp.print(month);
disp.print(F("/"));
disp.print(year);
}
void GPSON()
{
if (GPSPOWER)
{
digitalWrite(GPSPOWER, GPSONSTATE); //power up GPS
}
}
void GPSOFF()
{
if (GPSPOWER)
{
digitalWrite(GPSPOWER, GPSOFFSTATE); //power off GPS
}
}
void setup()
{
if (GPSPOWER >= 0)
{
pinMode(GPSPOWER, OUTPUT);
GPSON();
}
GPSserial.begin(9600);
Serial.begin(115200);
Serial.println();
Serial.print(F(__TIME__));
Serial.print(F(" "));
Serial.println(F(__DATE__));
Serial.println(F(Program_Version));
Serial.println();
disp.begin();
disp.setFont(DEFAULTFONT);
disp.clear();
disp.setCursor(0, 0);
disp.print(F("Display Ready"));
Serial.println(F("29_GPS_Checker_With_Display Starting"));
Serial.println();
startGetFixmS = millis();
}

View File

@@ -0,0 +1,69 @@
// --------------------------------------
// i2c_scanner
// from: https://playground.arduino.cc/Main/I2cScanner/
// This sketch tests the standard 7-bit addresses
// Devices with higher bit address might not be seen properly.
#include <Wire.h>
uint16_t counter;
void setup()
{
Wire.begin();
Serial.begin(9600);
Serial.println(F("I2C Scanner starting"));
Serial.println();
}
void loop()
{
uint8_t error, address;
int16_t nDevices;
counter++;
Serial.print(counter);
Serial.println(F(" Scanning..."));
nDevices = 0;
for (address = 1; address < 127; address++ )
{
// The i2c_scanner uses the return value of
// the Write.endTransmisstion to see if
// a device did acknowledge to the address.
Wire.beginTransmission(address);
error = Wire.endTransmission();
if (error == 0)
{
Serial.print(F("I2C device found at address 0x"));
if (address < 16)
Serial.print(F("0"));
Serial.println(address, HEX);
nDevices++;
}
else if (error == 4)
{
Serial.print(F("Unknown error at address 0x"));
if (address < 16)
Serial.print(F("0"));
Serial.println(address, HEX);
}
}
if (nDevices == 0)
{
Serial.println(F("No I2C devices found"));
}
else
{
Serial.println();
Serial.println(F("Done"));
Serial.println();
}
delay(5000); // wait 5 seconds for next scan
}

View File

@@ -0,0 +1,122 @@
/*******************************************************************************************************
Programs for Arduino - Copyright of the author Stuart Robinson - 20/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.
*******************************************************************************************************/
/*******************************************************************************************************
Program Operation - This program is a simple test program for the SSD1306 and SH1106 OLEDs running on
a 3.3V 8Mhz bare bones ATmega328P. The program prints a short message on each line, pauses, clears the
screen, turns off the screem, puts the processor to sleep and starts again. Sleep current with display
off is circa 8uA.
OLED address defaults to 0x3C.
Screen write on 8Mhz Atmel 196mS.
Serial monitor baud rate is set at 9600.
*******************************************************************************************************/
#include <avr/sleep.h>
#include <avr/wdt.h>
#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
#define DEFAULTFONT u8x8_font_chroma48medium8_r //font for U8X8 Library
uint16_t writecount;
uint32_t startwritemS, endwritemS, timemS;
void loop()
{
writecount++;
Serial.print(writecount);
Serial.print(F(" Writing to display"));
startwritemS = millis();
disp.clear();
screen1();
endwritemS = millis();
timemS = endwritemS - startwritemS;
disp.setCursor(8, 4);
disp.print(timemS);
disp.print(F("mS"));
Serial.print(F(" - done "));
Serial.print(timemS);
Serial.println(F("mS"));
delay(2000);
Serial.println(F("PowerSave display"));
Serial.flush(); //pending serial output affects sleep mode
disp.setPowerSave(1); //power save display, turns off, sleep current circa 8uA
sleep1seconds(2); //sleep in units of 1 second
disp.setPowerSave(0); //display back to normal
}
void sleep1seconds(uint32_t sleeps)
{
uint32_t index;
for (index = 1; index <= sleeps; index++)
{
ADCSRA = 0; //disable ADC
MCUSR = 0; //clear various "reset" flags
WDTCSR = bit (WDCE) | bit (WDE); //allow changes, disable reset
WDTCSR = bit (WDIE) | bit (WDP2) | bit (WDP1); //set interrupt mode and an interval, set WDIE, and 1 seconds sleep
wdt_reset(); //pat the dog
set_sleep_mode (SLEEP_MODE_PWR_DOWN);
noInterrupts (); //timed sequence follows
sleep_enable();
MCUCR = bit (BODS) | bit (BODSE); //turn off brown-out enable in software
MCUCR = bit (BODS);
interrupts (); //guarantees next instruction executed
sleep_cpu ();
//awake here
sleep_disable(); //cancel sleep as a precaution
}
}
ISR (WDT_vect)
{
//watchdog interrupt
wdt_disable(); // disable watchdog
}
void screen1()
{
disp.setCursor(0, 0);
disp.print(F("Hello World !"));
disp.setCursor(0, 1);
disp.print(F("Line 1"));
disp.setCursor(0, 2);
disp.print(F("Line 2"));
disp.setCursor(0, 3);
disp.print(F("Line 3"));
disp.setCursor(0, 4);
disp.print(F("Line 4"));
disp.setCursor(0, 5);
disp.print(F("Line 5"));
disp.setCursor(0, 6);
disp.print(F("Line 6"));
disp.setCursor(0, 7);
disp.print(F("0123456789012345")); //display is 8 lines x 16 charaters when using the
}
void setup()
{
Serial.begin(9600);
Serial.println(F("31_SSD1306_SH1106_OLED_Checker starting"));
disp.begin();
disp.setFont(DEFAULTFONT);
}

View File

@@ -0,0 +1,153 @@
/*******************************************************************************************************
Programs for Arduino - Copyright of the author Stuart Robinson - 05/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 program is GPS Time checker. It reads the GPS NMEA output and displays the time
on the Arduino IDE serial monitor. If you have the serial monitor output on screen as the same time as
observing a web site displaying the current time you can check how close your GPS is reporting to real time.
At power up a GPS will not normally display the time accurate to the exact second until it receives the
navigation message that is the updated value of current leaps seconds which is sent out every 12.5 minutes.
Serial monitor baud rate is set at 115200.
*******************************************************************************************************/
#define Program_Version "V1.0"
#define authorname "Stuart Robinson"
#include <TinyGPS++.h> //get library here > http://arduiniana.org/libraries/tinygpsplus/
TinyGPSPlus gps; //create the TinyGPS++ object
#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 -1 //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
#include <SoftwareSerial.h>
SoftwareSerial GPSserial(RXpin, TXpin);
uint8_t hours, mins, secs;
void loop()
{
if (gpsWaitFix(5))
{
hours = gps.time.hour();
mins = gps.time.minute();
secs = gps.time.second();
printGPSfix();
}
else
{
Serial.println(F("Timeout - No GPS Fix "));
}
}
bool gpsWaitFix(uint16_t waitSecs)
{
//waits a specified number of seconds for a fix, returns true for updated fix
uint32_t endwaitmS;
uint8_t GPSchar;
endwaitmS = millis() + (waitSecs * 1000);
while (millis() < endwaitmS)
{
if (GPSserial.available() > 0)
{
GPSchar = GPSserial.read();
gps.encode(GPSchar);
//Serial.write(GPSchar);
}
if (gps.location.isUpdated() && gps.time.isUpdated())
{
return true;
}
}
return false;
}
void printGPSfix()
{
Serial.print(F("Time,"));
if (hours < 10)
{
Serial.print(F("0"));
}
Serial.print(hours);
Serial.print(F(":"));
if (mins < 10)
{
Serial.print(F("0"));
}
Serial.print(mins);
Serial.print(F(":"));
if (secs < 10)
{
Serial.print(F("0"));
}
Serial.print(secs);
Serial.println();
}
void GPSON()
{
if (GPSPOWER)
{
digitalWrite(GPSPOWER, GPSONSTATE); //power up GPS
}
}
void GPSOFF()
{
if (GPSPOWER)
{
digitalWrite(GPSPOWER, GPSOFFSTATE); //power off GPS
}
}
void setup()
{
if (GPSPOWER >= 0)
{
pinMode(GPSPOWER, OUTPUT);
GPSON();
}
GPSserial.begin(9600);
Serial.begin(115200);
Serial.println();
Serial.print(F(__TIME__));
Serial.print(F(" "));
Serial.println(F(__DATE__));
Serial.println(F(Program_Version));
Serial.println();
Serial.println(F("32_GPS_Checker_Time Starting"));
Serial.println();
}

View File

@@ -0,0 +1,109 @@
/*******************************************************************************************************
Programs for Arduino - Copyright of the author Stuart Robinson - 03/09/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 of an Atmel ATMega328P processor.
At power up the flashes an LED 4 times, then turns on the LED for 5 seconds. Then the processor is put
to sleep for 16 seconds. On wakeup the LED flashes twice, then is on for 2 seconds and the board goes to
sleep again. And the sequence repeats.
Sleep current for a 'bare bones' ATmega328 with a MCP1700 regulator @ 3.3V and using an external event
such as a switch to wakeup from sleep should be around 2uA. Using the watchdog timer to wakeup raises
the deep sleep current to circa 6.2uA.
Serial monitor baud rate is set at 9600.
*******************************************************************************************************/
//basic code from here - https://www.gammon.com.au/forum/?id=11497
#include <avr/sleep.h>
#include <avr/wdt.h>
#define LED1 8
void loop ()
{
Serial.println("LED Off");
digitalWrite(LED1, LOW);
digitalWrite(13, LOW);
Serial.println(F("Now Sleeping... "));
Serial.flush();
sleep8seconds(2); //sleep for about 16 seconds
Serial.println("Awake ");
led_Flash(2, 125);
Serial.println("LED On ");
digitalWrite(LED1, HIGH);
digitalWrite(13, HIGH);
delay(2000);
}
void sleep8seconds(uint32_t sleeps)
{
uint32_t index;
for (index = 1; index <= sleeps; index++)
{
ADCSRA = 0; //disable ADC
MCUSR = 0; //clear various "reset" flags
WDTCSR = bit (WDCE) | bit (WDE); //allow changes, disable reset
WDTCSR = bit (WDIE) | bit (WDP3) | bit (WDP0); //set interrupt mode and an interval, set WDIE, and 8 seconds delay
wdt_reset(); //pat the dog
set_sleep_mode (SLEEP_MODE_PWR_DOWN);
noInterrupts (); //timed sequence follows
sleep_enable();
MCUCR = bit (BODS) | bit (BODSE); //turn off brown-out enable in software
MCUCR = bit (BODS);
interrupts (); //guarantees next instruction executed
sleep_cpu ();
//awake here
sleep_disable(); //cancel sleep as a precaution
}
}
void led_Flash(uint16_t flashes, uint16_t delaymS)
{
uint16_t index;
for (index = 1; index <= flashes; index++)
{
digitalWrite(LED1, HIGH);
digitalWrite(13, HIGH);
delay(delaymS);
digitalWrite(LED1, LOW);
digitalWrite(13, LOW);
delay(delaymS);
}
}
void setup ()
{
pinMode(LED1, OUTPUT);
pinMode(13, OUTPUT);
Serial.begin(9600);
led_Flash(4, 125);
Serial.println("LED On ");
digitalWrite(LED1, HIGH);
digitalWrite(13, HIGH);
delay(5000);
}
ISR (WDT_vect)
{
//watchdog interrupt
wdt_disable(); // disable watchdog
}

View File

@@ -0,0 +1,78 @@
/*******************************************************************************************************
Programs for Arduino - Copyright of the author Stuart Robinson - 30/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.
*******************************************************************************************************/
/*******************************************************************************************************
Program Operation - This program sweeps two servos from one end of their travel to the other. Useful to
check servos are connected correctly and working.
Serial monitor baud rate is set at 9600.
*******************************************************************************************************/
#define pinservoX1 2 //pin for controlling servo X 1
#define pinservoY1 4 //pin for controlling servo Y 1
#define LED1 8
#include <Servo.h>
Servo ServoX1; //create the servo object
Servo ServoY1; //create the servo object
void loop()
{
uint16_t index;
for (index = 900; index <= 2100; index++)
{
//Serial.print(F("Microseconds1 "));
//Serial.println(index);
ServoX1.writeMicroseconds(index);
ServoY1.writeMicroseconds(index);
}
delay(1000);
for (index = 2100; index >= 900; index--)
{
//Serial.print(F("Microseconds1 "));
//Serial.println(index);
ServoX1.writeMicroseconds(index);
ServoY1.writeMicroseconds(index);
}
delay(1000);
}
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);
ServoX1.attach(pinservoX1); //using pin servoX for servo object
ServoY1.attach(pinservoY1); //using pin servoX for servo object
Serial.println(F("Servo sweep test starting"));
}

View File

@@ -0,0 +1,267 @@
/*******************************************************************************************************
Programs for Arduino - Copyright of the author Stuart Robinson - 04/06/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 test program has been written to check that a connected SD card adapter, Micro
or standard, is functional.
When the program runs it will attempts to create a file that is next in sequence to Log0000.txt, thus
if this is the first time the program has run on the SD card it will create file Log0001.txt. If the
file Log0001.txt exists it will create Log0002.txt etc. This ensures that everytime the program starts
it creates a new file for testing.
Next the program checks if the Logxxxx.txt file exists and if so attempts to delete it.
Then the program starts a loop. First the same file is again opened for append, it will be created if it
does not exist and then the line '1 Hello World' is writtent to the file. The file is closed and the
contents of the file are dumped to the serial monitor. The loop restarts, and this time the line
'2 Hello World' is appended to the file.
As the program progresses the file will grow in size and after 4 iterrations of the open,write,close
and dump loop the file dump on serial monitor will look like this
1 Hello World
2 Hello World
3 Hello World
4 Hello World
This file dump will grow if you let the program run. If an error with the SD card is detected at any
time the LED will rapid flash continuously and the message 'X Card failed, or not present' is printed
to serial monitor. The number X will allow you to check the program listing for where the error occured.
1 Card failed = SD card did not initialise
2 Card failed = Could nt setup logFile for new name
3 Card failed = Could not open file for append
4 Card failed = Failure to dump file to serial monitor
Serial monitor baud rate is set at 9600
*******************************************************************************************************/
#define Program_Version "V1.1"
#include <SD.h>
#include <SPI.h>
#define LED1 8 //pin number for LED
#define SDCS 4 //pin number for device select on SD card module
File logFile;
char filename[] = "/LOG0000.TXT"; //filename used as base for creating logfile, 0000 replaced with numbers
uint16_t linecount;
void loop()
{
Serial.println();
Serial.println("Initializing SD card");
if (!SD.begin(SDCS))
{
cardFail(1);
}
Serial.println("Card initialized");
logFile = SD.open("/");
Serial.println("Card directory");
Serial.println();
printDirectory(logFile, 0);
Serial.println();
Serial.println();
if (!setupSDLOG(filename)) //setup logfile name for writing
{
cardFail(2);
}
Serial.print(F("logFile name is "));
Serial.println(filename);
if (SD.exists(filename))
{
Serial.print(filename);
Serial.println(" exists - delete");
SD.remove(filename);
}
if (!SD.exists(filename))
{
Serial.print(filename);
Serial.println(" does not exist");
}
while (1)
{
logFile = SD.open(filename, FILE_WRITE);
if (!logFile)
{
cardFail(3);
}
linecount++;
logFile.print(linecount);
logFile.println(" Hello World");
logFile.close();
Serial.println();
Serial.print("Dump file ");
Serial.println(filename);
Serial.println();
digitalWrite(LED1, HIGH);
if (dumpFile(filename))
{
Serial.println();
Serial.println("Finished File Dump");
}
else
{
cardFail(4);
}
digitalWrite(LED1, LOW);
delay(2000);
}
}
void printDirectory(File dir, int numTabs)
{
while (true)
{
File entry = dir.openNextFile();
if (! entry)
{
//no more files
break;
}
for (uint8_t i = 0; i < numTabs; i++) {
Serial.print('\t');
}
Serial.print(entry.name());
if (entry.isDirectory())
{
Serial.println("/");
printDirectory(entry, numTabs + 1);
}
else
{
//files have sizes, directories do not
Serial.print("\t\t");
Serial.println(entry.size(), DEC);
}
entry.close();
}
}
bool dumpFile(char *buf)
{
if (SD.exists(buf))
{
Serial.print(buf);
Serial.println(" found");
}
else
{
Serial.print(filename);
Serial.println(" not found");
return false;
}
logFile = SD.open(buf);
if (logFile) //if the file is available, read from it
{
while (logFile.available())
{
Serial.write(logFile.read());
}
logFile.close();
return true;
}
return false;
}
uint8_t setupSDLOG(char *buf)
{
//creats a new filename
uint16_t index;
for (index = 1; index <= 9999; index++) {
buf[4] = index / 1000 + '0';
buf[5] = ((index % 1000) / 100) + '0';
buf[6] = ((index % 100) / 10) + '0';
buf[7] = index % 10 + '0' ;
if (! SD.exists(filename)) {
// only open a new file if it doesn't exist
logFile = SD.open(buf, FILE_WRITE);
break;
}
}
if (!logFile)
{
return 0;
}
return index; //return number of logfile created
}
void cardFail(uint8_t num)
{
while (1)
{
Serial.print(num); //so we can tell where card failed
Serial.println(" Card failed, or not present");
led_Flash(100, 25);
}
}
void led_Flash(unsigned int flashes, unsigned int delaymS)
{
unsigned int index;
for (index = 1; index <= flashes; index++)
{
digitalWrite(LED1, HIGH);
delay(delaymS);
digitalWrite(LED1, LOW);
delay(delaymS);
}
}
void setup()
{
pinMode(LED1, OUTPUT); //for PCB LED
led_Flash(4, 125);
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("43_SD_Card_Test Starting"));
}

View File

@@ -0,0 +1,115 @@
/*******************************************************************************************************
Programs for Arduino - Copyright of the author Stuart Robinson - 20/01/20
This program is supplied as is, it is up to the user of the program to decide if the program is
suitable for the intended purpose and free from errors.
*******************************************************************************************************/
/*******************************************************************************************************
Program Operation - This test program has been written to check that hardware for reading the battery
voltage has been assembled correctly such that it is funtional. The value defined as 'ADMultiplier'
in settings.h is used to adjust the value read from the 91K\11K resistor divider and convert into mV.
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
*******************************************************************************************************/
/*
******************************************************************************************************
Program operation -
******************************************************************************************************
*/
#define ADMultiplier 6.36 //adjustment to convert AD value read into mV of battery voltage
#define BATVREADON 8 //used to turn on the resistor divider to measure voltage, //this pin turns on the MOSFET that switches in the resistor divider
#define LED1 8 //pin for PCB LED
#define SupplyAD A0 //Resitor divider for battery connected here
void loop()
{
Serial.println(F("LED Flash"));
led_Flash(4, 125);
printSupplyVoltage();
Serial.println();
delay(1500);
}
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 printSupplyVoltage()
{
//get and display supply volts on terminal or monitor
Serial.print(F("Supply Volts "));
Serial.print(readSupplyVoltage());
Serial.println(F("mV"));
}
uint16_t readSupplyVoltage()
{
//relies on 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 MOSFET connection resitor divider in circuit
}
analogReference(INTERNAL);
temp = analogRead(SupplyAD);
for (index = 0; index <= 4; index++) //sample AD 5 times
{
temp = analogRead(SupplyAD);
volts = volts + temp;
}
volts = ((volts / 5) * ADMultiplier);
if (BATVREADON >= 0)
{
digitalWrite(BATVREADON, LOW); //turn MOSFET connection resitor divider in circuit
}
return volts;
}
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("45_Battery_Voltage_Read_Test Starting");
pinMode(LED1, OUTPUT); //for PCB LED
if (BATVREADON >= 0)
{
pinMode (BATVREADON, OUTPUT); //for turning on resistor divider
}
}

View File

@@ -0,0 +1,154 @@
/*******************************************************************************************************
Programs for Arduino - Copyright of the author Stuart Robinson - 02/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 that an MB85RC16PNF or FM24CL64 FRAM is working and retaining
memory contents when power is removed. FRAMs are non-voltatile memory devices with a typical write
endurance of from 10,000,000,000 (MB85RC16PNF) to 100,000,000,000,000 (FM24CL64B) write cycles.
When the program starts the serial monitor will first display the results of an I2C Device scan which
should list 8 devices found from 0x50 to 0x57 for a MB85RC16PNF and 0x50 for a FM24CL64 with the default
pin connections. The MB85RC16PNF has eight 256 byte pages, FM24CL64 is one page of 8kbytes. The program
then will print the contents of the memory. Next all the variable types will be written to successive
addresses will print the area of memory, then read back each variable from memory.
To check if the FRAM is reating memory you could make some changes to the variables written, run the
program and then power off. On restart the changed variables should be displayed.
Serial monitor baud rate is set at 9600.
*******************************************************************************************************/
#define Program_Version "V1.0"
//#include <FRAM_FM24CL64.h> //SX12xx library file for FM24CL64 FRAM, 64kbit, 8kbyte, , I2C addresse 0x50
#include <FRAM_MB85RC16PNF.h> //SX12xx library file for MB85RC16PNF FRAM, 16kbit, 2kbyte, I2C addresses 0x50 to 0x57
#include <Wire.h>
#include "I2C_Scanner.h"
#define Serial_Monitor_Baud 9600 //this is baud rate used for the Arduino IDE Serial Monitor
int16_t Memory_Address = 0x50; //default I2C address of MB85RC16PNF and FM24CL64 FRAM
void loop()
{
Serial.println(F("Printing memory"));
Serial.flush();
printMemory(0, 31);
Serial.println();
Serial.flush();
while (true)
{
Serial.println();
writeMemory();
Serial.println();
readMemory();
Serial.println();
delay(5000);
}
}
void writeMemory()
{
Serial.println(F("Writing variables"));
Serial.flush();
Serial.println(F("Write char A"));
writeMemoryChar(0, 'A');
Serial.println(F("Write int8_t 0x55"));
writeMemoryInt8(1, 0x55);
Serial.println(F("Write uint8_t 0xAA"));
writeMemoryUint8(2, 0xAA);
Serial.println(F("Write int16_t 0xFEDC"));
writeMemoryInt16(3, 0xFEDC);
Serial.println(F("Write uint16_t 0x1234"));
writeMemoryUint16(5, 0x1234);
Serial.println(F("Write int32_t 0xFEDCBA98"));
writeMemoryInt32(7, 0xFEDCBA98);
Serial.println(F("Write uint32_t 0x12345678"));
writeMemoryUint32(11, 0x12345678);
Serial.println(F("Write float 0.12345678"));
writeMemoryFloat(15, 0.12345678);
}
void readMemory()
{
char var1;
int8_t var2;
uint8_t var3;
int16_t var4;
uint16_t var5;
int32_t var6;
uint32_t var7;
float var8;
char buf[9];
Serial.println(F("Reading variables"));
Serial.flush();
var1 = readMemoryChar(0);
Serial.print(F("Read char "));
Serial.write(var1);
Serial.println();
var2 = readMemoryInt8(1);
Serial.print(F("Read int8_t 0x"));
Serial.println(var2,HEX);
var3 = readMemoryUint8(2);
Serial.print(F("Read uint8_t 0x"));
Serial.println(var3,HEX);
var4 = readMemoryInt16(3);
Serial.print(F("Read int16_t 0x"));
sprintf(buf, "%04X", var4);
Serial.println(buf);
var5 = readMemoryUint16(5);
Serial.print(F("Read uint16_t 0x"));
Serial.println(var5,HEX);
var6 = readMemoryInt32(7);
Serial.print(F("Read int32_t 0x"));
Serial.println(var6,HEX);
var7 = readMemoryUint32(11);
Serial.print(F("Read uint32_t 0x"));
Serial.println(var7,HEX);
var8 = readMemoryFloat(15);
Serial.print(F("Read float "));
Serial.println(var8, 7);
}
void setup()
{
Serial.begin(9600);
Serial.println();
Serial.print(F(__TIME__));
Serial.print(F(" "));
Serial.println(F(__DATE__));
Serial.println(F(Program_Version));
Serial.println();
setup_I2CScan();
run_I2CScan();
memoryStart(Memory_Address); //optional command to start memory with I2C address, if required
}

View File

@@ -0,0 +1,84 @@
// --------------------------------------
// i2c_scanner
//
// Version 1
// This program (or code that looks like it)
// can be found in many places.
// For example on the Arduino.cc forum.
// The original author is not know.
// Version 2, Juni 2012, Using Arduino 1.0.1
// Adapted to be as simple as possible by Arduino.cc user Krodal
// Version 3, Feb 26 2013
// V3 by louarnold
// Version 4, March 3, 2013, Using Arduino 1.0.3
// by Arduino.cc user Krodal.
// Changes by louarnold removed.
// Scanning addresses changed from 0...127 to 1...119,
// according to the i2c scanner by Nick Gammon
// http://www.gammon.com.au/forum/?id=10896
// Version 5, March 28, 2013
// As version 4, but address scans now to 127.
// A sensor seems to use address 120.
// Version 6, November 27, 2015.
// Added waiting for the Leonardo serial communication.
//
//
// This sketch tests the standard 7-bit addresses
// Devices with higher bit address might not be seen properly.
//
//#include <Wire.h>
void setup_I2CScan()
{
Wire.begin();
//Serial.begin(9600);
Serial.println("I2C Scanner");
}
void run_I2CScan()
{
byte error, address;
int nDevices;
Serial.println("Scanning for I2C Devices...");
nDevices = 0;
for(address = 1; address < 127; address++ )
{
// The i2c_scanner uses the return value of
// the Write.endTransmisstion to see if
// a device did acknowledge to the address.
Wire.beginTransmission(address);
error = Wire.endTransmission();
if (error == 0)
{
Serial.print("I2C device found at address 0x");
if (address<16)
Serial.print("0");
Serial.println(address,HEX);
nDevices++;
}
else if (error==4)
{
Serial.print("Unknown error at address 0x");
if (address<16)
Serial.print("0");
Serial.println(address,HEX);
}
}
if (nDevices == 0)
Serial.println("No I2C devices found");
else
Serial.println("done");
Wire.endTransmission();
}

View File

@@ -0,0 +1,84 @@
/*******************************************************************************************************
Programs for Arduino - Copyright of the author Stuart Robinson - 20/01/20
This program is supplied as is, it is up to the user of the program to decide if the program is
suitable for the intended purpose and free from errors.
*******************************************************************************************************/
/*******************************************************************************************************
Program Operation - The program reads a single DS18B20 temperature sensor and prints the result to the
serial monitor.
The program also has the option of using a logic pin to control the power to the lora and SD card
devices, which can save power in sleep mode. If the hardware is fitted to your board then these devices are
assumed to be powered on by setting the VCCPOWER pin low. If your board does not have this feature set
VCCPOWER to -1.
Serial monitor baud rate is set at 9600
*******************************************************************************************************/
#define programversion "V1.0"
#define ONE_WIRE_BUS 4 //pin the DS18B20 is connected to
#define LED1 8 //LED, on when reading temperature
#include <OneWire.h> //get library here > https://github.com/PaulStoffregen/OneWire
OneWire oneWire(ONE_WIRE_BUS); //create instance of OneWire library
#include <DallasTemperature.h> //get library here > https://github.com/milesburton/Arduino-Temperature-Control-Library
DallasTemperature sensor(&oneWire); //create instance of dallas library
void loop()
{
float DS18B20temperature;
digitalWrite(LED1, HIGH);
sensor.requestTemperatures();
digitalWrite(LED1, LOW);
DS18B20temperature = sensor.getTempCByIndex(0);
Serial.print(F("DS18B20 Temperature "));
Serial.print(DS18B20temperature, 2);
Serial.println(F("c"));
delay(5000);
}
void led_Flash(unsigned int flashes, unsigned int delaymS)
{
unsigned int index;
for (index = 1; index <= flashes; index++)
{
digitalWrite(LED1, LOW);
delay(delaymS);
digitalWrite(LED1, HIGH);
delay(delaymS);
}
}
void setup()
{
Serial.begin(9600);
Serial.println();
Serial.print(__TIME__);
Serial.print(F(" "));
Serial.println(__DATE__);
Serial.println(F(programversion));
Serial.println();
Serial.println("48_DS18B20_Test Starting");
pinMode(LED1, OUTPUT);
led_Flash(4, 125); //one second of flashes
sensor.begin();
sensor.requestTemperatures(); //do a null temperature read
}

View File

@@ -0,0 +1,103 @@
/*******************************************************************************************************
Programs for Arduino - Copyright of the author Stuart Robinson - 05/12/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 a NRF2401 library to
check the NRF2401 can be written to and read from over the SPI bus.
The contents of the NRF2401 registers from 0x00 to 0x1F are read and printed to the serial monitor.
If the connections are OK then the printout should look like this;
57_NRF24L01_Is_It_There ?
Print registers 0x00 to 0x1F
Reg 0 1 2 3 4 5 6 7 8 9 A B C D E F
0x00 00 3F 02 03 5F 4C 27 42 00 00 E7 52 C3 C4 C5 C6
0x10 E7 00 20 00 00 00 00 12 00 00 FF FF FF FF FF FF
Note that this is just a 'is it there type check' the CE pin is not used or needed for this simple check.
If the device is faulty, not present or wired incorrectly the register contents will likely be all 00s or
FFs. The program makes no attempt to turn on the RF transmitter or receiver.
Serial monitor baud rate is set at 9600.
*******************************************************************************************************/
#include <SPI.h>
#define CSN_PIN 10
#define NUM_REGISTERS 26
#define CMD_R_REGISTER 0x00
#define CMD_W_REGISTER 0x20
void loop()
{
Serial.println(F("Print registers 0x00 to 0x1F"));
printRegisters(0, 0x1F);
Serial.println();
delay(5000);
}
void printRegisters(uint16_t Start, uint16_t End)
{
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"));
if (Loopv1 < 0x10)
{
Serial.print(F("0"));
}
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();
}
}
uint8_t readRegister(uint8_t reg)
{
uint8_t result = 0xFF;
if (reg < NUM_REGISTERS) {
digitalWrite(CSN_PIN, LOW);
SPI.transfer(CMD_R_REGISTER | reg);
result = SPI.transfer(0xff);
digitalWrite(CSN_PIN, HIGH);
}
return result;
}
void setup()
{
Serial.begin(9600);
pinMode(CSN_PIN, OUTPUT);
Serial.println();
Serial.println(F("57_NRF24L01_Is_It_There ?"));
Serial.println();
SPI.begin();
}

View File

@@ -0,0 +1,48 @@
/*******************************************************************************************************
Programs for Arduino - Copyright of the author Stuart Robinson - 06/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 simple program to test a Serial Bluetooth device is working. The program
uses software serial to send a Hello World message to a serial port. If the Bluetooth device is paired
with an Android device you should see Hello World in an Andriod Bluetooth terminal application.
Bluetooth baud rate is set at 9600, an HC-06 Bluetooth device is assumed.
Note that not all pins on all Arduinos will work with software serial, see here;
https://www.arduino.cc/en/Reference/softwareSerial
Serial monitor baud rate is set at 115200.
*******************************************************************************************************/
#define BlueToothBAUD 9600 //this is the serial baud rate that will be used for the Bluetooth, a common default
#define MONITORBAUD 9600 //this is the serial baud rate that will be used for the serial monitor
#define RXpin A3 //this is the pin that the Arduino will use to receive data from the Bluetooth
#define TXpin A2 //this is the pin that the Arduino can use to send data (commands) to the Bluetooth
#include <SoftwareSerial.h>
SoftwareSerial BlueTooth(RXpin, TXpin);
uint32_t counter;
void loop()
{
BlueTooth.print(counter++);
BlueTooth.println(F(" Hello World"));
delay(1000);
}
void setup()
{
BlueTooth.begin(BlueToothBAUD);
Serial.begin(MONITORBAUD);
Serial.println("61_Bluetooth_Test Starting");
}

View File

@@ -0,0 +1,62 @@
/*******************************************************************************************************
Programs for Arduino - Copyright of the author Stuart Robinson - 08/09/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 sends a command to a Quectel GPS to return its firmware revision.
The output from the GPS is copied to the Serial Monitor.
If you get no data displayed on the serial monitor, the most likely cause is that you have the receive
data pin into the Arduino (RX) pin connected incorrectly.
If the data displayed on the serial terminal appears to be random text with odd symbols its very
likely you have the GPS serial baud rate set incorrectly.
Note that not all pins on all Arduinos will work with software serial, see here;
https://www.arduino.cc/en/Reference/softwareSerial
Serial monitor baud rate is set at 115200.
*******************************************************************************************************/
#define GPSBAUD 9600 //this is the serial baud rate that will be used for the GPS, a common default
#define MONITORBAUD 115200 //this is the serial baud rate that will be used for the serial monitor
#define RXpin A3 //this is the pin that the Arduino will use to receive data from the GPS
#define TXpin A2 //this is the pin that the Arduino can use to send data (commands) to the GPS - not used
#define GPSPOWER 4 //When high this pin turns GPS on
#define LED1 8 //when high this pin turns LED on
#include <SoftwareSerial.h>
SoftwareSerial GPS(RXpin, TXpin);
void loop()
{
while (GPS.available())
{
Serial.write(GPS.read());
}
}
void setup()
{
pinMode(GPSPOWER, OUTPUT);
digitalWrite(GPSPOWER, HIGH);
pinMode(LED1, OUTPUT);
digitalWrite(LED1, HIGH);
GPS.begin(GPSBAUD);
Serial.begin(MONITORBAUD);
Serial.println("63_QuectelGPS_Firmware_Checker");
delay(2000);
GPS.println("$PMTK605*31");
}

View File

@@ -0,0 +1,145 @@
/*******************************************************************************************************
Programs for Arduino - Copyright of the author Stuart Robinson - 12/10/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 uses a GPS to indicate speed, should work with most GPSs. Speed update
rate approx once per second. GPS characters are output to serial monitor when checking for update from
GPS. Prints speed in large text on an SSD1306 or SH1106 OLED.
Display and serial monitor updatesto speed only occur when the a new update has been decoded from the
GPS.
Serial monitor baud rate is set at 115200.
*******************************************************************************************************/
#include <TinyGPS++.h> //get library here > http://arduiniana.org/libraries/tinygpsplus/
TinyGPSPlus gps; //create the TinyGPS++ object
#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
#include <SoftwareSerial.h>
SoftwareSerial GPSserial(RXpin, TXpin);
#include <U8g2lib.h> //get library here > https://github.com/olikraus/u8g2
#include <Wire.h>
U8G2_SSD1306_128X64_NONAME_1_HW_I2C disp(U8G2_R0, U8X8_PIN_NONE); //use this line for 0.96" SSD1306 OLED
//U8G2_SH1106_128X64_NONAME_1_HW_I2C disp(U8G2_R0, U8X8_PIN_NONE); //use this line for 1.3" SH1106 OLED
float GPSSpeed; //Speed of GPS, mph
uint32_t startGetFixmS;
uint32_t endFixmS;
void loop()
{
if (gpsWaitFix(3))
{
Serial.println();
Serial.println();
Serial.print(F("Fix time "));
Serial.print(endFixmS - startGetFixmS);
Serial.println(F("mS"));
GPSSpeed = gps.speed.mph();
Serial.print(F("Speed,"));
Serial.print(GPSSpeed, 1);
Serial.println();
displayscreen1(); //print GPS data on display
startGetFixmS = millis(); //have a fix, next thing that happens is checking for a fix, so restart timer
}
else
{
displayscreen2();
Serial.println();
Serial.println();
Serial.print(F("Timeout - No GPS Fix "));
Serial.print( (millis() - startGetFixmS) / 1000 );
Serial.println(F("s"));
}
}
bool gpsWaitFix(uint16_t waitSecs)
{
//waits a specified number of seconds for a fix, returns true for good fix
uint32_t startmS, waitmS;
uint8_t GPSchar;
Serial.print(F("Wait GPS Fix "));
Serial.print(waitSecs);
Serial.println(F(" seconds"));
waitmS = waitSecs * 1000; //convert seconds wait into mS
startmS = millis();
while ((uint32_t) (millis() - startmS) < waitmS)
{
if (GPSserial.available() > 0)
{
GPSchar = GPSserial.read();
gps.encode(GPSchar);
Serial.write(GPSchar);
}
if (gps.location.isUpdated() && gps.altitude.isUpdated() && gps.speed.isUpdated())
{
endFixmS = millis(); //record the time when we got a new GPS update
return true;
}
}
return false;
}
void displayscreen1()
{
disp.setFont(u8g2_font_logisoso62_tn);
disp.firstPage();
do {
disp.setCursor(0, 63);
disp.print(GPSSpeed, 0);
} while ( disp.nextPage() );
}
void displayscreen2()
{
disp.setFont(u8g2_font_lubB14_tr);
disp.firstPage();
do {
disp.setCursor(35, 15);
disp.print(F("Speedo"));
disp.setCursor(15, 45);
disp.print(F("No GPS fix"));
} while ( disp.nextPage() );
}
void setup()
{
delay(1000);
Serial.begin(115200);
GPSserial.begin(9600);
disp.begin();
disp.clear();
displayscreen2();
disp.print(F("Display Ready"));
Serial.println(F("72A_GPS_Speedo_With_Display Starting"));
Serial.println();
startGetFixmS = millis();
}

View File

@@ -0,0 +1,105 @@
/*******************************************************************************************************
Programs for Arduino - Copyright of the author Stuart Robinson - 30/12/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 uses a GPS to indicate speed, should work with most GPSs. Speed update
rate approx onece per second. GPS characters are output to serial monitor when checking for update from
GPS.
Serial monitor baud rate is set at 115200.
*******************************************************************************************************/
#include <TinyGPS++.h> //get library here > http://arduiniana.org/libraries/tinygpsplus/
TinyGPSPlus gps; //create the TinyGPS++ object
#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
#include <SoftwareSerial.h>
SoftwareSerial GPSserial(RXpin, TXpin);
float GPSSpeed; //Speed of GPS, mph
uint32_t startGetFixmS;
uint32_t endFixmS;
void loop()
{
if (gpsWaitFix(5))
{
Serial.println();
Serial.println();
Serial.print(F("Fix time "));
Serial.print(endFixmS - startGetFixmS);
Serial.println(F("mS"));
GPSSpeed = gps.speed.mph();
Serial.print(F("Speed,"));
Serial.print(GPSSpeed, 1);
Serial.println();
startGetFixmS = millis(); //have a fix, next thing that happens is checking for a fix, so restart timer
}
else
{
Serial.println();
Serial.println();
Serial.print(F("Timeout - No GPS Fix "));
Serial.print( (millis() - startGetFixmS) / 1000 );
Serial.println(F("s"));
}
}
bool gpsWaitFix(uint16_t waitSecs)
{
//waits a specified number of seconds for a fix, returns true for good fix
uint32_t startmS, waitmS;
uint8_t GPSchar;
Serial.print(F("Wait GPS Fix "));
Serial.print(waitSecs);
Serial.println(F(" seconds"));
waitmS = waitSecs * 1000; //convert seconds wait into mS
startmS = millis();
while ((uint32_t) (millis() - startmS) < waitmS)
{
if (GPSserial.available() > 0)
{
GPSchar = GPSserial.read();
gps.encode(GPSchar);
Serial.write(GPSchar);
}
if (gps.location.isUpdated() && gps.altitude.isUpdated() && gps.speed.isUpdated())
{
endFixmS = millis(); //record the time when we got a new GPS update
return true;
}
}
return false;
}
void setup()
{
delay(1000);
Serial.begin(115200);
GPSserial.begin(9600);
Serial.println(F("72_GPS_Speedo Starting"));
Serial.println();
startGetFixmS = millis();
}

View File

@@ -0,0 +1,134 @@
/*******************************************************************************************************
Programs for Arduino - Copyright of the author Stuart Robinson - 30/09/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 simple test program for the LIL9341 TFT display that comes in a
range of sizes. The program prints a short message on each line, pauses, clears the screen, and starts
again. Program uses Adafruit ILI9341 library.
Screen write time on Arduino DUE 332mS, screen clear 268mS
Screen write time on Teensy 4.1 207mS, screen clear 180mS
Serial monitor baud rate is set at 9600.
*******************************************************************************************************/
#include "SPI.h"
#include "Adafruit_GFX.h" //get library here > https://github.com/adafruit/Adafruit-GFX-Library
#include "Adafruit_ILI9341.h" //get library here > https://github.com/adafruit/Adafruit_ILI9341
int8_t DISPCS = 10;
int8_t DISPDC = 8;
//int8_t DISPCS = 43; //for DUE shield
//int8_t DISPDC = 45; //for DUE shield
Adafruit_ILI9341 disp = Adafruit_ILI9341(DISPCS, DISPDC);
#define textscale 2 //default text scale
uint16_t writecount;
uint32_t startmS, endmS, timemS;
void loop()
{
setCursor(0, 0);
disp.setTextColor(ILI9341_WHITE);
disp.setTextSize(textscale);
writecount++;
Serial.print(writecount);
Serial.print(F(" Writing to display"));
startmS = millis();
disp.fillScreen(ILI9341_BLACK); //clear screen
screen1();
endmS = millis();
timemS = endmS - startmS;
setCursor(8, 4);
disp.print(timemS);
disp.print(F("mS"));
Serial.print(F(" - done "));
Serial.print(timemS);
Serial.println(F("mS"));
delay(2000);
startmS = millis();
disp.fillScreen(ILI9341_BLACK); //clear screen
endmS = millis();
timemS = endmS - startmS;
setCursor(0, 0);
disp.print(F("Screen clear "));
disp.print(timemS);
disp.print(F("mS"));
delay(2000);
}
void setCursor(uint8_t lcol, uint8_t lrow)
{
disp.setCursor((lcol * 6 * textscale), (lrow * 10 * textscale));
}
void screen1()
{
setCursor(0, 0);
disp.print(F("ILI9341_Checker"));
setCursor(0, 1);
disp.print(F("Line 1"));
setCursor(0, 2);
disp.print(F("Line 2"));
setCursor(0, 3);
disp.print(F("Line 3"));
setCursor(0, 4);
disp.print(F("Line 4"));
setCursor(0, 5);
disp.print(F("Line 5"));
setCursor(0, 6);
disp.print(F("Line 6"));
setCursor(0, 7);
disp.print(F("Line 7"));
setCursor(0, 8);
disp.print(F("Line 8"));
setCursor(0, 9);
disp.print(F("Line 9"));
setCursor(0, 10);
disp.print(F("Line 10"));
setCursor(0, 11);
disp.print(F("01234567890123456789012")); //display is 12 lines x 23 charaters
}
void setup()
{
Serial.begin(9600);
Serial.println(F("77_ILI9341_Display_Checker starting"));
SPI.begin();
disp.begin();
//disp.setFont(Arial_16);
disp.fillScreen(ILI9341_BLACK);
disp.setTextColor(ILI9341_WHITE);
disp.setRotation(1);
disp.setTextSize(textscale);
}

View File

@@ -0,0 +1,55 @@
/*******************************************************************************************************
Programs for Arduino - Copyright of the author Stuart Robinson - 14/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.
*******************************************************************************************************/
/*******************************************************************************************************
Program Operation - This is a simple terminal to allow you to use a Serial terminal program, such as Teraterm
or CoolTerm to talk to a serial device such as a Bluetooth module connected to your Arduino.
Note that not all pins on all Arduinos will work with software serial, see here;
https://www.arduino.cc/en/Reference/softwareSerial
Serial monitor baud rate is set at 9600.
*******************************************************************************************************/
#define DEVICEBAUD 9600 //serial baud rate that will be used for the device conncted to your Arduino
#define MONITORBAUD 9600 //serial baud rate that will be used for the serial monitor
#define RXpin A3 //this is the pin that the Arduino will use to receive data from the serial device
#define TXpin A2 //this is the pin that the Arduino can use to send data (commands) to the serial device
#include <SoftwareSerial.h>
SoftwareSerial device(RXpin, TXpin);
void loop()
{
while (device.available())
{
Serial.write(device.read());
}
while (Serial.available())
{
device.write(Serial.read());
}
}
void setup()
{
device.begin(DEVICEBAUD);
Serial.begin(MONITORBAUD);
Serial.println("79_Serial_Terminal Starting");
delay(1000);
}

View File

@@ -0,0 +1,120 @@
/*******************************************************************************************************
Programs for Arduino - Copyright of the author Stuart Robinson - 03/02/20
This program is supplied as is, it is up to the user of the program to decide if the program is
suitable for the intended purpose and free from errors.
*******************************************************************************************************/
/*******************************************************************************************************
Program Operation - This is a simple test for a Bosch BME280 sensor. Readings are sent to the serial
monitor. The Seeed library assumes the BME280 is at address 0x76. It can be changed to 0x77 by an edit
in the Seeed_BME280.h librsry file.
Serial monitor baud rate is set at 9600.
*******************************************************************************************************/
#include <Seeed_BME280.h> //get library here; https://github.com/Seeed-Studio/Grove_BME280
BME280 bme280; //create an instance of the BME280 senosor
#define BME280_REGISTER_CONTROL 0xF4 //BME280 register number for power control
#include <Wire.h>
#define LED1 8 //on board LED, high for on
float temperature; //the BME280 temperature value
float pressure; //the BME280 pressure value
uint16_t humidity; //the BME280 humididty value
void loop()
{
Serial.print(F("Reading > "));
readSensors(); //read the sensor values
printSensorValues(); //print the sensor values
Serial.println();
sleepBME280();
delay(500);
normalBME280(); //BME280 sensor to normal mode
}
void readSensors()
{
//read the sensor values into the global variables
temperature = bme280.getTemperature();
pressure = bme280.getPressure();
humidity = bme280.getHumidity();
}
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("%"));
Serial.print(F(" "));
Serial.flush();
}
void sleepBME280()
{
//write this register value to BME280 to put it to sleep
writeBME280reg(BME280_REGISTER_CONTROL, B01111100);
}
void normalBME280()
{
//write this register value to BME280 to put it to read mode
writeBME280reg(BME280_REGISTER_CONTROL, B01111111);
}
void writeBME280reg(uint8_t reg, uint8_t 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();
}
void led_Flash(uint16_t flashes, uint16_t delaymS)
{
uint16_t index;
for (index = 1; index <= flashes; index++)
{
digitalWrite(LED1, HIGH);
delay(delaymS);
digitalWrite(LED1, LOW);
delay(delaymS);
}
}
void setup()
{
pinMode(LED1, OUTPUT); //for PCB LED
led_Flash(2, 125);
Serial.begin(9600);
Serial.println();
Serial.println(F("81_BME280_Test starting"));
bme280.init();
Serial.println(F("Initialised BME280"));
Serial.println();
readSensors(); //do an initial sensor read
}

View File

@@ -0,0 +1,28 @@
//see the video here > https://www.youtube.com/watch?v=eeDC1m7ANJI&t=100s
//code here > https://gist.github.com/speters/f889faec42b510052a6ab4be437d38ca
//Purpose is to simply run a memory check on ATMEGA238P to test for counterfeit parts
#include <avr/boot.h>
#define SIGRD 5
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
Serial.println("");
Serial.println("boot sig dump");
int newLineIndex = 0;
for (uint8_t i = 0; i <= 0x1F; i += 1) {
Serial.print(boot_signature_byte_get(i), HEX);
Serial.print("\t");
newLineIndex++;
if (newLineIndex == 8) {
Serial.println("");
newLineIndex = 0;
}
}
Serial.println();
}
void loop() {
}

View File

@@ -0,0 +1,26 @@
//
// ArduinoUniqueID.ino
//
// Example shows the UniqueID on the Serial Monitor.
//
#include <ArduinoUniqueID.h> //get library here > https://github.com/ricaun/ArduinoUniqueID
void setup()
{
Serial.begin(115200);
UniqueIDdump(Serial);
Serial.print("UniqueID: ");
for (size_t i = 0; i < UniqueIDsize; i++)
{
if (UniqueID[i] < 0x10)
Serial.print("0");
Serial.print(UniqueID[i], HEX);
Serial.print(" ");
}
Serial.println();
}
void loop()
{
}

View File

@@ -0,0 +1,69 @@
// --------------------------------------
// i2c_scanner
// from: https://playground.arduino.cc/Main/I2cScanner/
// This sketch tests the standard 7-bit addresses
// Devices with higher bit address might not be seen properly.
#include <Wire.h>
uint16_t counter;
void setup()
{
Wire.begin();
Serial.begin(9600);
Serial.println(F("I2C Scanner starting"));
Serial.println();
}
void loop()
{
uint8_t error, address;
int16_t nDevices;
counter++;
Serial.print(counter);
Serial.println(F(" Scanning..."));
nDevices = 0;
for (address = 1; address < 127; address++ )
{
// The i2c_scanner uses the return value of
// the Write.endTransmisstion to see if
// a device did acknowledge to the address.
Wire.beginTransmission(address);
error = Wire.endTransmission();
if (error == 0)
{
Serial.print(F("I2C device found at address 0x"));
if (address < 16)
Serial.print(F("0"));
Serial.println(address, HEX);
nDevices++;
}
else if (error == 4)
{
Serial.print(F("Unknown error at address 0x"));
if (address < 16)
Serial.print(F("0"));
Serial.println(address, HEX);
}
}
if (nDevices == 0)
{
Serial.println(F("No I2C devices found"));
}
else
{
Serial.println();
Serial.println(F("Done"));
Serial.println();
}
delay(5000); // wait 5 seconds for next scan
}

View File

@@ -0,0 +1,86 @@
/*******************************************************************************************************
Programs for Arduino - Copyright of the author Stuart Robinson - 20/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.
*******************************************************************************************************/
/*******************************************************************************************************
Program Operation - This program is a simple test program for the SSD1306 and SH1106 OLEDs. The program
prints a short message on each line, pauses, clears the screen, and starts again.
OLED address is defined as 0x3C.
Serial monitor baud rate is set at 9600.
*******************************************************************************************************/
#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
#define DEFAULTFONT u8x8_font_chroma48medium8_r //font for U8X8 Library
#define OLED_Address 0x3C
uint16_t writecount;
uint32_t startwritemS, endwritemS, timemS;
void loop()
{
writecount++;
Serial.print(writecount);
Serial.print(F(" Writing to display"));
disp.setI2CAddress(OLED_Address<<1); //I2C address multiplied by 2, the lowest bit must be zero
disp.setFont(DEFAULTFONT);
startwritemS = millis();
disp.clear();
screen1();
endwritemS = millis();
timemS = endwritemS - startwritemS;
disp.setCursor(8, 4);
disp.print(timemS);
disp.print(F("mS"));
Serial.print(F(" - done"));
Serial.print(timemS);
Serial.println(F("mS"));
delay(2000);
Serial.println(F("PowerSave display"));
disp.setPowerSave(1); //power save display, turns off
delay(2000);
disp.setPowerSave(0); //display back to normal
}
void screen1()
{
disp.setCursor(0, 0);
disp.print(F("Hello World !"));
disp.setCursor(0, 1);
disp.print(F("Line 1"));
disp.setCursor(0, 2);
disp.print(F("Line 2"));
disp.setCursor(0, 3);
disp.print(F("Line 3"));
disp.setCursor(0, 4);
disp.print(F("Line 4"));
disp.setCursor(0, 5);
disp.print(F("Line 5"));
disp.setCursor(0, 6);
disp.print(F("Line 6"));
disp.setCursor(0, 7);
disp.print(F("0123456789012345")); //display is 8 lines x 16 charaters when using the
//u8x8_font_chroma48medium8_r font
}
void setup()
{
Serial.begin(9600);
Serial.println(F("31_SSD1306_SH1106_OLED_Checker_ESP32 starting"));
disp.begin();
}

View File

@@ -0,0 +1,272 @@
/*******************************************************************************************************
Programs for Arduino - Copyright of the author Stuart Robinson - 04/06/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 test program has been written to check that a connected SD card adapter, Micro
or standard, is functional.
When the program runs it will attempts to create a file that is next in sequence to Log0000.txt, thus
if this is the first time the program has run on the SD card it will create file Log0001.txt. If the
file Log0001.txt exists it will create Log0002.txt etc. This ensures that everytime the program starts
it creates a new file for testing.
Next the program checks if the Logxxxx.txt file exists and if so attempts to delete it.
Then the program starts a loop. First the same file is again opened for append, it will be created if it
does not exist and then the line '1 Hello World' is writtent to the file. The file is closed and the
contents of the file are dumped to the serial monitor. The loop restarts, and this time the line
'2 Hello World' is appended to the file.
As the program progresses the file will grow in size and after 4 iterrations of the open,write,close
and dump loop the file dump on serial monitor will look like this
1 Hello World
2 Hello World
3 Hello World
4 Hello World
This file dump will grow if you let the program run. If an error with the SD card is detected at any
time the LED will rapid flash continuously and the message 'X Card failed, or not present' is printed
to serial monitor. The number X will allow you to check the program listing for where the error occured.
1 Card failed = SD card did not initialise
2 Card failed = Could nt setup logFile for new name
3 Card failed = Could not open file for append
4 Card failed = Failure to dump file to serial monitor
Note: At the time of writing, 04/06/20, the function that the dumpFile() routine uses to check if an SD
card is still present, SD.exists(filename), does not work on the SD.h file included in the current Expressif
core for Arduino. If the SD card is removed, the SD.exists(filename) function returns true so the following
dump of the file locks up the ESP32.
Serial monitor baud rate is set at 9600
*******************************************************************************************************/
#define Program_Version "V1.1"
#include <SD.h>
#include <SPI.h>
//pin definitions. You also need to connect the card SCK to pin 18, MISO to pin 19 and MOSI to pin 23
#define LED1 2 //pin number for LED
#define SDCS 13 //pin number for device select on SD card module
File logFile;
char filename[] = "/LOG0000.TXT"; //filename used as base for creating logfile, 0000 replaced with numbers
uint16_t linecount;
void loop()
{
Serial.println();
Serial.println("Initializing SD card");
if (!SD.begin(SDCS))
{
cardFail(1);
}
Serial.println("Card initialized");
logFile = SD.open("/");
Serial.println("Card directory");
Serial.println();
printDirectory(logFile, 0);
Serial.println();
Serial.println();
if (!setupSDLOG(filename)) //setup logfile name for writing
{
cardFail(2);
}
Serial.print(F("logFile name is "));
Serial.println(filename);
if (SD.exists(filename))
{
Serial.print(filename);
Serial.println(" exists - delete");
SD.remove(filename);
}
if (!SD.exists(filename))
{
Serial.print(filename);
Serial.println(" does not exist");
}
while (1)
{
logFile = SD.open(filename, FILE_APPEND);
if (!logFile)
{
cardFail(3);
}
linecount++;
logFile.print(linecount);
logFile.println(" Hello World");
logFile.close();
Serial.println();
Serial.print("Dump file ");
Serial.println(filename);
Serial.println();
digitalWrite(LED1, HIGH);
if (dumpFile(filename))
{
Serial.println();
Serial.println("Finished File Dump");
}
else
{
cardFail(4);
}
digitalWrite(LED1, LOW);
delay(2000);
}
}
void printDirectory(File dir, int numTabs)
{
while (true)
{
File entry = dir.openNextFile();
if (! entry)
{
//no more files
break;
}
for (uint8_t i = 0; i < numTabs; i++) {
Serial.print('\t');
}
Serial.print(entry.name());
if (entry.isDirectory())
{
Serial.println("/");
printDirectory(entry, numTabs + 1);
}
else
{
//files have sizes, directories do not
Serial.print("\t\t");
Serial.println(entry.size(), DEC);
}
entry.close();
}
}
bool dumpFile(char *buf)
{
//Note, this function will return true if the SD card is remove. See note at program start.
if (SD.exists(buf))
{
Serial.print(buf);
Serial.println(" found");
}
else
{
Serial.print(filename);
Serial.println(" not found");
return false;
}
logFile = SD.open(buf);
if (logFile) //if the file is available, read from it
{
while (logFile.available())
{
Serial.write(logFile.read());
}
logFile.close();
return true;
}
return false;
}
uint8_t setupSDLOG(char *buf)
{
//creats a new filename
uint16_t index;
for (index = 1; index <= 9999; index++) {
buf[4] = index / 1000 + '0';
buf[5] = ((index % 1000) / 100) + '0';
buf[6] = ((index % 100) / 10) + '0';
buf[7] = index % 10 + '0' ;
if (! SD.exists(filename)) {
// only open a new file if it doesn't exist
logFile = SD.open(buf, FILE_WRITE);
break;
}
}
if (!logFile)
{
return 0;
}
return index; //return number of logfile created
}
void cardFail(uint8_t num)
{
while (1)
{
Serial.print(num); //so we can tell where card failed
Serial.println(" Card failed, or not present");
led_Flash(100, 25);
}
}
void led_Flash(unsigned int flashes, unsigned int delaymS)
{
unsigned int index;
for (index = 1; index <= flashes; index++)
{
digitalWrite(LED1, HIGH);
delay(delaymS);
digitalWrite(LED1, LOW);
delay(delaymS);
}
}
void setup()
{
pinMode(LED1, OUTPUT); //for PCB LED
led_Flash(4, 125);
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("43_SD_Card_Test Starting"));
}

View File

@@ -0,0 +1,110 @@
/*******************************************************************************************************
Programs for Arduino - Copyright of the author Stuart Robinson - 20/01/20
This program is supplied as is, it is up to the user of the program to decide if the program is
suitable for the intended purpose and free from errors.
*******************************************************************************************************/
/*******************************************************************************************************
Program Operation - This test program has been written to check that a connected SD card adapter, Micro
or standard, is funtional with the FS functions. To use the program first copy the file (in this programs
directory) called testfile.txt to the root directory of the SD card.
When the program runs it will attempt to open 'testfile.txt' and spool the contents to the Arduino IDE
serial monitor. The testfile is part of the source code for the Apollo 11 Lunar Lander navigation and
guidance computer. There are LED flashes at power up or reset, then at start of every loop of the test.
The LED is on whilst the testfile is being read. If the LED flashes very rapidly then there is a problem
accessing the SD card.
The program also has the option of using a logic pin to control the power to the lora and SD card
devices, which can save power in sleep mode. If the hardware is fitted to your board these devices are
powered on by setting the VCCPOWER pin low. If your board does not have this feature set VCCPOWER to -1.
Serial monitor baud rate is set at 9600
*******************************************************************************************************/
#define Program_Version "V1.0"
#include "ESP32_LoRa_Micro_Node.h"
#include "FS.h"
#include "SD.h"
#include "SPI.h"
void loop()
{
Serial.println(F("LED Flash"));
Serial.println();
led_Flash(2, 50);
readFile(SD, "/testfile.txt");
delay(1000);
}
void readFile(fs::FS &fs, const char * path) {
Serial.printf("Reading file: %s\n", path);
File file = fs.open(path);
if (!file) {
Serial.println();
Serial.println("Failed to open file for reading");
Serial.println();
return;
}
Serial.print("Read from file: ");
digitalWrite(LED1, HIGH);
while (file.available()) {
Serial.write(file.read());
}
file.close();
digitalWrite(LED1, LOW);
}
void led_Flash(unsigned int flashes, unsigned int delaymS)
{
unsigned int index;
for (index = 1; index <= flashes; index++)
{
digitalWrite(LED1, HIGH);
delay(delaymS);
digitalWrite(LED1, LOW);
delay(delaymS);
}
}
void setup()
{
pinMode(LED1, OUTPUT); //for PCB LED
led_Flash(4, 125);
if (VCCPOWER >= 0)
{
pinMode(VCCPOWER, OUTPUT); //For controlling power to external devices
digitalWrite(VCCPOWER, LOW); //VCCOUT on. lora device on
}
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("44_SD_Card_Test_With_FS_ESP32 Starting"));
Serial.print("Initializing SD card...");
if (!SD.begin(SDCS)) {
Serial.println("Card failed, or not present.");
led_Flash(100, 25);
return; //loop if no card found
}
Serial.println("Card initialized.");
}

View File

@@ -0,0 +1,21 @@
/*******************************************************************************************************
Programs for Arduino - Copyright of the author Stuart Robinson - 20/01/20
This program is supplied as is, it is up to the user of the program to decide if the program is
suitable for the intended purpose and free from errors.
*******************************************************************************************************/
//******* Setup hardware pin definitions here ! ***************
//These are the pin definitions for one of the Tracker boards, the ESP32_Micro_Node, be sure to change
//them to match your own setup. You will also need to connect up the pins for the SPI bus, which on the
//ESP32_Micro_Node are SCK on pin 13, MISO on pin 19 and MOSI on pin 23. Some pins such as DIO1, DIO2 and
//BUZZER may not be in used by this sketch so they do not need to be connected and should be set to -1.
#define SWITCH1 0 //pin number to attach switch
#define LED1 2 //pin number for LED
#define SDCS 13 //ESP32 pin number for device select on SD card module
#define VCCPOWER 14 //pin controls power to external devices, such as the SD card

View File

@@ -0,0 +1,111 @@
/*******************************************************************************************************
Programs for Arduino - Copyright of the author Stuart Robinson - 20/01/20
This program is supplied as is, it is up to the user of the program to decide if the program is
suitable for the intended purpose and free from errors.
*******************************************************************************************************/
/*******************************************************************************************************
Program Operation - This test program has been written to check that hardware for reading the battery
voltage has been assembled correctly such that it is funtional. The value defined as 'ADMultiplier'
in settings.h is used to adjust the value read from the 91K\11K resistor divider and convert into mV.
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 ADMultiplier 10.872 //adjustment to convert AD value read into mV of battery voltage
#define BATVREADON 25 //used to turn on the resistor divider to measure voltage //this pin turns on the MOSFET that switches in the resistor divider
#define LED1 2 //pin for PCB LED
#define SupplyAD 36 //Resitor divider for battery connected here
void loop()
{
Serial.println(F("LED Flash"));
led_Flash(4, 125);
printSupplyVoltage();
Serial.println();
delay(1500);
}
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 printSupplyVoltage()
{
//get and display supply volts on terminal or monitor
Serial.print(F("Supply Volts "));
Serial.print(readSupplyVoltage());
Serial.println(F("mV"));
}
uint16_t readSupplyVoltage()
{
//ESP32 uses the 3.3V VCC as reference
uint16_t temp;
uint16_t volts = 0;
byte index;
if (BATVREADON >= 0)
{
digitalWrite(BATVREADON, HIGH); //turn on MOSFET connecting resitor divider in circuit
}
temp = analogRead(SupplyAD);
for (index = 0; index <= 4; index++) //sample AD 5 times
{
temp = analogRead(SupplyAD);
volts = volts + temp;
}
volts = ((volts / 5) * ADMultiplier);
if (BATVREADON >= 0)
{
digitalWrite(BATVREADON, LOW); //turn off MOSFET connecting resitor divider in circuit
}
return volts;
}
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("45_Battery_Voltage_Read_Test_ESP32 Starting");
pinMode(LED1, OUTPUT); //for PCB LED
if (BATVREADON >= 0)
{
pinMode(BATVREADON, OUTPUT); //controls MOSFET connecting resitor divider in circuit
}
}

View File

@@ -0,0 +1,90 @@
/*******************************************************************************************************
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 flashes a LED connected to the pin defined by LED1, and puts the ESP32
to deep_sleep for a period determined by the TIME_TO_SLEEP variable (in seconds).
The program also has the option of using a logic pin to control the power to the lora and SD card
devices, which can save power in sleep mode. If the hardware is fitted to your board these devices are
powered on by setting the VCCPOWER pin low. If your board does not have this feature set VCCPOWER to -1.
Current in deep_sleep for a bare bones ESP32 with regulator and no other devices was 27uA.
Serial monitor baud rate is set at 9600.
*******************************************************************************************************/
#define LED1 2 //pin number for LED
#define VCCPOWER 14 //pin may control power to external devices, -1 if not used
#define uS_TO_S_FACTOR 1000000 //Conversion factor for micro seconds to seconds
#define TIME_TO_SLEEP 15 //Time ESP32 will go to sleep (in seconds)
RTC_DATA_ATTR int32_t bootCount = 0;
RTC_DATA_ATTR uint32_t sleepcount = 0;
void loop()
{
Serial.print(F("Bootcount "));
Serial.println(bootCount);
Serial.print(F("Sleepcount "));
Serial.println(sleepcount);
Serial.println(F("LED Flash"));
led_Flash(4, 125);
Serial.println(F("LED On"));
digitalWrite(LED1, HIGH);
delay(2500);
Serial.println(F("LED Off"));
digitalWrite(LED1, LOW);
esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
Serial.println(F("Start Sleep"));
Serial.flush();
sleepcount++;
esp_deep_sleep_start();
Serial.println();
Serial.println();
Serial.println(F("Awake !"));
}
void led_Flash(unsigned int flashes, unsigned int delaymS)
{
//flash LED to show tracker is alive
unsigned int index;
for (index = 1; index <= flashes; index++)
{
digitalWrite(LED1, LOW);
delay(delaymS);
digitalWrite(LED1, HIGH);
delay(delaymS);
}
}
void setup()
{
Serial.begin(9600); //setup Serial console ouput
Serial.println(F("47_DeepSleep_Timed_Wakeup_ESP32 - Starting"));
if (bootCount == 0) //Run this only the first time
{
bootCount = bootCount + 1;
}
pinMode(LED1, OUTPUT); //for PCB LED
if (VCCPOWER >= 0)
{
pinMode(VCCPOWER, OUTPUT);
digitalWrite(VCCPOWER, HIGH); //VCCOUT off
}
}

View File

@@ -0,0 +1,92 @@
/*******************************************************************************************************
Programs for Arduino - Copyright of the author Stuart Robinson - 03/02/20
This program is supplied as is, it is up to the user of the program to decide if the program is
suitable for the intended purpose and free from errors.
*******************************************************************************************************/
/*
****************************************************************************************************************
Program operation - The program flashes a LED connected to the pin defined by LED1, and puts the ESP32 to
light_sleep for a period determined by TIME_TO_SLEEP (in seconds).
The program also has the option of using a logic pin to control the power to the lora.SD card and DS18B20
devices, which can save power in sleep mode. If the hardware is fitted to your board these devices are
powered on by setting the VCCPOWER pin low. If your board does not have this feature set VCCPOWER to -1.
Current in light_sleep mode was 1500uA
****************************************************************************************************************
*/
#define VCCPOWER 14 //when low supplies VCC power to external devices. Set to -1 if not used
#define LED1 2 //On board LED, high for on
#define uS_TO_S_FACTOR 1000000 //Conversion factor for micro seconds to seconds
#define TIME_TO_SLEEP 15 //Time ESP32 will go to sleep (in seconds)
RTC_DATA_ATTR int16_t bootCount = 0;
RTC_DATA_ATTR uint16_t sleepcount = 0;
void loop()
{
Serial.print(F("Bootcount "));
Serial.println(bootCount);
Serial.print(F("Sleepcount "));
Serial.println(sleepcount);
Serial.println(F("LED Flash"));
led_Flash(4, 125);
Serial.println(F("LED On"));
digitalWrite(LED1, HIGH);
delay(2500);
Serial.println(F("LED Off"));
digitalWrite(LED1, LOW);
esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
Serial.println(F("Start Sleep"));
Serial.flush();
sleepcount++;
esp_light_sleep_start();
Serial.println();
Serial.println();
Serial.println(F("Awake !"));
}
void led_Flash(unsigned int flashes, unsigned int delaymS)
{
//flash LED to show tracker is alive
unsigned int index;
for (index = 1; index <= flashes; index++)
{
digitalWrite(LED1, LOW);
delay(delaymS);
digitalWrite(LED1, HIGH);
delay(delaymS);
}
}
void setup()
{
Serial.begin(9600); //setup Serial console ouput
Serial.println(F("50_LightSleep_Timed_Wakeup_ESP32 - Starting"));
if (bootCount == 0) //Run this only the first time
{
bootCount = bootCount + 1;
}
pinMode(LED1, OUTPUT); //for PCB LED
if (VCCPOWER >= 0)
{
pinMode(VCCPOWER, OUTPUT); //For controlling power to external devices
digitalWrite(VCCPOWER, HIGH); //VCCOUT off, lora device and SD card off
}
}

View File

@@ -0,0 +1,87 @@
/*******************************************************************************************************
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 flashes a LED connected to the pin defined by LED1, and puts the ESP32
to deep_sleep. Pressing BOOT switch should wake up the ESP32 from sleep.
Only the specific RTC IO pins can be used as a source for external wakeup.
These are pins: 0,2,4,12-15,25-27,32-39.
Current in deep_sleep for a bare bones ESP32 with regulator and no other devices was 27uA.
Serial monitor baud rate is set at 9600.
*******************************************************************************************************/
#define LED1 2 //pin number for LED
#define SWITCH1 0 //pin number wakeup switch
RTC_DATA_ATTR int16_t bootCount = 0;
RTC_DATA_ATTR uint16_t sleepcount = 0;
void loop()
{
Serial.print(F("Bootcount "));
Serial.println(bootCount);
Serial.print(F("Sleepcount "));
Serial.println(sleepcount);
Serial.println(F("LED Flash"));
led_Flash(4,125);
Serial.println(F("LED On"));
digitalWrite(LED1, HIGH);
delay(2500);
Serial.println(F("LED Off"));
digitalWrite(LED1, LOW);
//esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
esp_sleep_enable_ext0_wakeup(GPIO_NUM_0, 0); //wakeup on pin GPIO0 going low
Serial.println(F("Start Sleep"));
Serial.flush();
sleepcount++;
esp_deep_sleep_start();
Serial.println();
Serial.println();
Serial.println(F("Awake ?")); //should not really see this, deep sleep wakeup causes reset ....
}
void led_Flash(unsigned int flashes, unsigned int delaymS)
{
//flash LED to show tracker is alive
unsigned int index;
for (index = 1; index <= flashes; index++)
{
digitalWrite(LED1, LOW);
delay(delaymS);
digitalWrite(LED1, HIGH);
delay(delaymS);
}
}
void setup()
{
Serial.begin(9600); //setup Serial console ouput
Serial.println();
Serial.println();
Serial.println(F("51_DeepSleep_Timed_Wakeup_ESP32 - Starting"));
if(bootCount == 0) //Run this only the first time
{
bootCount = bootCount+1;
}
pinMode(LED1, OUTPUT); //for PCB LED
pinMode(SWITCH1, INPUT_PULLUP); //for wakeup switch
}

View File

@@ -0,0 +1,131 @@
/*******************************************************************************************************
lora Programs for Arduino - Copyright of the author Stuart Robinson - 20/01/20
This program is supplied as is, it is up to the user of the program to decide if the program is
suitable for the intended purpose and free from errors.
*******************************************************************************************************/
/*******************************************************************************************************
Program Operation - When the ESP32 turns on the WiFi function, there is a short high current pulse that
can cause the ESP32 brownout detect to operate.
This test program at startup flashes an LED, leaves it on and then starts the WiFi. If the Wifi initiates
a brownout, you will see the LED flash again. The LED stays on when scanning, the program reports the
networks found to the serial console and displays them on an attached SSD1306 OLED.
Thus if you see the LED continually doing short bursts of flashing the turn on\off the WiFi is causing
the ESP32 to reset. There will also be a message on the serial monitor that the brownout detector operated.
Serial monitor baud rate is set at 9600
*******************************************************************************************************/
#include "WiFi.h"
#define LED1 2 //Arduino pin number for LED, when high LED should be on.
#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
void loop()
{
Serial.println("Set WiFi to Station mode"); //Set WiFi to station mode
Serial.flush();
WiFi.mode(WIFI_STA);
WiFi.disconnect();
delay(1000);
Serial.println("Setup done");
Serial.flush();
digitalWrite(LED1, HIGH);
Serial.println("WiFi scan start");
Serial.flush();
int n = WiFi.scanNetworks(); //WiFi.scanNetworks will return the number of networks found
digitalWrite(LED1, LOW);
delay(500);
disp.clear();
disp.setCursor(0, 0);
if (n == 0) {
Serial.println("No WiFi");
disp.println("No WiFi");
} else {
Serial.print(n);
disp.print(n);
Serial.println(" WiFi found");
disp.println(" WiFi found");
led_Flash(n, 500);
if (n > 16) //only want to display first 16 networks
{
n = 16;
}
for (int i = 0; i < n; ++i) {
//Print SSID and RSSI for each network found
Serial.print(i + 1);
Serial.print(": ");
Serial.print(WiFi.SSID(i));
if (i > 7)
{ disp.clearLine(i - 8);
disp.setCursor(0, i - 8);
}
else
{
disp.clearLine(i);
disp.setCursor(0, i);
}
disp.print(WiFi.SSID(i));
Serial.print(" (");
Serial.print(WiFi.RSSI(i));
Serial.print(")");
Serial.println((WiFi.encryptionType(i) == WIFI_AUTH_OPEN) ? " " : "*");
if (i == 7) //check if 8 lines have already been sent to display
{
delay(2000); //leave last 8 on display for a while
disp.clear();
}
}
}
Serial.println();
disp.println();
// Wait a bit before scanning again
delay(5000);
}
void led_Flash(unsigned int flashes, unsigned int delaymS)
{
//flash LED
unsigned int index;
for (index = 1; index <= flashes; index++)
{
digitalWrite(LED1, HIGH);
delay(delaymS);
digitalWrite(LED1, LOW);
delay(delaymS);
}
}
void setup()
{
pinMode(LED1, OUTPUT);
led_Flash(5, 50);
digitalWrite(LED1, LOW);
delay(1000);
Serial.begin(9600);
disp.begin();
disp.setFont(u8x8_font_chroma48medium8_r);
disp.clear();
disp.setCursor(0, 0);
disp.print(F("Scanner Ready"));
}

View File

@@ -0,0 +1,35 @@
/*******************************************************************************************************
Programs for Arduino - Copyright of the author Stuart Robinson - 20/01/20
This program is supplied as is, it is up to the user of the program to decide if the program is
suitable for the intended purpose and free from errors.
*******************************************************************************************************/
//******* Setup hardware pin definitions here ! ***************
//These are the pin definitions for one of the Tracker boards, the ESP32_Micro_Node, be sure to change
//them to match your own setup. You will also need to connect up the pins for the SPI bus, which on the
//ESP32_Micro_Node are SCK on pin 18, MISO on pin 19 and MOSI on pin 23. Some pins such as DIO1, DIO2 and
//BUZZER may not be in used by this sketch so they do not need to be connected and should be set to -1.
#define SWITCH1 0 //pin number for switch, the boot switch also
#define LED1 2 //pin number for LED
#define NSS 5 //pin number where the NSS line for the LoRa device is connected
#define SDCS 13 //ESP32 pin number for device select on SD card module
#define VCCPOWER 14 //pin controls power to external devices
#define DIO2 15 //pin number for DIO2 pin on LoRa device
#define TonePin 15 //pin number for LoRa radio tone generation, connects to LoRa device pin DIO2
#define GPSTX 16 //pin number for TX output from Arduino - RX into GPS
#define GPSRX 17 //pin number for RX input into Arduino - TX from GPS
#define BATREAD 25 //pin that switches on supply measure resistor devider
#define GPSPOWER 26 //pin controls power to external devices
#define NRESET 27 //pin where LoRa device reset line is connected
#define ONEWIREBUS 33 //pin for one wire bus devices
#define DIO1 34 //pin connected to DIO1 on LoRa device
#define DIO0 35 //pin number for DIO0 pin on LoRa device
#define SupplyAD 36 //pin for reading supply voltage
#define ADMultiplier 10 //multiplier for supply volts calculation, default

View File

@@ -0,0 +1,125 @@
/*******************************************************************************************************
Programs for Arduino - Copyright of the author Stuart Robinson - 27/06/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 test for a Bosch BME280 sensor. Readings are sent to the serial
monitor.
Serial monitor baud rate is set at 9600.
*******************************************************************************************************/
#include <Seeed_BME280.h> //get library here; https://github.com/Seeed-Studio/Grove_BME280
BME280 bme280; //create an instance of the BME280 senosor
#define BME280_ADDRESS 0x76 //I2C bus address of BME280
#define BME280_REGISTER_CONTROL 0xF4 //BME280 register number for power control
#include <Wire.h>
#define LED1 2 //on board LED, high for on
float temperature; //the BME280 temperature value
float pressure; //the BME280 pressure value
uint16_t humidity; //the BME280 humididty value
void loop()
{
Serial.print(F("Reading > "));
readSensors(); //read the sensor values
printSensorValues(); //print the sensor values
Serial.println();
sleepBME280();
delay(5000);
normalBME280(); //BME280 sensor to normal mode
}
void readSensors()
{
//read the sensor values into the global variables
temperature = bme280.getTemperature();
pressure = bme280.getPressure();
humidity = bme280.getHumidity();
}
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("%"));
Serial.print(F(" "));
Serial.flush();
}
void sleepBME280()
{
//write this register value to BME280 to put it to sleep
writeBME280reg(BME280_REGISTER_CONTROL, B01111100);
}
void normalBME280()
{
//write this register value to BME280 to put it to read mode
writeBME280reg(BME280_REGISTER_CONTROL, B01111111);
}
void writeBME280reg(uint8_t reg, uint8_t 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();
}
void led_Flash(uint16_t flashes, uint16_t delaymS)
{
uint16_t index;
for (index = 1; index <= flashes; index++)
{
digitalWrite(LED1, HIGH);
delay(delaymS);
digitalWrite(LED1, LOW);
delay(delaymS);
}
}
void setup()
{
pinMode(LED1, OUTPUT); //for PCB LED
led_Flash(2, 125);
Serial.begin(9600);
Serial.println();
Serial.println(F("81_BME280_Test_ESP32 starting"));
bme280.init(); //intialise BME280 library
Wire.begin(); //default for ESP32 is SDA on 21, SCL on 22
//alternative pins for I2C, ESP32 allows re-direction of I2C, format is Wire.begin(SDA,SCL);
//The SeedBME280 library does do a Wire.begin(); so this will overide it
Wire.begin(16,17);
Serial.println(F("Initialised BME280"));
Serial.println();
readSensors(); //do an initial sensor read
}

View File

@@ -0,0 +1,86 @@
/*******************************************************************************************************
Programs for Arduino - Copyright of the author Stuart Robinson - 20/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.
*******************************************************************************************************/
/*******************************************************************************************************
Program Operation - This program is a simple test program for the SSD1306 and SH1106 OLEDs. The program
prints a short message on each line, pauses, clears the screen, and starts again.
OLED address is defined as 0x3C.
Serial monitor baud rate is set at 9600.
*******************************************************************************************************/
#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
#define DEFAULTFONT u8x8_font_chroma48medium8_r //font for U8X8 Library
#define OLED_Address 0x3C
uint16_t writecount;
uint32_t startwritemS, endwritemS, timemS;
void loop()
{
writecount++;
Serial.print(writecount);
Serial.print(F(" Writing to display"));
disp.setI2CAddress(OLED_Address<<1); //I2C address multiplied by 2, the lowest bit must be zero
disp.setFont(DEFAULTFONT);
startwritemS = millis();
disp.clear();
screen1();
endwritemS = millis();
timemS = endwritemS - startwritemS;
disp.setCursor(8, 3);
disp.print(timemS);
disp.print(F("mS"));
Serial.print(F(" - done "));
Serial.print(timemS);
Serial.println(F("mS"));
delay(2000);
Serial.println(F("PowerSave display"));
disp.setPowerSave(1); //power save display, turns off
delay(2000);
disp.setPowerSave(0); //display back to normal
}
void screen1()
{
disp.setCursor(0, 0);
disp.print(F("Hello World !"));
disp.setCursor(0, 1);
disp.print(F("Line 1"));
disp.setCursor(0, 2);
disp.print(F("Line 2"));
disp.setCursor(0, 3);
disp.print(F("Line 3"));
disp.setCursor(0, 4);
disp.print(F("Line 4"));
disp.setCursor(0, 5);
disp.print(F("Line 5"));
disp.setCursor(0, 6);
disp.print(F("Line 6"));
disp.setCursor(0, 7);
disp.print(F("0123456789012345")); //display is 8 lines x 16 charaters when using the
//u8x8_font_chroma48medium8_r font
}
void setup()
{
Serial.begin(9600);
Serial.println(F("31_SSD1306_OLED_Checker starting"));
disp.begin();
}

View File

@@ -0,0 +1,636 @@
## SX12XX Library Example Programs
For the majority of the program examples you will need to define the pins used, the frequency and the LoRa settings in the Settings.h file. The default provided settings may not be optimised for long distance. See the 'What is LoRa' document for information on how LoRa settings affect range.
Some of the examples use sleep mode on the processor and LoRa device to save power. Typical sleep currents may be mentioned in the description of the program. In most all cases a 'bare bones' Arduino has been used to measure the sleep currents and you may not get even close to the quoted figures using standard Arduinos such as Pro Minis or similar. Optimising particular Arduino boards for low power sleep is outside of the scope of this library and examples.
#### 1\_LED\_Blink &emsp; &emsp; &emsp; &emsp; &emsp; &emsp; (Basics folder)
This program blinks an LED connected the pin number defined by LED1.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.
#### 2\_Register\_Test &emsp; &emsp; &emsp; &emsp; &emsp; &emsp; (Basics folder)
This program is stand alone, it is not necessary to install the SX12XX-LoRa library to use it.
The program checks that a 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 different to the programmed frequency, there is a rounding error due to the use of floats to calculate the frequency.
SX1276-79 Selected
LoRa Device found
Device version 0x12
Frequency at reset 434000000
Registers at reset
Reg 0 1 2 3 4 5 6 7 8 9 A B C D E F
0x00 00 09 1A 0B 00 52 6C 80 00 4F 09 2B 20 08 02 0A
0x10 FF 70 15 0B 28 0C 12 47 32 3E 00 00 00 00 00 40
0x20 00 00 00 00 05 00 03 93 55 55 55 55 55 55 55 55
0x30 90 40 40 00 00 0F 00 00 00 F5 20 82 04 02 80 40
0x40 00 00 12 24 2D 00 03 00 04 23 00 09 05 84 32 2B
0x50 14 00 00 10 00 00 00 0F E0 00 0C 04 06 00 5C 78
0x60 00 19 0C 4B CC 0D FD 20 04 47 AF 3F F2 3F D9 0B
0x70 D0 01 10 00 00 00 00 00 00 00 00 00 00 00 00 00
Changed Frequency 434099968
Reg 0 1 2 3 4 5 6 7 8 9 A B C D E F
0x00 00 09 1A 0B 00 52 6C 86 66 4F 09 2B 20 08 02 0A
0x10 FF 70 15 0B 28 0C 12 47 32 3E 00 00 00 00 00 40
0x20 00 00 00 00 05 00 03 93 55 55 55 55 55 55 55 55
0x30 90 40 40 00 00 0F 00 00 00 F5 20 82 04 02 80 40
0x40 00 00 12 24 2D 00 03 00 04 23 00 09 05 84 32 2B
0x50 14 00 00 10 00 00 00 0F E0 00 0C 04 06 00 5C 78
0x60 00 19 0C 4B CC 0D FD 20 04 47 AF 3F F2 3F D9 0B
0x70 D0 01 10 00 00 00 00 00 00 00 00 00 00 00 00 00
#### 3\_LoRa\_Transmitter &emsp; &emsp; &emsp; &emsp; &emsp; &emsp; (Basics folder)
This is a minimum setup LoRa test transmitter. A packet containing the ASCII text "Hello World 1234567890" is sent using the frequency and LoRa settings specified in the LT.setupLoRa() command. The pins to access the lora device need to be defined at the top of the program also.
The details of the packet sent and any errors are shown on the Arduino IDE Serial Monitor, together with the transmit power used and the packet length. The matching receiver program, '4\_LoRa\_Receiver' can be used
to check the packets are being sent correctly, the frequency and LoRa settings (in the LT.setupLoRa() commands) must be the same for the transmitter and receiver programs. Sample Serial Monitor output;
10dBm Packet> Hello World 1234567890 BytesSent,23 PacketsSent,6
For an example of a more detailed configuration for a transmitter, see program 103\_LoRa\_Transmitter.
Serial monitor baud rate is set at 9600
#### 4\_LoRa\_Receiver &emsp; &emsp; &emsp; &emsp; &emsp; &emsp; (Basics folder)
This is a minimum setup LoRa test receiver. The program listens for incoming packets using the frequency and LoRa settings in the LT.setupLoRa() command. The pins to access the lora device need to be defined at the top of the program 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. Sample serial monitor output;
8s Hello World 1234567890,RSSI,-44dBm,SNR,9dB,Length,23,Packets,7,Errors,0,IRQreg,50
If there is a packet error it might look like this, which is showing a CRC error;
137s PacketError,RSSI,-89dBm,SNR,-8dB,Length,23,Packets,37,Errors,2,IRQreg,70,IRQ\_HEADER\_VALID,IRQ\_CRC\_ERROR,IRQ\_RX\_DONE
If there are no packets received in a 10 second period then you should see a message like this;
112s RXTimeout
For an example of a more detailed configuration for a receiver, see program 104\_LoRa\_Receiver.
Serial monitor baud rate is set at 9600.
<br>
#### 5\_LoRa\_TX\_Sleep\_Timed\_Wakeup\_Atmel &emsp; &emsp; &emsp; &emsp; &emsp; &emsp; (Sleep folder)
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 6.5uA.
#### 6\_LoRa\_RX\_and\_Sleep\_Atmel &emsp; &emsp; &emsp; &emsp; &emsp; &emsp; (Sleep folder)
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.
When the program starts the LoRa device is set-up to receive packets with pin DIO0 set to go high when a packet arrives. The receiver remains powered (it cannot receive otherwise) and the processor (Atmel ATMega328P or 1284P) is put to sleep. When pin DIO0 does go high, indicating a packet is received, the processor wakes up and prints the packet. It then goes back to sleep.
There is a printout of the valid packets received, these are assumed to be in ASCII printable text. The LED will flash for each packet received and the buzzer will sound,if fitted.
Tested on a 'bare bones' ATmega328P board, the current in sleep mode was 12.26mA.
#### 7\_LoRa\_TX\_Sleep\_Switch\_Wakeup\_Atmel &emsp; &emsp; &emsp; &emsp; &emsp; &emsp; (Sleep folder)
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 should remain asleep until the pin defined by SWITCH1 in the Settings.h file is connected to ground and the LoRa device register values should be retained. The LoRa 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 2.4uA.
#### 8\_LoRa\_LowMemory\_TX &emsp; &emsp; &emsp; &emsp; &emsp; &emsp; (LowMemory folder)
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 omitted.
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
#### 9\_LoRa\_LowMemory\_RX &emsp; &emsp; &emsp; &emsp; &emsp; &emsp; (LowMemory folder)
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 omitted.
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
#### 10\_LoRa\_Link\_Test\_Transmitter &emsp; &emsp; &emsp; &emsp; &emsp; &emsp; (Diagnostics and Test folder)
This is a program that can save you a great deal of time if your testing the effectiveness of a LoRa links or 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,-03dBm,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.
#### 11\_LoRa\_Packet\_Logger\_Receiver &emsp; &emsp; &emsp; &emsp; &emsp; &emsp; (Diagnostics and Test folder)
This is a useful packet logger program. It 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.
#### 12\_ATmel\_Sleep\_with\_Switch\_Wakeup &emsp; &emsp; &emsp; &emsp; &emsp; &emsp; (Hardware_Checks folder)
This program tests the deep sleep mode and wakeup with a switch of an Atmel 328P or 1284P processor. The program starts, flashes the LED and then puts the processor into permanent sleep. It can be woken up with a switch press. Used as a base test routine for checking the sleep current of a board.
Tested on an 'bare bones' ATmega328P board, the current in sleep mode was 1.7uA with a 3.3V MCP1700 regulator being used.
#### 13\_Frequency\_and\_Power\_Check\_TX &emsp; &emsp; &emsp; &emsp; &emsp; &emsp; (Diagnostics and Test folder)
This is a program that transmits a long LoRa packets lasting about 5 seconds that can be used to measure the frequency and power of the transmission using external equipment. The bandwidth of the transmission is only 10khz, so a frequency counter should give reasonable average result.
The LoRa settings to use, including transmit power, are specified in the 'Settings.h' file.
#### 14\_LoRa\_Structure\_TX &emsp; &emsp; &emsp; &emsp; &emsp; &emsp; (Basics folder)
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 structure 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
#### 15\_LoRa\_Structure\_RX &emsp; &emsp; &emsp; &emsp; &emsp; &emsp; (Basics folder)
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
#### 16\_LoRa\_RX\_Frequency\_Error\_Check &emsp; &emsp; &emsp; &emsp; &emsp; &emsp; (Diagnostics and Test folder)
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\_Transmitter'.
#### 17\_Sensor\_Transmitter &emsp; &emsp; &emsp; &emsp; &emsp; &emsp; (Sensor folder)
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 micro controller are put to sleep in units of 8 seconds using the Atmel processor internal watchdog.
The pin definitions, LoRa frequency and LoRa modem settings are in the Settings.h file. The 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 175mAh battery, to see how long the battery actually lasts.
#### 18\_Sensor\_Receiver &emsp; &emsp; &emsp; &emsp; &emsp; &emsp; (Sensor folder)
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\_Transmitter' 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 set-up to set the DIO0 pin high when a packet is received, the Atmel processor is then put to sleep and will wake up 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. Between readings the sensor transmitter is put to sleep in units of 8 seconds using the Atmel
processor internal watchdog.
For the sensor data to be accepted as valid the flowing 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 that's 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.
#### 20\_LoRa\_Link\_Test\_Receiver &emsp; &emsp; &emsp; &emsp; &emsp; &emsp; (Diagnostics and Test folder)
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\_TX'. 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.
#### 21\_On\_Off\_Transmitter &emsp; &emsp; &emsp; &emsp; &emsp; &emsp; (Remote Control folder)
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 micro controller 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 set-up 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.
#### 22\_On\_Off\_Receiver &emsp; &emsp; &emsp; &emsp; &emsp; &emsp; (Remote Control folder)
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 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.
#### 23\_GPS\_Tracker\_Transmitter &emsp; &emsp; &emsp; &emsp; &emsp; &emsp; (Tracker folder)
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 start-up 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 likely 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, if the GPS module being used has this feature. To use the option change the define in the Settings.h file; '#define GPSPOWER -1' from -1 to the pin number being used. Also set the GPSONSTATE and GPSOFFSTATE to the appropriate logic levels.
#### 24\_GPS\_Tracker\_Receiver &emsp; &emsp; &emsp; &emsp; &emsp; &emsp; (Tracker folder)
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.
#### 25\_GPS\_Tracker\_Receiver\_with\_Display\_and\_GPS &emsp; &emsp; &emsp; &emsp; &emsp; &emsp; (Tracker folder)
This program is an example of a basic portable GPS tracker receiver. The program receives the location packets from the remote tracker and displays them on an OLED display. The program also reads a local 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 received information is printed to screen in this order top to bottom;
Latitude, Longitude, Altitude, HDOP, GPS Fixtime, Tracker battery mV, Number of received packets, Distance and direction to tracker, if local GPS fix. In addition if there is a recent tracker transmitter GPS fix a 'T' is shown on line 0 right of screen and if there is a recent local (receiver) GPS fix a 'R' is displayed line 1 right of screen.
The received information is printed to the Serial Monitor as CSV data in this order;
Packet Address information, Latitude, Longitude, Altitude, Satellites in use, HDOP, TX status byte, GPS Fixtime, Tracker battery mV, Number of received packets, Distance and direction to tracker, if local GPS fix.
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 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.
#### 26\_GPS\_Echo &emsp; &emsp; &emsp; &emsp; &emsp; &emsp; (Hardware_Checks folder)
This is a simple program to test a GPS. It reads characters from the GPS using software serial and sends them (echoes) to the IDE serial monitor. If your ever having problems with a GPS (or just think you are) use this program first.
If you get no data displayed on the serial monitor, the most likely cause is that you have the receive data pin into the Arduino (RX) pin connected incorrectly.
If the data displayed on the serial terminal appears to be random text with odd symbols its very likely you have the GPS serial baud rate set incorrectly.
Note that not all pins on all Arduinos will work with software serial, see here;
https://www.arduino.cc/en/Reference/softwareSerial
Serial monitor baud rate is set at 115200.
#### 28\_GPS\_Checker &emsp; &emsp; &emsp; &emsp; &emsp; &emsp; (Hardware_Checks folder)
This program is a portable GPS checker and display. At start-up the program starts checking the data coming from the GPS for a valid fix. It checks for 5 seconds and if there is no fix, prints a message on the serial monitor. During this time the data coming from the GPS is copied to the serial monitor also.
When the program detects that the GPS has a fix, it prints the Latitude, Longitude, Altitude, Number of satellites in use and the HDOP value to the serial monitor.
Serial monitor baud rate is set at 115200, GPS baud rate to 9600, both are configured in setup().
#### 29\_GPS\_Checker\_With\_Display &emsp; &emsp; &emsp; &emsp; &emsp; &emsp; (Hardware_Checks folder)
This program is a GPS checker with a display output. It uses an SSD1306 or SH1106 128x64 I2C OLED display. At start-up the program starts checking the data coming from the GPS for a valid fix. It reads the GPS for 5 seconds and if there is no fix, prints a message on the serial monitor and updates the seconds without a fix on the display. During this time the data coming from the GPS is copied to the serial monitor also.
When the program detects that the GPS has a fix, it prints the Latitude, Longitude, Altitude, Number of satellites in use, the HDOP value, time and date to the serial monitor. If the I2C OLED display is attached that is updated as well. Display is assumed to be on I2C address 0x3C.
#### 30\_I2C\_Scanner &emsp; &emsp; &emsp; &emsp; &emsp; &emsp; (Hardware_Checks folder)
The program scans the I2C bus and displays the addresses of any devices found. Useful first check when using I2C devices.
#### 31\_SSD1306\_OLED\_Checker &emsp; &emsp; &emsp; &emsp; &emsp; &emsp; (Diagnostics and Test folder)
This program is a simple test program for the SSD1306 and SH1106 OLEDs. The program prints a short message on each line, pauses, clears the screen, and starts again.
OLED address is defined as 0x3C.
#### 33\_LoRa\_RSSI\_Checker\_With\_Display &emsp; &emsp; &emsp; &emsp; &emsp; &emsp; (Diagnostics and Test folder)
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.
#### 34\_ATmel\_Sleep\_with\_Watchdog\_Wakeup &emsp; &emsp; &emsp; &emsp; &emsp; &emsp; (Hardware_Checks folder)
This program tests the sleep mode of an Atmel ATMega328P processor.
At power up the flashes an LED 4 times, then turns on the LED for 5 seconds. Then the processor is put to sleep for 8 seconds. On wakeup the LED flashes twice, then is on for 5 seconds and the board goes to sleep again. And the sequence repeats.
Sleep current for a 'bare bones' ATmega328 with a MCP1700 regulator @ 3.3V and using an external event such as a switch to wakeup from sleep should be around 2uA. Using the watchdog timer to wakeup raises the deep sleep current to circa 6.2uA.
#### 35\_Remote\_Control\_Servo\_Transmitter &emsp; &emsp; &emsp; &emsp; &emsp; &emsp; (Remote Control folder)
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 positions 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.
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 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 - 255. The receiver must be set-up 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.
#### 36\_Remote\_Control\_Servo\_Receiver &emsp; &emsp; &emsp; &emsp; &emsp; &emsp; (Remote Control folder)
This is a remote control receiver that uses a LoRa link to control the positions of servos sent from a remote transmitter.
If the transmitter 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 set-up 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.
#### 37\_Servo\_Sweep\_Tester &emsp; &emsp; &emsp; &emsp; &emsp; &emsp; (Hardware_Checks folder)
This program sweeps two servos from one end of their travel to the other. Useful to check servos are connected correctly and working.
#### 38\_lora\_Relay &emsp; &emsp; &emsp; &emsp; &emsp; &emsp; (Tracker folder)
This program will receive a lora packet and relay (re-transmit) it. The receiving and transmitting can use different frequencies and lora settings. The receiving and transmitting settings are in the 'Settings.h' file. For an example of it's use see this report;
How to Search 500 Square Kilometres in 10 minutes.pdf in the libraries 'Test_Reports' folder.
#### 40\_LoRa\_Transmitter\_ImplicitPacket &emsp; &emsp; &emsp; &emsp; &emsp; &emsp; (Implicit folder)
This is an example of the use of implicit or fixed length LoRa packets.
Implicit packets have no header so both transmitter and receiver need to be programmed with the packet length in use. The use of spreading factor 6 requires implicit packets and together with a bandwidth of 500khz, leads to the shortest possible and lowest air time packets.
This example sends a buffer that is 23 characters long and that length must be defined in Settings.h as the constant 'PacketLength'.
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, '41\_LoRa\_Receiver\_ImplicitPackets' 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,8mS PacketsSent,1
#### 41\_LoRa\_Receiver\_ImplicitPacket &emsp; &emsp; &emsp; &emsp; &emsp; &emsp; (Implicit folder)
This is an example of the use of implicit or fixed length LoRa packets. Implicit packets have no header so both transmitter and receiver need to be programmed with the packet length in use. The use of spreading factor 6 requires implicit packets and together with a bandwidth of 500khz, leads to the shortest possible and lowest air time packets. The program listens for incoming packets using the LoRa settings in the 'Settings.h'.
This example receives a buffer that is 19 characters long and that length must be defined in Settings.h as the constant 'PacketLength'.
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
#### 42\_WiFi\_Scanner\_Display\_ESP32 &emsp; &emsp; &emsp; &emsp; &emsp; &emsp; (Hardware Checks\ESP32 folder)
When the ESP32 turns on the WiFi function, there is a short high current pulse that can cause the ESP32 brownout detect to operate.
This test program at startup flashes an LED, leaves it on and then starts the WiFi. If the Wifi initiates a brownout, you will see the LED flash again. The LED stays on when scanning, the program reports the networks found to the serial console and displays them on an attached SSD1306 OLED.
Thus if you see the LED continually doing short bursts of flashing the turn on off the WiFi is causing the ESP32 to reset. There will also be a message on the serial monitor that the brownout detector operated.
#### 43\_SD\_Card\_Test\_ESP32 &emsp; &emsp; &emsp; &emsp; &emsp; &emsp; (Hardware Checks\ESP32 folder)
This test program has been written to check that a connected SD card adapter, Micro or standard, is functional. To use the program first copy the file (in this programs directory) called testfile.txt to the root directory of the SD card.
When the program runs it will attempt to open 'testfile.txt' and spool the contents to the Arduino IDE serial monitor. The testfile is part of the source code for the Apollo 11 Lunar Lander navigation and guidance computer. There are LED flashes at power up or reset, then at start of every loop of the test. The LED is on whilst the testfile is being read. If the LED flashes very rapidly then there is a problem accessing the SD card.
The program also has the option of using a logic pin to control the power to the lora and SD card devices, which can save power in sleep mode. If the hardware is fitted to your board these devices are powered on by setting the VCCPOWER pin low. If your board does not have this feature set VCCPOWER to -1.
#### 44\_SD\_Card\_Test\_With\_FS\_ESP322 &emsp; &emsp; &emsp; &emsp; &emsp; &emsp; (Hardware Checks\ESP32 folder)
This test program has been written to check that a connected SD card adapter, Micro or standard, is functional with the FS functions. To use the program first copy the file (in this programs directory) called testfile.txt to the root directory of the SD card.
When the program runs it will attempt to open 'testfile.txt' and spool the contents to the Arduino IDE serial monitor. The testfile is part of the source code for the Apollo 11 Lunar Lander navigation and guidance computer. There are LED flashes at power up or reset, then at start of every loop of the test. The LED is on whilst the testfile is being read. If the LED flashes very rapidly then there is a problem accessing the SD card.
The program also has the option of using a logic pin to control the power to the lora and SD card devices, which can save power in sleep mode. If the hardware is fitted to your board these devices are powered on by setting the VCCPOWER pin low. If your board does not have this feature set VCCPOWER to -1.
#### 45\_Battery\_Voltage\_Read\_Test &emsp; &emsp; &emsp; &emsp; &emsp; &emsp; (Hardware_Checks folder)
This test program has been written to check that hardware for reading the battery voltage has been assembled correctly such that it is funtional. The value defined as 'ADMultiplier' in settings.h is used to adjust the value read from the 91K\11K resistor divider and convert into mV.
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.
#### 47\_DeepSleep\_Timed\_Wakeup\_ESP32 &emsp; &emsp; &emsp; &emsp; &emsp; &emsp; (Hardware_Checks\ESP32 folder)
This program flashes a LED connected to the pin defined by LED1, and puts the ESP32 to deep_sleep for a period determined by the TIME_TO_SLEEP variable (in seconds).
The program also has the option of using a logic pin to control the power to the lora and SD card devices, which can save power in sleep mode. If the hardware is fitted to your board these devices are powered on by setting the VCCPOWER pin low. If your board does not have this feature set VCCPOWER to -1.
Current in deep_sleep for a bare bones ESP32 with regulator and no other devices was 27uA.
#### 48\_DS18B20\_Test &emsp; &emsp; &emsp; &emsp; &emsp; &emsp; (Hardware_Checks folder)
The program reads a single DS18B20 temperature sensor and prints the result to the serial monitor.
The program also has the option of using a logic pin to control the power to the lora and SD card devices, which can save power in sleep mode. If the hardware is fitted to your board then these devices are assumed to be powered on by setting the VCCPOWER pin low. If your board does not have this feature set VCCPOWER to -1.
#### 50\_LightSleep\_Timed\_Wakeup\_ESP32 &emsp; &emsp; &emsp; &emsp; &emsp; &emsp; (ESP32 folder)
The program flashes a LED connected to the pin defined by LED1, and puts the ESP32 to light_sleep for a period determined by TIME_TO_SLEEP (in seconds).
The program also has the option of using a logic pin to control the power to the lora device, SD card and DS18B20 devices, which can save power in sleep mode. If the hardware is fitted to your board these devices are powered on by setting the VCCPOWER pin low. If your board does not have this feature set VCCPOWER to -1.
#### 51\_DeepSleep\_Switch\_Wakeup\_ESP32 &emsp; &emsp; &emsp; &emsp; &emsp; &emsp; (ESP32 folder)
The program flashes a LED connected to the pin defined by LED1, and puts the ESP32 to deep_sleep. Pressing BOOT switch should wake up the ESP32 from sleep.
Only the specific RTC IO pins can be used as a source for external wakeup.
These are pins: 0,2,4,12-15,25-27,32-39.
Current in deep sleep for a bare bones ESP32 with regulator and no other devices was 27uA.
#### 52\_FLRC\_Transmitter &emsp; &emsp; &emsp; &emsp; &emsp; &emsp; (SX128X\Examples\Basics folder)
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
#### 53\_FLRC\_Receiver &emsp; &emsp; &emsp; &emsp; &emsp; &emsp; (SX128X_Examples\Basics folder)
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
#### 58\_FM\_Tone &emsp; &emsp; &emsp; &emsp; &emsp; &emsp; (Basics folder)
Transmits a FM tone using the LoRa device that can be picked up on an FM UHF handheld receiver. The tones are not true FM but the UHF receiver does not know that.
#### 59\_Play\_Star\_Wars\_Tune &emsp; &emsp; &emsp; &emsp; &emsp; &emsp; (Silly folder)
A silly program really, but does demonstrate that you can shift a carrier generated by the LoRa device in FSK mode fast enough to play audio tones that can be picked up on an FM UHF handheld receiver. The tones are not true FM but the receiver does not know that.
#### 60\_LoRa\_Packet\_Logger\_Receiver\_SD &emsp; &emsp; &emsp; &emsp; &emsp; &emsp; (Diagnostics and Test folder)
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.
#### 103\_LoRa\_Transmitter\_Detailed\_Setup &emsp; &emsp; &emsp; &emsp; &emsp; &emsp; (Basics folder)
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
#### 104\_LoRa\_Receiver\_Detailed\_Setup &emsp; &emsp; &emsp; &emsp; &emsp; &emsp; (Basics folder)
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.

View File

@@ -0,0 +1,188 @@
/*******************************************************************************************************
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.
*******************************************************************************************************/
/*******************************************************************************************************
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 <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
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, SW, 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, Optimisation);
//***************************************************************************************************
//Setup LoRa device
//***************************************************************************************************
LT.setMode(MODE_STDBY_RC);
LT.setRegulatorMode(USE_DCDC);
LT.setPaConfig(0x04, PAAUTO, LORA_DEVICE);
LT.setDIO3AsTCXOCtrl(TCXO_CTRL_3_3V);
LT.calibrateDevice(ALLDevices); //is required after setting TCXO
LT.calibrateImage(Frequency);
LT.setDIO2AsRfSwitchCtrl();
LT.setPacketType(PACKET_TYPE_LORA);
LT.setRfFrequency(Frequency, Offset);
LT.setModulationParams(SpreadingFactor, Bandwidth, CodeRate, Optimisation);
LT.setBufferBaseAddress(0, 0);
LT.setPacketParams(8, LORA_PACKET_VARIABLE_LENGTH, 255, LORA_CRC_ON, LORA_IQ_NORMAL);
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.setHighSensitivity(); //set for maximum gain
LT.setSyncWord(LORA_MAC_PRIVATE_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();
LT.printRegisters(0x00, 0x4F); //print contents of device registers, normally 0x00 to 0x4F
Serial.println();
Serial.println();
Serial.print(F("Transmitter ready"));
Serial.println();
}

View File

@@ -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, 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 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 SW -1 //SW pin on some Dorji LoRa devices, used to power antenna switch, set to -1 if not used
#define LED1 8 //on board LED, high for on
#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
//for SX1262, SX1268 power range is +22dBm to -9dBm
//for SX1261, power range is +15dBm t0 -9dBm
const int8_t TXpower = 10; //LoRa transmit power in dBm
const uint16_t packet_delay = 1000; //mS delay between packets

View File

@@ -0,0 +1,254 @@
/*******************************************************************************************************
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.
*******************************************************************************************************/
/*******************************************************************************************************
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 <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
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, 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); //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, Optimisation);
//***************************************************************************************************
//Setup LoRa device
//***************************************************************************************************
LT.setMode(MODE_STDBY_RC);
LT.setRegulatorMode(USE_DCDC);
LT.setPaConfig(0x04, PAAUTO, LORA_DEVICE);
LT.setDIO3AsTCXOCtrl(TCXO_CTRL_3_3V);
LT.calibrateDevice(ALLDevices); //is required after setting TCXO
LT.calibrateImage(Frequency);
LT.setDIO2AsRfSwitchCtrl();
LT.setPacketType(PACKET_TYPE_LORA);
LT.setRfFrequency(Frequency, Offset);
LT.setModulationParams(SpreadingFactor, Bandwidth, CodeRate, Optimisation);
LT.setBufferBaseAddress(0, 0);
LT.setPacketParams(8, LORA_PACKET_VARIABLE_LENGTH, 255, LORA_CRC_ON, LORA_IQ_NORMAL);
LT.setDioIrqParams(IRQ_RADIO_ALL, (IRQ_RX_DONE + IRQ_RX_TX_TIMEOUT), 0, 0); //set for IRQ on TX done and timeout on DIO1
LT.setHighSensitivity(); //set for maximum gain
LT.setSyncWord(LORA_MAC_PRIVATE_SYNCWORD);
//***************************************************************************************************
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, normally 0x00 to 0x4F
Serial.println();
Serial.println();
Serial.print(F("Receiver ready - RXBUFFER_SIZE "));
Serial.println(RXBUFFER_SIZE);
Serial.println();
}

View File

@@ -0,0 +1,49 @@
/*******************************************************************************************************
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 //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 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 SW -1 //SW pin on some Dorji LoRa devices, used to power antenna switch, set to -1 if not used
#define LED1 8 //on board LED, high for on
#define BUZZER 4 //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 = 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,145 @@
/*******************************************************************************************************
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.
*******************************************************************************************************/
/*******************************************************************************************************
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 <SX126XLT.h>
#include "Settings.h"
SX126XLT 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, SW, 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, Optimisation);
Serial.println(F("Transmitter ready"));
Serial.println();
}

View File

@@ -0,0 +1,41 @@
/*******************************************************************************************************
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 //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 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 = 10; //LoRa transmit power in dBm
const uint16_t packet_delay = 1000; //mS delay between packets

View File

@@ -0,0 +1,194 @@
/*******************************************************************************************************
Programs for Arduino - Copyright of the author Stuart Robinson - 17/12/19
This program is supplied as is, it is up to the user of the program to decide if the program is
suitable for the intended purpose and free from errors.
*******************************************************************************************************/
/*******************************************************************************************************
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 <SX126XLT.h>
#include "Settings.h"
SX126XLT 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, SW, 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, Optimisation);
Serial.print(F("Receiver ready"));
Serial.println();
Serial.println();
}

View File

@@ -0,0 +1,44 @@
/*******************************************************************************************************
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,
//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 BUZZER 4 //pin for buzzer, on when logic high
#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 = 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,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"));
}

View File

@@ -0,0 +1,402 @@
/*******************************************************************************************************
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 program is stand alone, it is not necessary to install the SX12XX-LoRa library
to use it. This test program is for the SX126X LoRa devices.
The program checks that a SX126X 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, SX1261, SX1262,
or SX1268 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
0x800 00 00 00 00 01 07 20 1E 00 10 19 04 0F FF 0F FF
0x810 10 00 10 00 10 00 10 00 00 00 00 00 00 00 00 00
0x820 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x830 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x840 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x850 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x860 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x870 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x880 03 00 00 5F 10 08 00 00 08 05 00 39 30 00 00 0C
0x890 00 00 00 00 00 0F 0A 07 10 00 26 01 01 53 06 07
0x8A0 10 00 AA 20 5A 04 F0 00 56 56 54 43 94 20 40 00
0x8B0 00 83 11 00 01 04 0A 4C 14 0A 2F 01 6B FF FF 00
0x8C0 00 A0 20 00 00 00 AC 00 1C 00 00 AB 05 30 00 00
0x8D0 0C 14 14 40 06 00 00 10 C8 00 00 00 00 00 31 39
0x8E0 90 39 0C 04 40 20 1C 18 03 00 05 04 03 02 01 01
0x8F0 00 00 00 00 30 00 00 00 00 00 00 00 00 00 00 00
0x900 30 00 00 00 00 00 00 00 00 00 00 00 24 04 47 04
0x910 14 12 12 04 00 03 0A 00 15 35 09 00 02 1F 5F 08
0x920 01 04 05 00 00 00 00 00 00 00 00 00 00 00 00 00
0x930 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x940 00 07 00 03 02 00 10 0E 0D 0C 03 04 03 70 0C 00
0x950 00 00 00 04 00 00 00 00 00 00 00 00 00 00 00 00
0x960 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x970 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x980 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x990 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x9A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x9B0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x9C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x9D0 00 00 00 00 00 00 00 00 00 00 00 00 00 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 915000000
Reg 0 1 2 3 4 5 6 7 8 9 A B C D E F
0x880 03 00 00 5F 10 08 00 00 08 05 00 39 30 00 00 0C
Change Frequency 434100000
Reg 0 1 2 3 4 5 6 7 8 9 A B C D E F
0x880 03 00 00 5F 10 08 00 00 08 05 00 1B 21 99 A0 0C
Changed Frequency 434100000
Serial monitor baud rate is set at 9600.
*******************************************************************************************************/
const uint16_t REG_RFFrequency31_24 = 0x088B;
const uint16_t REG_RFFrequency23_16 = 0x088C;
const uint16_t REG_RFFrequency15_8 = 0x088D;
const uint16_t REG_RFFrequency7_0 = 0x088E;
const uint8_t RADIO_WRITE_REGISTER = 0x0D;
const uint8_t RADIO_READ_REGISTER = 0x1D;
const uint8_t RADIO_SET_RFFREQUENCY = 0x86;
const uint8_t DEVICE_SX1261 = 0x01;
const uint8_t DEVICE_SX1262 = 0x00;
const uint8_t DEVICE_SX1268 = 0x02;
//********* 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 //SX126X device select
#define NRESET 9 //SX126X reset pin
#define RFBUSY 7 //SX126X busy pin
#define LED1 8 //for on board LED, put high for on
#define SW -1 //SW pin on Dorji devices is used to turn RF switch on\off, set to -1 if not used
#define LORA_DEVICE DEVICE_SX1262 //define the device, DEVICE_SX1261, DEVICE_SX1262 or DEVICE_SX1268
//**************************************************************/
#include <SPI.h>
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 are not used in this example so are set to -1
if (begin(NSS, NRESET, RFBUSY, -1, -1, -1, SW, LORA_DEVICE))
{
Serial.println(F("LoRa Device found"));
}
else
{
Serial.println(F("No device responding"));
}
}
void loop()
{
uint32_t frequency;
resetDevice(LORA_DEVICE); //reset the device
Serial.println(F("Registers at reset")); //show the all registers following a reset
printRegisters(0x800, 0x9FF);
Serial.println();
Serial.println();
frequency = getFreqInt(); //read the set frequency following a reset
Serial.print(F("Frequency at reset "));
Serial.println(frequency);
printRegisters(0x0880, 0x088F); //show the registers before the frequency change
setRfFrequency(434100000, 0); //change the frequency at reset, in hertz
frequency = getFreqInt(); //read back the changed frequency
Serial.print(F("Change Frequency "));
Serial.println(frequency); //print the changed frequency, did the write work (allow for rounding errors) ?
printRegisters(0x0880, 0x088F); //show the registers after frequency change
frequency = getFreqInt(); //read the set frequency following a reset
Serial.print(F("Changed Frequency "));
Serial.println(frequency);
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 from registers, return as long integer
uint8_t MsbH, MsbL, Mid, Lsb;
uint32_t uinttemp;
float floattemp;
MsbH = readRegister(REG_RFFrequency31_24);
MsbL = readRegister(REG_RFFrequency23_16);
Mid = readRegister(REG_RFFrequency15_8);
Lsb = readRegister(REG_RFFrequency7_0);
floattemp = ( (MsbH * 0x1000000ul) + (MsbL * 0x10000ul) + (Mid * 0x100ul) + Lsb);
floattemp = ((floattemp * 0.95367431640625) / 1000000ul);
uinttemp = (uint32_t)(floattemp * 1000000);
return uinttemp;
}
void printRegisters(uint16_t Start, uint16_t End)
{
//prints the contents of SX126x 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 )
{
//Note RF_Freq = freq_reg*32M/(2^25)-----> freq_reg = (RF_Freq * (2^25))/32
uint8_t Rf_Freq[4];
frequency = frequency + offset;
frequency = ( uint32_t )( ( double )frequency / ( double )0.95367431640625 );
checkBusy();
Rf_Freq[0] = (frequency >> 24) & 0xFF; //MSB
Rf_Freq[1] = (frequency >> 16) & 0xFF;
Rf_Freq[2] = (frequency >> 8) & 0xFF;
Rf_Freq[3] = frequency & 0xFF;//LSB
writeCommand(RADIO_SET_RFFREQUENCY, Rf_Freq, 4);
}
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(uint8_t device)
{
if ( (device == DEVICE_SX1261) | (device == DEVICE_SX1262) | (device == DEVICE_SX1268) )
{
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, int8_t pinSW, uint8_t device)
{
pinMode(pinNSS, OUTPUT);
digitalWrite(pinNSS, HIGH);
pinMode(pinNRESET, OUTPUT);
digitalWrite(pinNRESET, LOW);
pinMode(pinRFBUSY, INPUT);
if (pinDIO1 >= 0)
{
pinMode( pinDIO1, INPUT);
}
if (pinDIO2 >= 0)
{
pinMode(pinDIO2, INPUT);
}
if (pinDIO3 >= 0)
{
pinMode(pinDIO3, INPUT);
}
if (pinSW >= 0)
{
pinMode(pinSW, OUTPUT); //Dorji devices have an SW pin that needs to be set high to power antenna switch
digitalWrite(pinSW, HIGH);
}
resetDevice(device);
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(0x88e); //low byte of frequency setting
writeRegister(0x88e, (Regdata1 + 1));
Regdata2 = readRegister(0x88e); //read changed value back
writeRegister(0x88e, 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]);
}
digitalWrite(NSS, HIGH);
checkBusy();
}

View File

@@ -0,0 +1,123 @@
/*******************************************************************************************************
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.
*******************************************************************************************************/
/*******************************************************************************************************
Program Operation - This is a minimum setup LoRa test transmitter. A packet containing the ASCII text
"Hello World 1234567890" is sent using the frequency and LoRa settings specified in the LT.setupLoRa()
command. The pins to access the lora device need to be defined at the top of the program also.
The details of the packet sent and any errors are shown on the Arduino IDE Serial Monitor, together with
the transmit power used and the packet length. The matching receiver program, '4_LoRa_Receiver' can be used
to check the packets are being sent correctly, the frequency and LoRa settings (in the LT.setupLoRa()
commands) must be the same for the transmitter and receiver programs. Sample Serial Monitor output;
10dBm Packet> Hello World 1234567890* BytesSent,23 PacketsSent,6
For an example of a more detailed configuration for a transmitter, see program 103_LoRa_Transmitter.
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
SX126XLT LT; //create a library class instance called LT
#define NSS 10 //select pin on LoRa device
#define NRESET 9 //reset pin on LoRa device
#define RFBUSY 7 //SX126X busy pin
#define DIO1 3 //DIO1 pin on LoRa device, used for sensing RX and TX done
#define SW 5 //SW pin on LoRa device, used to power antenna switch
#define LORA_DEVICE DEVICE_SX1262 //we need to define the device we are using
#define TXpower 10 //LoRa transmit power in dBm
uint8_t TXPacketL;
uint32_t TXPacketCount;
uint8_t buff[] = "Hello World 1234567890"; //the message to send
void setup()
{
Serial.begin(9600);
Serial.println();
Serial.println(F("3_LoRa_Transmitter Starting"));
SPI.begin();
if (LT.begin(NSS, NRESET, RFBUSY, DIO1, SW, LORA_DEVICE))
{
Serial.println(F("LoRa Device found"));
delay(1000);
}
else
{
Serial.println(F("No device responding"));
while (1);
}
LT.setupLoRa(434000000, 0, LORA_SF7, LORA_BW_125, LORA_CR_4_5, LDRO_AUTO); //configure frequency and LoRa settings
Serial.print(F("Transmitter ready"));
Serial.println();
}
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
if (LT.transmit(buff, TXPacketL, 10000, TXpower, WAIT_TX)) //will return packet length sent if OK, otherwise 0 if transmit error
{
TXPacketCount++;
packet_is_OK();
}
else
{
packet_is_Error(); //transmit packet returned 0, there was an error
}
Serial.println();
delay(1000); //have a delay between packets
}
void packet_is_OK()
{
//if here packet has been sent OK
Serial.print(F(" BytesSent,"));
Serial.print(TXPacketL); //print transmitted packet length
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
}

View File

@@ -0,0 +1,170 @@
/*******************************************************************************************************
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.
*******************************************************************************************************/
/*******************************************************************************************************
Program Operation - This is a minimum setup LoRa test receiver. The program listens for incoming packets
using the frequency and LoRa settings in the LT.setupLoRa() command. The pins to access the lora device
need to be defined at the top of the program 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. Sample serial monitor output;
8s Hello World 1234567890*,RSSI,-44dBm,SNR,9dB,Length,23,Packets,7,Errors,0,IRQreg,50
If there is a packet error it might look like this, which is showing a CRC error;
137s PacketError,RSSI,-89dBm,SNR,-8dB,Length,23,Packets,37,Errors,2,IRQreg,70,IRQ_HEADER_VALID,IRQ_CRC_ERROR,IRQ_RX_DONE
If there are no packets received in a 10 second period then you should see a message like this;
112s RXTimeout
For an example of a more detailed configuration for a receiver, see program 104_LoRa_Receiver.
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
SX126XLT LT; //create a library class instance called LT
#define NSS 10 //select pin on LoRa device
#define NRESET 9 //reset pin on LoRa device
#define RFBUSY 7 //SX126X busy pin
#define DIO1 3 //DIO1 pin on LoRa device, used for RX and TX done
#define SW 5 //SW pin on LoRa device, used to power antenna switch
#define LORA_DEVICE DEVICE_SX1262 //we need to define the device we are using
#define RXBUFFER_SIZE 32 //RX buffer size
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 setup()
{
Serial.begin(9600);
Serial.println();
Serial.println(F("4_LoRa_Receiver Starting"));
Serial.println();
SPI.begin();
if (LT.begin(NSS, NRESET, RFBUSY, DIO1, SW, LORA_DEVICE))
{
Serial.println(F("LoRa Device found"));
delay(1000);
}
else
{
Serial.println(F("No device responding"));
while (1);
}
LT.setupLoRa(434000000, 0, LORA_SF7, LORA_BW_125, LORA_CR_4_5, LDRO_AUTO); //configure frequency and LoRa settings
Serial.print(F("Receiver ready - RXBUFFER_SIZE "));
Serial.println(RXBUFFER_SIZE);
Serial.println();
}
void loop()
{
RXPacketL = LT.receive(RXBUFFER, RXBUFFER_SIZE, 60000, WAIT_RX); //wait for a packet to arrive with 60seconds (60000mS) timeout
PacketRSSI = LT.readPacketRSSI(); //read the received packets RSSI value
PacketSNR = LT.readPacketSNR(); //read the received packets SNR value
if (RXPacketL == 0) //if the LT.receive() function detects an error RXpacketL is 0
{
packet_is_Error();
}
else
{
packet_is_OK();
}
Serial.println();
}
void packet_is_OK()
{
uint16_t IRQStatus;
RXpacketCount++;
IRQStatus = LT.readIrqStatus(); //read the LoRa device IRQ status register
printElapsedTime(); //print elapsed time to Serial Monitor
Serial.print(F(" "));
LT.printASCIIPacket(RXBUFFER, RXPacketL); //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);
}
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"));
}

View File

@@ -0,0 +1,95 @@
/*******************************************************************************************************
Programs for Arduino - Copyright of the author Stuart Robinson - 23/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 - Transmits a FM tone using the LoRa device that can be picked up on an FM UHF
handheld receiver. The tones are not true FM but the UHF receiver does not know that.
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
void loop()
{
Serial.print(TXpower); //print the transmit power defined
Serial.print(F("dBm "));
Serial.println(F("PlayTone> "));
Serial.println();
digitalWrite(LED1, HIGH);
LT.toneFM(1000, 1000, deviation, adjustfreq, TXpower);
digitalWrite(LED1, LOW);
delay(1000);
}
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
pinMode(4, OUTPUT);
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("58_FM_Tone 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, SW, 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.setupDirect(Frequency, Offset);
Serial.print(F("Tone Transmitter ready"));
Serial.println();
}

View File

@@ -0,0 +1,36 @@
/*******************************************************************************************************
Programs for Arduino - Copyright of the author Stuart Robinson - 23/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 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 LORA_DEVICE DEVICE_SX1262 //we need to define the device we are using
//******* Setup Direct Modem Parameters Here ! ***************
const uint32_t Frequency = 434000000; //frequency of transmissions in hertz
const uint32_t Offset = 0; //offset frequency for calibration purposes
const uint16_t deviation = 10000; //deviation, total frequency shift low to high
const float adjustfreq = 0.9; //adjustment to tone frequency
const int8_t TXpower = 10; //LoRa transmit power in dBm

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

View File

@@ -0,0 +1,189 @@
/*******************************************************************************************************
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 <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
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, SW, 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, Optimisation);
//***************************************************************************************************
//Setup LoRa device
//***************************************************************************************************
LT.setMode(MODE_STDBY_RC);
LT.setRegulatorMode(USE_DCDC);
LT.setPaConfig(0x04, PAAUTO, LORA_DEVICE);
LT.setDIO3AsTCXOCtrl(TCXO_CTRL_3_3V);
LT.calibrateDevice(ALLDevices); //is required after setting TCXO
LT.calibrateImage(Frequency);
LT.setDIO2AsRfSwitchCtrl();
LT.setPacketType(PACKET_TYPE_LORA);
LT.setRfFrequency(Frequency, Offset);
LT.setModulationParams(SpreadingFactor, Bandwidth, CodeRate, Optimisation);
LT.setBufferBaseAddress(0, 0);
LT.setPacketParams(8, LORA_PACKET_VARIABLE_LENGTH, 255, LORA_CRC_ON, LORA_IQ_NORMAL);
LT.setDioIrqParams(IRQ_RADIO_ALL, (IRQ_RX_DONE + IRQ_RX_TX_TIMEOUT), 0, 0); //set for IRQ on TX done and timeout on DIO1
LT.setHighSensitivity(); //set for maximum gain
LT.setSyncWord(LORA_MAC_PRIVATE_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();
LT.printRegisters(0x900, 0x9FF); //print contents of device registers, normally 0x00 to 0x4F
Serial.println();
Serial.println();
Serial.print(F("Transmitter ready"));
Serial.println();
}

View File

@@ -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 my 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 SW -1 //SW pin on Dorji devices is used to turn RF switch on\off, 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_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 = 10; //LoRa transmit power in dBm
const uint16_t packet_delay = 1000; //mS delay between packets

View File

@@ -0,0 +1,254 @@
/*******************************************************************************************************
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 <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
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, 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); //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, Optimisation);
//***************************************************************************************************
//Setup LoRa device
//***************************************************************************************************
LT.setMode(MODE_STDBY_RC);
LT.setRegulatorMode(USE_DCDC);
LT.setPaConfig(0x04, PAAUTO, LORA_DEVICE);
LT.setDIO3AsTCXOCtrl(TCXO_CTRL_3_3V);
LT.calibrateDevice(ALLDevices); //is required after setting TCXO
LT.calibrateImage(Frequency);
LT.setDIO2AsRfSwitchCtrl();
LT.setPacketType(PACKET_TYPE_LORA);
LT.setRfFrequency(Frequency, Offset);
LT.setModulationParams(SpreadingFactor, Bandwidth, CodeRate, Optimisation);
LT.setBufferBaseAddress(0, 0);
LT.setPacketParams(8, LORA_PACKET_VARIABLE_LENGTH, 255, LORA_CRC_ON, LORA_IQ_NORMAL);
LT.setDioIrqParams(IRQ_RADIO_ALL, (IRQ_RX_DONE + IRQ_RX_TX_TIMEOUT), 0, 0); //set for IRQ on TX done and timeout on DIO1
LT.setHighSensitivity(); //set for maximum gain
LT.setSyncWord(LORA_MAC_PRIVATE_SYNCWORD);
//***************************************************************************************************
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 0x00 to 0x4F
Serial.println();
Serial.println();
Serial.print(F("Receiver ready - RXBUFFER_SIZE "));
Serial.println(RXBUFFER_SIZE);
Serial.println();
}

View File

@@ -0,0 +1,52 @@
/*******************************************************************************************************
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 my 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 SCK 18 //SCK on SPI3
#define MISO 19 //MISO on SPI3
#define MOSI 23 //MOSI on SPI3
#define NSS 5 //select pin on LoRa device
#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 SW -1 //SW pin on Dorji devices is used to turn RF switch on\off, 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_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 = 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,127 @@
/*******************************************************************************************************
Programs for Arduino - Copyright of the author Stuart Robinson - 28/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 minimum setup LoRa test transmitter. A packet containing the ASCII text
"Hello World 1234567890" is sent using the frequency and LoRa settings specified in the LT.setupLoRa()
command. The pins to access the lora device need to be defined at the top of the program also.
The details of the packet sent and any errors are shown on the Arduino IDE Serial Monitor, together with
the transmit power used and the packet length. The matching receiver program, '4_LoRa_Receiver' can be used
to check the packets are being sent correctly, the frequency and LoRa settings (in the LT.setupLoRa()
commands) must be the same for the transmitter and receiver programs. Sample Serial Monitor output;
10dBm Packet> Hello World 1234567890* BytesSent,23 PacketsSent,6
For an example of a more detailed configuration for a transmitter, see program 103_LoRa_Transmitter.
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
SX126XLT LT; //create a library class instance called LT
//These are the pin definitions for used for the program. Be sure to change to match the pins for your
//own setup. You will also need to connect up the pins for the SPI bus, which are SCK on pin 18, MISO
//on pin 19 and MOSI on pin 23.
#define NSS 5 //select pin on LoRa device
#define NRESET 27 //reset pin on LoRa device
#define RFBUSY 25 //busy line
#define DIO1 35 //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
const int8_t TXpower = 10; //LoRa transmit power in dBm
uint8_t TXPacketL;
uint32_t TXPacketCount;
uint8_t buff[] = "Hello World 1234567890"; //the message to send
void setup()
{
Serial.begin(9600);
Serial.println();
Serial.println(F("3_LoRa_Transmitter Starting"));
SPI.begin();
if (LT.begin(NSS, NRESET, RFBUSY, DIO1, LORA_DEVICE))
{
Serial.println(F("LoRa Device found"));
delay(1000);
}
else
{
Serial.println(F("No device responding"));
while (1);
}
LT.setupLoRa(434000000, 0, LORA_SF7, LORA_BW_125, LORA_CR_4_5, LDRO_AUTO); //configure frequency and LoRa settings
Serial.print(F("Transmitter ready"));
Serial.println();
}
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
if (LT.transmit(buff, TXPacketL, 10000, TXpower, WAIT_TX)) //will return packet length sent if OK, otherwise 0 if transmit error
{
TXPacketCount++;
packet_is_OK();
}
else
{
packet_is_Error(); //transmit packet returned 0, there was an error
}
Serial.println();
delay(1000); //have a delay between packets
}
void packet_is_OK()
{
//if here packet has been sent OK
Serial.print(F(" BytesSent,"));
Serial.print(TXPacketL); //print transmitted packet length
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
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 KiB

View 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.
![Picture 1](/pictures/ESP32_Bare_Bones_Schematic.jpg)
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;
![Picture 1](/pictures/ESP32_Micro_Node.jpg)
### 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

View File

@@ -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 <SX126XLT.h>
#include "Settings.h"
SX126XLT 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, SW, 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, Optimisation);
Serial.println(F("Transmitter ready"));
Serial.println();
}

View File

@@ -0,0 +1,41 @@
/*******************************************************************************************************
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 //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 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 = 10; //LoRa transmit power in dBm
const uint16_t packet_delay = 1000; //mS delay between packets

View File

@@ -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 <SX126XLT.h>
#include "Settings.h"
SX126XLT 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, SW, 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, Optimisation);
Serial.println(F("Receiver ready"));
Serial.println();
}

View File

@@ -0,0 +1,44 @@
/*******************************************************************************************************
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,
//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 BUZZER 4 //pin for buzzer, on when logic high
#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 = 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,44 @@
# SX126X Library
<cr>
This part of the SX12XX library supports the SX1261, SX1262 and SX1268 (all UHF) LoRa devices..
The objective of the 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.
The library was tested on both NiceRF and Dorji modules.
The Library has not been tested on the Semtech SX1261MB2BAS or similar development boards, so consider them unsupported. These development modules are not low cost and are not in a form (and too big) to be of practical use to the author of the library.
###Considerations for pin usage
There is a range of SX126X 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.
Of the LoRa devices DIO pins the SX126X library in standard form only uses DIO1. The Dorji DRF1262 and DRF1268 modules have an additional SW pin which must be configured and used since it provides power to the antenna switch on these modules. Some SX126x modules have RX and TX enable pins that need to be appropiatly 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, SW, LORA\_DEVICE);
Clearly the above begin statement is somewhat cumbersome and could potentially be shortened for the NiceRF S1262 devices to;
begin(NSS, NRESET, RFBUSY, DIO1, LORA\_DEVICE);
And shortened for the Dorji devices to;
begin(NSS, NRESET, RFBUSY, DIO1, SW, LORA\_DEVICE);
Which is a lot more manageable.
The first edition of the SX126X part of the library did use use a begin function in the examples of;
begin(NSS, NRESET, RFBUSY, DIO1, DIO2, DIO3, SW, LORA\_DEVICE)
This format is still valid so 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.
Accepted its all a bit confusing, but regrettably module manufacturers have different ideas about design.

View File

@@ -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 <SX126XLT.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
SX126XLT 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, SW, 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, Optimisation);
Serial.println(F("Transmitter ready"));
Serial.println();
}

View File

@@ -0,0 +1,52 @@
/*******************************************************************************************************
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 SX126X devices, set to -1 if not used
const int8_t TX_EN = -1; //pin for TX enable, used on some SX126X devices, set to -1 if not used
const int8_t SW = -1; //SW pin on Dorji devices is used to turn RF switch on\off, set to -1 if not used
#define LORA_DEVICE DEVICE_SX1262 //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
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
#define TXpower 10 //power for transmissions in dBm

View File

@@ -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 <SX126XLT.h>
#include "Settings.h"
#include <ProgramLT_Definitions.h>
SX126XLT 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, SW, 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, Optimisation);
Serial.println(F("Receiver ready"));
}

View File

@@ -0,0 +1,48 @@
/*******************************************************************************************************
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 SX126X devices, set to -1 if not used
const int8_t TX_EN = -1; //pin for TX enable, used on some SX126X devices, set to -1 if not used
const int8_t SW = -1; //SW pin on Dorji devices is used to turn RF switch on\off, set to -1 if not used
const int8_t BUZZER = -1; //pin for buzzer, set to -1 if not used
#define LORA_DEVICE DEVICE_SX1262 //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
//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
#define TXpower 10 //power for transmissions in dBm

View File

@@ -0,0 +1,205 @@
/*******************************************************************************************************
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.
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 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 <SX126XLT.h>
#include "Settings.h"
#include <ProgramLT_Definitions.h>
SX126XLT 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.
//uint8_t len;
uint32_t packetStartmS, packettimemS;
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
packetStartmS = millis();
TXPacketL = LT.transmitSXBuffer(0, PacketLength, 10000, TXpower, WAIT_TX);
packettimemS = millis() - packetStartmS;
#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.print(F(","));
Serial.print(packettimemS);
Serial.print(F("mS"));
Serial.println();
#endif
digitalWrite(LED1, LOW); //LED off, may have been on due to switch press
delay(packettimemS * 9); //delay for 9 times packet transmit time to ensure 10% duty cycle
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, SW, 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, Optimisation);
attachInterrupts();
Serial.println(F("35_Remote_Control_Servo_Transmitter ready"));
}

View File

@@ -0,0 +1,53 @@
/*******************************************************************************************************
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 ! ***************
//******* 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 SX126X devices, set to -1 if not used
const int8_t TX_EN = -1; //pin for TX enable, used on some SX126X devices, set to -1 if not used
const int8_t SW = -1; //SW pin on Dorji devices is used to turn RF switch on\off, set to -1 if not used
#define LORA_DEVICE DEVICE_SX1262 //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
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 uint8_t PacketLength = 5; //packet length is fixed
const int8_t TXpower = 10; //LoRa transmit power in dBm

View File

@@ -0,0 +1,259 @@
/*******************************************************************************************************
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 <SX126XLT.h>
#include "Settings.h"
#include <ProgramLT_Definitions.h>
SX126XLT 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 (LT.readIrqStatus() == (IRQ_RX_DONE + IRQ_HEADER_VALID + IRQ_PREAMBLE_DETECTED))
{
packet_is_OK();
}
else
{
Serial.print(F("IRQ,"));
Serial.print(LT.readIrqStatus(),HEX);
Serial.print(F(","));
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, SW, 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, Optimisation);
Serial.println(F("36_Remote_Control_Servo_Receiver ready"));
Serial.println();
}

View File

@@ -0,0 +1,48 @@
/*******************************************************************************************************
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 SX126X devices, set to -1 if not used
const int8_t TX_EN = -1; //pin for TX enable, used on some SX126X devices, set to -1 if not used
const int8_t SW = -1; //SW pin on Dorji devices is used to turn RF switch on\off, set to -1 if not used
#define LORA_DEVICE DEVICE_SX1262 //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
//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 uint8_t PacketLength = 5; //packet length is fixed

View File

@@ -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"));
}

View File

@@ -0,0 +1,401 @@
/*******************************************************************************************************
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 program is stand alone, it is not necessary to install the SX12XX-LoRa library
to use it. This test program is for the SX126X LoRa devices.
The program checks that a SX126X 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, SX1261, SX1262,
or SX1268 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
0x800 00 00 00 00 01 07 20 1E 00 10 19 04 0F FF 0F FF
0x810 10 00 10 00 10 00 10 00 00 00 00 00 00 00 00 00
0x820 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x830 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x840 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x850 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x860 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x870 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x880 03 00 00 5F 10 08 00 00 08 05 00 39 30 00 00 0C
0x890 00 00 00 00 00 0F 0A 07 10 00 26 01 01 53 06 07
0x8A0 10 00 AA 20 5A 04 F0 00 56 56 54 43 94 20 40 00
0x8B0 00 83 11 00 01 04 0A 4C 14 0A 2F 01 6B FF FF 00
0x8C0 00 A0 20 00 00 00 AC 00 1C 00 00 AB 05 30 00 00
0x8D0 0C 14 14 40 06 00 00 10 C8 00 00 00 00 00 31 39
0x8E0 90 39 0C 04 40 20 1C 18 03 00 05 04 03 02 01 01
0x8F0 00 00 00 00 30 00 00 00 00 00 00 00 00 00 00 00
0x900 30 00 00 00 00 00 00 00 00 00 00 00 24 04 47 04
0x910 14 12 12 04 00 03 0A 00 15 35 09 00 02 1F 5F 08
0x920 01 04 05 00 00 00 00 00 00 00 00 00 00 00 00 00
0x930 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x940 00 07 00 03 02 00 10 0E 0D 0C 03 04 03 70 0C 00
0x950 00 00 00 04 00 00 00 00 00 00 00 00 00 00 00 00
0x960 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x970 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x980 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x990 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x9A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x9B0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x9C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x9D0 00 00 00 00 00 00 00 00 00 00 00 00 00 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 915000000
Reg 0 1 2 3 4 5 6 7 8 9 A B C D E F
0x880 03 00 00 5F 10 08 00 00 08 05 00 39 30 00 00 0C
Change Frequency 434100000
Reg 0 1 2 3 4 5 6 7 8 9 A B C D E F
0x880 03 00 00 5F 10 08 00 00 08 05 00 1B 21 99 A0 0C
Changed Frequency 434100000
Serial monitor baud rate is set at 9600.
*******************************************************************************************************/
const uint16_t REG_RFFrequency31_24 = 0x088B;
const uint16_t REG_RFFrequency23_16 = 0x088C;
const uint16_t REG_RFFrequency15_8 = 0x088D;
const uint16_t REG_RFFrequency7_0 = 0x088E;
const uint8_t RADIO_WRITE_REGISTER = 0x0D;
const uint8_t RADIO_READ_REGISTER = 0x1D;
const uint8_t RADIO_SET_RFFREQUENCY = 0x86;
const uint8_t DEVICE_SX1261 = 0x01;
const uint8_t DEVICE_SX1262 = 0x00;
const uint8_t DEVICE_SX1268 = 0x02;
//********* 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
#define NSS 10 //SX126X device select
#define NRESET 9 //SX126X reset pin
#define RFBUSY -1 //SX126X busy pin
#define SW -1 //SW pin on Dorji devices is used to turn RF switch on\off, set to -1 if not used
#define LORA_DEVICE DEVICE_SX1261 //define the device, DEVICE_SX1261, DEVICE_SX1262 or DEVICE_SX1268
//**************************************************************/
#include <SPI.h>
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 are not used in this example so are set to -1
if (begin(NSS, NRESET, RFBUSY, -1, -1, -1, SW, LORA_DEVICE))
{
Serial.println(F("LoRa Device found"));
}
else
{
Serial.println(F("No device responding"));
}
}
void loop()
{
uint32_t frequency;
resetDevice(LORA_DEVICE); //reset the device
Serial.println(F("Registers at reset")); //show the all registers following a reset
printRegisters(0x800, 0x9FF);
Serial.println();
Serial.println();
frequency = getFreqInt(); //read the set frequency following a reset
Serial.print(F("Frequency at reset "));
Serial.println(frequency);
printRegisters(0x0880, 0x088F); //show the registers before the frequency change
setRfFrequency(434100000, 0); //change the frequency at reset, in hertz
frequency = getFreqInt(); //read back the changed frequency
Serial.print(F("Change Frequency "));
Serial.println(frequency); //print the changed frequency, did the write work (allow for rounding errors) ?
printRegisters(0x0880, 0x088F); //show the registers after frequency change
frequency = getFreqInt(); //read the set frequency following a reset
Serial.print(F("Changed Frequency "));
Serial.println(frequency);
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 from registers, return as long integer
uint8_t MsbH, MsbL, Mid, Lsb;
uint32_t uinttemp;
float floattemp;
MsbH = readRegister(REG_RFFrequency31_24);
MsbL = readRegister(REG_RFFrequency23_16);
Mid = readRegister(REG_RFFrequency15_8);
Lsb = readRegister(REG_RFFrequency7_0);
floattemp = ( (MsbH * 0x1000000ul) + (MsbL * 0x10000ul) + (Mid * 0x100ul) + Lsb);
floattemp = ((floattemp * 0.95367431640625) / 1000000ul);
uinttemp = (uint32_t)(floattemp * 1000000);
return uinttemp;
}
void printRegisters(uint16_t Start, uint16_t End)
{
//prints the contents of SX126x 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 )
{
//Note RF_Freq = freq_reg*32M/(2^25)-----> freq_reg = (RF_Freq * (2^25))/32
uint8_t Rf_Freq[4];
frequency = frequency + offset;
frequency = ( uint32_t )( ( double )frequency / ( double )0.95367431640625 );
checkBusy();
Rf_Freq[0] = (frequency >> 24) & 0xFF; //MSB
Rf_Freq[1] = (frequency >> 16) & 0xFF;
Rf_Freq[2] = (frequency >> 8) & 0xFF;
Rf_Freq[3] = frequency & 0xFF;//LSB
writeCommand(RADIO_SET_RFFREQUENCY, Rf_Freq, 4);
}
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(uint8_t device)
{
if ( (device == DEVICE_SX1261) | (device == DEVICE_SX1262) | (device == DEVICE_SX1268) )
{
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, int8_t pinSW, uint8_t device)
{
pinMode(pinNSS, OUTPUT);
digitalWrite(pinNSS, HIGH);
pinMode(pinNRESET, OUTPUT);
digitalWrite(pinNRESET, LOW);
pinMode(pinRFBUSY, INPUT);
if (pinDIO1 >= 0)
{
pinMode( pinDIO1, INPUT);
}
if (pinDIO2 >= 0)
{
pinMode(pinDIO2, INPUT);
}
if (pinDIO3 >= 0)
{
pinMode(pinDIO3, INPUT);
}
if (pinSW >= 0)
{
pinMode(pinSW, OUTPUT); //Dorji devices have an SW pin that needs to be set high to power antenna switch
digitalWrite(pinSW, HIGH);
}
resetDevice(device);
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(0x88e); //low byte of frequency setting
writeRegister(0x88e, (Regdata1 + 1));
Regdata2 = readRegister(0x88e); //read changed value back
writeRegister(0x88e, 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]);
}
digitalWrite(NSS, HIGH);
checkBusy();
}

View File

@@ -0,0 +1,123 @@
/*******************************************************************************************************
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.
*******************************************************************************************************/
/*******************************************************************************************************
Program Operation - This is a minimum setup LoRa test transmitter. A packet containing the ASCII text
"Hello World 1234567890" is sent using the frequency and LoRa settings specified in the LT.setupLoRa()
command. The pins to access the lora device need to be defined at the top of the program also.
The details of the packet sent and any errors are shown on the Arduino IDE Serial Monitor, together with
the transmit power used and the packet length. The matching receiver program, '4_LoRa_Receiver' can be used
to check the packets are being sent correctly, the frequency and LoRa settings (in the LT.setupLoRa()
commands) must be the same for the transmitter and receiver programs. Sample Serial Monitor output;
10dBm Packet> Hello World 1234567890* BytesSent,23 PacketsSent,6
For an example of a more detailed configuration for a transmitter, see program 103_LoRa_Transmitter.
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
SX126XLT LT; //create a library class instance called LT
#define NSS 10 //select pin on LoRa device
#define NRESET 9 //reset pin on LoRa device
#define RFBUSY 7 //SX126X busy pin
#define DIO1 4 //DIO1 pin on LoRa device, used for sensing RX and TX done
#define SW 5 //SW pin on LoRa device, used to power antenna switch
#define LORA_DEVICE DEVICE_SX1261 //we need to define the device we are using
#define TXpower 10 //LoRa transmit power in dBm
uint8_t TXPacketL;
uint32_t TXPacketCount;
uint8_t buff[] = "Hello World 1234567890"; //the message to send
void setup()
{
Serial.begin(9600);
Serial.println();
Serial.println(F("3_LoRa_Transmitter Starting"));
SPI.begin();
if (LT.begin(NSS, NRESET, RFBUSY, DIO1, SW, LORA_DEVICE))
{
Serial.println(F("LoRa Device found"));
delay(1000);
}
else
{
Serial.println(F("No device responding"));
while (1);
}
LT.setupLoRa(434000000, 0, LORA_SF7, LORA_BW_125, LORA_CR_4_5, LDRO_AUTO); //configure frequency and LoRa settings
Serial.print(F("Transmitter ready"));
Serial.println();
}
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
if (LT.transmit(buff, TXPacketL, 10000, TXpower, WAIT_TX)) //will return packet length sent if OK, otherwise 0 if transmit error
{
TXPacketCount++;
packet_is_OK();
}
else
{
packet_is_Error(); //transmit packet returned 0, there was an error
}
Serial.println();
delay(1000); //have a delay between packets
}
void packet_is_OK()
{
//if here packet has been sent OK
Serial.print(F(" BytesSent,"));
Serial.print(TXPacketL); //print transmitted packet length
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
}

View File

@@ -0,0 +1,170 @@
/*******************************************************************************************************
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.
*******************************************************************************************************/
/*******************************************************************************************************
Program Operation - This is a minimum setup LoRa test receiver. The program listens for incoming packets
using the frequency and LoRa settings in the LT.setupLoRa() command. The pins to access the lora device
need to be defined at the top of the program 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. Sample serial monitor output;
8s Hello World 1234567890*,RSSI,-44dBm,SNR,9dB,Length,23,Packets,7,Errors,0,IRQreg,50
If there is a packet error it might look like this, which is showing a CRC error;
137s PacketError,RSSI,-89dBm,SNR,-8dB,Length,23,Packets,37,Errors,2,IRQreg,70,IRQ_HEADER_VALID,IRQ_CRC_ERROR,IRQ_RX_DONE
If there are no packets received in a 10 second period then you should see a message like this;
112s RXTimeout
For an example of a more detailed configuration for a receiver, see program 104_LoRa_Receiver.
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
SX126XLT LT; //create a library class instance called LT
#define NSS 10 //select pin on LoRa device
#define NRESET 9 //reset pin on LoRa device
#define RFBUSY 7 //SX126X busy pin
#define DIO1 3 //DIO1 pin on LoRa device, used for RX and TX done
#define SW 5 //SW pin on LoRa device, used to power antenna switch
#define LORA_DEVICE DEVICE_SX1262 //we need to define the device we are using
#define RXBUFFER_SIZE 32 //RX buffer size
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 setup()
{
Serial.begin(9600);
Serial.println();
Serial.println(F("4_LoRa_Receiver Starting"));
Serial.println();
SPI.begin();
if (LT.begin(NSS, NRESET, RFBUSY, DIO1, SW, LORA_DEVICE))
{
Serial.println(F("LoRa Device found"));
delay(1000);
}
else
{
Serial.println(F("No device responding"));
while (1);
}
LT.setupLoRa(434000000, 0, LORA_SF7, LORA_BW_125, LORA_CR_4_5, LDRO_AUTO); //configure frequency and LoRa settings
Serial.print(F("Receiver ready - RXBUFFER_SIZE "));
Serial.println(RXBUFFER_SIZE);
Serial.println();
}
void loop()
{
RXPacketL = LT.receive(RXBUFFER, RXBUFFER_SIZE, 60000, WAIT_RX); //wait for a packet to arrive with 60seconds (60000mS) timeout
PacketRSSI = LT.readPacketRSSI(); //read the received packets RSSI value
PacketSNR = LT.readPacketSNR(); //read the received packets SNR value
if (RXPacketL == 0) //if the LT.receive() function detects an error RXpacketL is 0
{
packet_is_Error();
}
else
{
packet_is_OK();
}
Serial.println();
}
void packet_is_OK()
{
uint16_t IRQStatus;
RXpacketCount++;
IRQStatus = LT.readIrqStatus(); //read the LoRa device IRQ status register
printElapsedTime(); //print elapsed time to Serial Monitor
Serial.print(F(" "));
LT.printASCIIPacket(RXBUFFER, RXPacketL); //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);
}
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"));
}

View File

@@ -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 <SX126XLT.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
SX126XLT 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, SW, 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, Optimisation);
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
}

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.
*******************************************************************************************************/
//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 //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 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_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 = 14; //LoRa transmit power in dBm
#define BME280_ADDRESS 0x76 //I2C bus address of BME280
#define BME280_REGISTER_CONTROL 0xF4 //BME280 register number for power control
const uint8_t sleeps = 2; //number of 8 second sleeps, gap between transmissions

View File

@@ -0,0 +1,358 @@
/*******************************************************************************************************
Programs for Arduino - Copyright of the author Stuart Robinson - 18/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 <SX126XLT.h>
#include "Settings.h"
#include <ProgramLT_Definitions.h>
SX126XLT 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, SW, LORA_DEVICE))
{
disp.print(F("LoRa OK"));
led_Flash(2, 125);
}
else
{
disp.print(F("Device error"));
Serial.println(F("Device error"));
while (1)
{
led_Flash(50, 50); //long fast speed flash indicates device error
}
}
LT.setupLoRa(Frequency, Offset, SpreadingFactor, Bandwidth, CodeRate, Optimisation);
Serial.println(F("Receiver ready"));
Serial.println();
}

Some files were not shown because too many files have changed in this diff Show More