first commit
This commit is contained in:
@@ -0,0 +1,212 @@
|
||||
/*****************************************************************************************************
|
||||
Programs for Arduino - Copyright of the author Stuart Robinson - 16/03/20
|
||||
|
||||
This program is supplied as is, it is up to the user of the program to decide if the program is
|
||||
suitable for the intended purpose and free from errors.
|
||||
*******************************************************************************************************/
|
||||
|
||||
#define Program_Version "V1.0"
|
||||
|
||||
#include <SPI.h>
|
||||
#include <SX128XLT.h>
|
||||
#include "Settings.h"
|
||||
|
||||
SX128XLT LT;
|
||||
|
||||
|
||||
#ifdef ENABLEOLED
|
||||
#include <U8x8lib.h> //https://github.com/olikraus/u8g2
|
||||
U8X8_SSD1306_128X64_NONAME_HW_I2C disp(U8X8_PIN_NONE); //standard 0.96" SSD1306
|
||||
//U8X8_SH1106_128X64_NONAME_HW_I2C disp(U8X8_PIN_NONE); //1.3" OLED often sold as 1.3" SSD1306
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
uint16_t rangeing_errors, rangeings_valid, rangeing_results;
|
||||
uint16_t IrqStatus;
|
||||
uint32_t endwaitmS, startrangingmS, range_result_sum, range_result_average;
|
||||
float distance, distance_sum, distance_average;
|
||||
bool ranging_error;
|
||||
int32_t range_result;
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
uint8_t index;
|
||||
distance_sum = 0;
|
||||
range_result_sum = 0;
|
||||
rangeing_results = 0; //count of valid results in each loop
|
||||
|
||||
for (index = 1; index <= rangeingcount; index++)
|
||||
{
|
||||
|
||||
startrangingmS = millis();
|
||||
|
||||
LT.transmitRanging(RangingAddress, TXtimeoutmS, RangingTXPower, WAIT_TX);
|
||||
|
||||
IrqStatus = LT.readIrqStatus();
|
||||
|
||||
if (IrqStatus & IRQ_RANGING_MASTER_RESULT_VALID)
|
||||
{
|
||||
rangeing_results++;
|
||||
rangeings_valid++;
|
||||
digitalWrite(LED1, HIGH);
|
||||
Serial.print(F("Valid"));
|
||||
range_result = LT.getRangingResultRegValue(RANGING_RESULT_RAW);
|
||||
Serial.print(F(",Register,"));
|
||||
Serial.print(range_result);
|
||||
|
||||
if (range_result > 800000)
|
||||
{
|
||||
range_result = 0;
|
||||
}
|
||||
range_result_sum = range_result_sum + range_result;
|
||||
|
||||
distance = LT.getRangingDistance(RANGING_RESULT_RAW, range_result, distance_adjustment);
|
||||
distance_sum = distance_sum + distance;
|
||||
|
||||
Serial.print(F(",Distance,"));
|
||||
Serial.print(distance, 1);
|
||||
digitalWrite(LED1, LOW);
|
||||
}
|
||||
else
|
||||
{
|
||||
rangeing_errors++;
|
||||
distance = 0;
|
||||
range_result = 0;
|
||||
Serial.print(F("NotValid"));
|
||||
Serial.print(F(",Irq,"));
|
||||
Serial.print(IrqStatus, HEX);
|
||||
}
|
||||
delay(packet_delaymS);
|
||||
|
||||
if (index == rangeingcount)
|
||||
{
|
||||
range_result_average = (range_result_sum / rangeing_results);
|
||||
|
||||
if (rangeing_results == 0)
|
||||
{
|
||||
distance_average = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
distance_average = (distance_sum / rangeing_results);
|
||||
}
|
||||
|
||||
Serial.print(F(",TotalValid,"));
|
||||
Serial.print(rangeings_valid);
|
||||
Serial.print(F(",TotalErrors,"));
|
||||
Serial.print(rangeing_errors);
|
||||
Serial.print(F(",AverageRAWResult,"));
|
||||
Serial.print(range_result_average);
|
||||
Serial.print(F(",AverageDistance,"));
|
||||
Serial.print(distance_average, 1);
|
||||
|
||||
#ifdef ENABLEDISPLAY
|
||||
display_screen1();
|
||||
#endif
|
||||
|
||||
delay(2000);
|
||||
|
||||
}
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#ifdef ENABLEDISPLAY
|
||||
void display_screen1()
|
||||
{
|
||||
disp.clear();
|
||||
disp.setCursor(0, 0);
|
||||
disp.print(F("Distance "));
|
||||
disp.print(distance_average, 1);
|
||||
disp.print(F("m"));
|
||||
disp.setCursor(0, 2);
|
||||
disp.print(F("OK,"));
|
||||
disp.print(rangeings_valid);
|
||||
disp.print(F(",Err,"));
|
||||
disp.print(rangeing_errors);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void led_Flash(uint16_t flashes, uint16_t delaymS)
|
||||
{
|
||||
uint16_t index;
|
||||
|
||||
for (index = 1; index <= flashes; index++)
|
||||
{
|
||||
digitalWrite(LED1, HIGH);
|
||||
delay(delaymS);
|
||||
digitalWrite(LED1, LOW);
|
||||
delay(delaymS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
pinMode(LED1, OUTPUT); //setup pin as output for indicator LED
|
||||
led_Flash(4, 125); //two quick LED flashes to indicate program start
|
||||
|
||||
Serial.begin(9600);
|
||||
Serial.println();
|
||||
Serial.print(F(__TIME__));
|
||||
Serial.print(F(" "));
|
||||
Serial.println(F(__DATE__));
|
||||
Serial.println(F(Program_Version));
|
||||
Serial.println();
|
||||
Serial.println(F("54_Ranging_Master Starting"));
|
||||
|
||||
SPI.begin();
|
||||
|
||||
led_Flash(2, 125);
|
||||
|
||||
if (LT.begin(NSS, NRESET, RFBUSY, DIO1, LORA_DEVICE))
|
||||
{
|
||||
Serial.println(F("Device found"));
|
||||
led_Flash(2, 125);
|
||||
delay(1000);
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println(F("No device responding"));
|
||||
while (1)
|
||||
{
|
||||
led_Flash(50, 50); //long fast flash indicates device error
|
||||
}
|
||||
}
|
||||
|
||||
LT.setupRanging(Frequency, Offset, SpreadingFactor, Bandwidth, CodeRate, RangingAddress, RANGING_MASTER);
|
||||
|
||||
//LT.setRangingCalibration(Calibration); //override automatic lookup of calibration value from library table
|
||||
|
||||
#ifdef ENABLEDISPLAY
|
||||
Serial.println("Display Enabled");
|
||||
disp.begin();
|
||||
disp.setFont(u8x8_font_chroma48medium8_r);
|
||||
disp.setCursor(0, 0);
|
||||
disp.print(F("Ranging RAW Ready"));
|
||||
disp.setCursor(0, 1);
|
||||
disp.print(F("Power "));
|
||||
disp.print(RangingTXPower);
|
||||
disp.print(F("dBm"));
|
||||
disp.setCursor(0, 2);
|
||||
disp.print(F("Cal "));
|
||||
disp.print(Calibration);
|
||||
disp.setCursor(0, 3);
|
||||
disp.print(F("Adjust "));
|
||||
disp.print(distance_adjustment, 4);
|
||||
#endif
|
||||
|
||||
|
||||
Serial.print(F("Address "));
|
||||
Serial.println(RangingAddress);
|
||||
Serial.print(F("CalibrationValue "));
|
||||
Serial.println(LT.getSetCalibrationValue());
|
||||
Serial.println(F("Ranging master RAW ready"));
|
||||
|
||||
delay(2000);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
/*****************************************************************************************************
|
||||
Programs for Arduino - Copyright of the author Stuart Robinson - 16/03/20
|
||||
|
||||
This program is supplied as is, it is up to the user of the program to decide if the program is
|
||||
suitable for the intended purpose and free from errors.
|
||||
*******************************************************************************************************/
|
||||
|
||||
//******* Setup hardware pin definitions here ! ***************
|
||||
|
||||
//These are the pin definitions for one of my own boards, the Easy Pro Mini,
|
||||
//be sure to change the definitions to match your own setup. Some pins such as DIO2,
|
||||
//DIO3, BUZZER may not be in used by this sketch so they do not need to be
|
||||
//connected and should be included and be set to -1.
|
||||
|
||||
|
||||
#define NSS 10
|
||||
#define RFBUSY 7
|
||||
#define NRESET 9
|
||||
#define LED1 8
|
||||
#define DIO1 3
|
||||
|
||||
#define LORA_DEVICE DEVICE_SX1280 //we need to define the device we are using
|
||||
|
||||
//******* Setup LoRa Parameters Here ! ***************
|
||||
|
||||
//LoRa Modem Parameters
|
||||
const uint32_t Frequency = 2445000000; //frequency of transmissions in hz
|
||||
const int32_t Offset = 0; //offset frequency in hz for calibration purposes
|
||||
const uint8_t Bandwidth = LORA_BW_0800; //LoRa bandwidth
|
||||
const uint8_t SpreadingFactor = LORA_SF8; //LoRa spreading factor
|
||||
const uint8_t CodeRate = LORA_CR_4_5; //LoRa coding rate
|
||||
const uint16_t Calibration = 11350; //Manual Ranging calibrarion value
|
||||
|
||||
const uint8_t RangingTXPower = 10; //Transmit power used
|
||||
const uint32_t RangingAddress = 16; //must match address in recever
|
||||
|
||||
const uint16_t waittimemS = 10000; //wait this long in mS for packet before assuming timeout
|
||||
const uint16_t TXtimeoutmS = 5000; //ranging TX timeout in mS
|
||||
const uint16_t packet_delaymS = 0; //forced extra delay in mS between ranging requests
|
||||
const uint16_t rangeingcount = 5; //number of times ranging is cqarried out for each distance measurment
|
||||
float distance_adjustment = 1.0000; //adjustment factor to calculated distance
|
||||
|
||||
|
||||
#define ENABLEOLED //enable this define to use display
|
||||
#define ENABLEDISPLAY //enable this define to use display
|
||||
|
||||
|
||||
@@ -0,0 +1,147 @@
|
||||
/*******************************************************************************************************
|
||||
Programs for Arduino - Copyright of the author Stuart Robinson - 16/03/20
|
||||
|
||||
This program is supplied as is, it is up to the user of the program to decide if the program is
|
||||
suitable for the intended purpose and free from errors.
|
||||
*******************************************************************************************************/
|
||||
|
||||
|
||||
/*******************************************************************************************************
|
||||
Program Operation -
|
||||
|
||||
Serial monitor baud rate is set at 9600
|
||||
*******************************************************************************************************/
|
||||
|
||||
#define programversion "V1.0"
|
||||
|
||||
#include <SPI.h>
|
||||
#include <SX128XLT.h>
|
||||
#include "Settings.h"
|
||||
|
||||
SX128XLT LT;
|
||||
|
||||
uint32_t endwaitmS;
|
||||
uint16_t IrqStatus;
|
||||
uint32_t response_sent;
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
LT.receiveRanging(RangingAddress, 0, TXpower, NO_WAIT);
|
||||
|
||||
endwaitmS = millis() + rangingRXTimeoutmS;
|
||||
|
||||
while (!digitalRead(DIO1) && (millis() <= endwaitmS)); //wait for Ranging valid or timeout
|
||||
|
||||
if (millis() >= endwaitmS)
|
||||
{
|
||||
Serial.println("Error - Ranging Receive Timeout!!");
|
||||
led_Flash(2, 100); //single flash to indicate timeout
|
||||
}
|
||||
else
|
||||
{
|
||||
IrqStatus = LT.readIrqStatus();
|
||||
digitalWrite(LED1, HIGH);
|
||||
|
||||
if (IrqStatus & IRQ_RANGING_SLAVE_RESPONSE_DONE)
|
||||
{
|
||||
response_sent++;
|
||||
Serial.print(response_sent);
|
||||
Serial.print(" Response sent");
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.print("Slave error,");
|
||||
Serial.print(",Irq,");
|
||||
Serial.print(IrqStatus, HEX);
|
||||
LT.printIrqStatus();
|
||||
}
|
||||
digitalWrite(LED1, LOW);
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void led_Flash(unsigned int flashes, unsigned int delaymS)
|
||||
{
|
||||
//flash LED to show board is alive
|
||||
unsigned int index;
|
||||
|
||||
for (index = 1; index <= flashes; index++)
|
||||
{
|
||||
digitalWrite(LED1, HIGH);
|
||||
delay(delaymS);
|
||||
digitalWrite(LED1, LOW);
|
||||
delay(delaymS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(9600); //setup Serial console ouput
|
||||
Serial.println();
|
||||
Serial.println(__FILE__);
|
||||
Serial.print(F("Compiled "));
|
||||
Serial.print(__TIME__);
|
||||
Serial.print(F(" "));
|
||||
Serial.println(__DATE__);
|
||||
Serial.println(F(programversion));
|
||||
Serial.println(F("Stuart Robinson"));
|
||||
Serial.println();
|
||||
|
||||
Serial.println("55_Ranging_Slave Starting");
|
||||
|
||||
pinMode(LED1, OUTPUT);
|
||||
led_Flash(2, 125);
|
||||
|
||||
SPI.begin();
|
||||
|
||||
if (LT.begin(NSS, NRESET, RFBUSY, DIO1, LORA_DEVICE))
|
||||
{
|
||||
Serial.println(F("Device found"));
|
||||
led_Flash(2, 125);
|
||||
delay(1000);
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println(F("No device responding"));
|
||||
while (1)
|
||||
{
|
||||
led_Flash(50, 50); //long fast speed flash indicates device error
|
||||
}
|
||||
}
|
||||
|
||||
//The function call list below shows the complete setup for the LoRa device for ranging using the information
|
||||
//defined in the Settings.h file.
|
||||
//The 'Setup LoRa device for Ranging' list below can be replaced with a single function call, note that
|
||||
//the calibration value will be loaded automatically from the table in the library;
|
||||
//LT.setupRanging(Frequency, Offset, SpreadingFactor, Bandwidth, CodeRate, RangingAddress, RangingRole);
|
||||
|
||||
LT.setupRanging(Frequency, Offset, SpreadingFactor, Bandwidth, CodeRate, RangingAddress, RANGING_SLAVE);
|
||||
|
||||
//***************************************************************************************************
|
||||
//Setup LoRa device for Ranging Slave
|
||||
//***************************************************************************************************
|
||||
LT.setMode(MODE_STDBY_RC);
|
||||
LT.setPacketType(PACKET_TYPE_RANGING);
|
||||
LT.setModulationParams(SpreadingFactor, Bandwidth, CodeRate);
|
||||
LT.setPacketParams(12, LORA_PACKET_VARIABLE_LENGTH, 0, LORA_CRC_ON, LORA_IQ_NORMAL, 0, 0);
|
||||
LT.setRfFrequency(Frequency, Offset);
|
||||
LT.setTxParams(TXpower, RADIO_RAMP_02_US);
|
||||
LT.setRangingMasterAddress(RangingAddress);
|
||||
LT.setRangingSlaveAddress(RangingAddress);
|
||||
LT.setRangingCalibration(LT.lookupCalibrationValue(SpreadingFactor, Bandwidth));
|
||||
LT.setRangingRole(RANGING_SLAVE);
|
||||
LT.writeRegister(REG_RANGING_FILTER_WINDOW_SIZE, 8); //set up window size for ranging averaging
|
||||
LT.setHighSensitivity();
|
||||
//***************************************************************************************************
|
||||
|
||||
LT.setRangingCalibration(11300); //override automatic lookup of calibration value from library table
|
||||
|
||||
Serial.print(F("Calibration,"));
|
||||
Serial.println(LT.getSetCalibrationValue()); //reads the calibratuion value currently set
|
||||
delay(2000);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/*****************************************************************************************************
|
||||
Programs for Arduino - Copyright of the author Stuart Robinson - 16/03/20
|
||||
|
||||
This program is supplied as is, it is up to the user of the program to decide if the program is
|
||||
suitable for the intended purpose and free from errors.
|
||||
*******************************************************************************************************/
|
||||
|
||||
//******* Setup hardware pin definitions here ! ***************
|
||||
|
||||
//These are the pin definitions for one of my own boards, the Easy Pro Mini,
|
||||
//be sure to change the definitions to match your own setup. Some pins such as DIO2,
|
||||
//DIO3, BUZZER may not be in used by this sketch so they do not need to be
|
||||
//connected and should be included and be set to -1.
|
||||
|
||||
|
||||
#define NSS 10
|
||||
#define RFBUSY 7
|
||||
#define NRESET 9
|
||||
#define LED1 8
|
||||
#define DIO1 3
|
||||
|
||||
#define LORA_DEVICE DEVICE_SX1280 //we need to define the device we are using
|
||||
|
||||
//******* Setup LoRa Parameters Here ! ***************
|
||||
|
||||
//LoRa Modem Parameters
|
||||
const uint32_t Frequency = 2445000000; //frequency of transmissions in hz
|
||||
const int32_t Offset = 0; //offset frequency in hz for calibration purposes
|
||||
const uint8_t Bandwidth = LORA_BW_0800; //LoRa bandwidth
|
||||
const uint8_t SpreadingFactor = LORA_SF8; //LoRa spreading factor
|
||||
const uint8_t CodeRate = LORA_CR_4_5; //LoRa coding rate
|
||||
const uint16_t Calibration = 11350; //Manual Ranging calibrarion value
|
||||
|
||||
const uint8_t TXpower = 10; //Transmit power used
|
||||
const uint32_t RangingAddress = 16; //must match address in recever
|
||||
|
||||
const uint16_t rangingRXTimeoutmS = 0xFFFF; //ranging RX timeout in mS
|
||||
|
||||
@@ -0,0 +1,204 @@
|
||||
/*****************************************************************************************************
|
||||
Programs for Arduino - Copyright of the author Stuart Robinson - 17/03/20
|
||||
|
||||
This program is supplied as is, it is up to the user of the program to decide if the program is
|
||||
suitable for the intended purpose and free from errors.
|
||||
*******************************************************************************************************/
|
||||
|
||||
#define programversion "V1.1"
|
||||
#define Serial_Monitor_Baud 9600
|
||||
|
||||
#include <SPI.h>
|
||||
#include <SX128XLT.h>
|
||||
SX128XLT LT;
|
||||
#include "Settings.h"
|
||||
|
||||
uint8_t distance_zero_count;
|
||||
uint16_t calvalue, calibrationstart, calibrationend;
|
||||
uint16_t rangeing_error_count, rangeing_valid_count;
|
||||
uint16_t IrqStatus;
|
||||
uint32_t endwaitmS, startrangingmS, range_result;
|
||||
float distance;
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
uint16_t index;
|
||||
distance_zero_count = 0;
|
||||
|
||||
for (index = calibrationstart; index <= calibrationend; index = index + 10)
|
||||
{
|
||||
digitalWrite(LED1, HIGH);
|
||||
LT.setRangingCalibration(index);
|
||||
Serial.print(F("TransmitRanging,Calibration,"));
|
||||
Serial.print(index);
|
||||
LT.transmitRanging(RangingAddress, TXtimeoutmS, TXpower, NO_WAIT);
|
||||
digitalWrite(LED1, LOW);
|
||||
|
||||
endwaitmS = millis() + waittimemS;
|
||||
startrangingmS = millis();
|
||||
|
||||
while (!(digitalRead(DIO1)) && (millis() < endwaitmS)); //wait for Ranging valid or timeout
|
||||
|
||||
delay(10);
|
||||
|
||||
IrqStatus = LT.readIrqStatus();
|
||||
Serial.print(F(",IRQ,"));
|
||||
Serial.print(IrqStatus, HEX);
|
||||
|
||||
if (IrqStatus & IRQ_RANGING_MASTER_RESULT_TIMEOUT)
|
||||
{
|
||||
rangeing_error_count++;
|
||||
Serial.print(F(", RangingTimeout! "));
|
||||
}
|
||||
|
||||
if (millis() > endwaitmS)
|
||||
{
|
||||
Serial.print(F(",ProgramTimeout"));
|
||||
}
|
||||
|
||||
if (IrqStatus & IRQ_RANGING_MASTER_RESULT_VALID)
|
||||
{
|
||||
rangeing_valid_count++;
|
||||
digitalWrite(LED1, HIGH);
|
||||
Serial.print(F(",Valid"));
|
||||
range_result = LT.getRangingResultRegValue(RANGING_RESULT_RAW);
|
||||
Serial.print(F(",RAW,"));
|
||||
Serial.print(range_result, HEX);
|
||||
|
||||
distance = LT.getRangingDistance(RANGING_RESULT_RAW, range_result, 1);
|
||||
|
||||
Serial.print(F(",Distance,"));
|
||||
Serial.print(distance, 1);
|
||||
Serial.print(F("m"));
|
||||
Serial.print(F(",Time,"));
|
||||
Serial.print(millis() - startrangingmS);
|
||||
Serial.print("mS");
|
||||
digitalWrite(LED1, LOW);
|
||||
}
|
||||
|
||||
Serial.print(F(",OKCount,"));
|
||||
Serial.print(rangeing_valid_count);
|
||||
Serial.print(F(",ErrorCount,"));
|
||||
Serial.print(rangeing_error_count);
|
||||
|
||||
if (distance == 0)
|
||||
{
|
||||
Serial.print(F(", Distance is Zero!"));
|
||||
distance_zero_count++;
|
||||
}
|
||||
|
||||
if (distance_zero_count >= 3)
|
||||
{
|
||||
delay(5000);
|
||||
break;
|
||||
}
|
||||
|
||||
Serial.println();
|
||||
delay(packet_delaymS);
|
||||
|
||||
}
|
||||
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
|
||||
void led_Flash(uint16_t flashes, uint16_t delaymS)
|
||||
{
|
||||
unsigned int index;
|
||||
|
||||
for (index = 1; index <= flashes; index++)
|
||||
{
|
||||
digitalWrite(LED1, HIGH);
|
||||
delay(delaymS);
|
||||
digitalWrite(LED1, LOW);
|
||||
delay(delaymS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
uint16_t Remainder;
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
Serial.begin(Serial_Monitor_Baud); //setup Serial console ouput
|
||||
Serial.println();
|
||||
Serial.println(__FILE__);
|
||||
Serial.print(F("Compiled "));
|
||||
Serial.print(__TIME__);
|
||||
Serial.print(F(" "));
|
||||
Serial.println(__DATE__);
|
||||
Serial.println(F(programversion));
|
||||
Serial.println(F("Stuart Robinson"));
|
||||
Serial.println();
|
||||
|
||||
Serial.println(F("56_Ranging_Calibration_Checker Starting"));
|
||||
|
||||
pinMode(LED1, OUTPUT);
|
||||
|
||||
led_Flash(2, 125);
|
||||
|
||||
Serial.println(F("Checking device"));
|
||||
|
||||
SPI.begin();
|
||||
|
||||
if (LT.begin(NSS, NRESET, RFBUSY, DIO1, DIO2, DIO3, RX_EN, TX_EN, LORA_DEVICE))
|
||||
{
|
||||
Serial.println(F("Device found"));
|
||||
led_Flash(2, 125);
|
||||
delay(1000);
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println(F("No device responding"));
|
||||
while (1)
|
||||
{
|
||||
led_Flash(50, 50); //long fast speed flash indicates device error
|
||||
}
|
||||
}
|
||||
|
||||
//The function call list below shows the complete setup for the LoRa device for ranging using the information
|
||||
//defined in the Settings.h file.
|
||||
//The 'Setup LoRa device for Ranging' list below can be replaced with a single function call, note that
|
||||
//the calibration value will be loaded automatically from the table in the library;
|
||||
|
||||
//LT.setupRanging(Frequency, Offset, SpreadingFactor, Bandwidth, CodeRate, RangingAddress, RangingRole);
|
||||
|
||||
//***************************************************************************************************
|
||||
//Setup LoRa device for Ranging Master
|
||||
//***************************************************************************************************
|
||||
LT.setMode(MODE_STDBY_RC);
|
||||
LT.setPacketType(PACKET_TYPE_RANGING);
|
||||
LT.setModulationParams(SpreadingFactor, Bandwidth, CodeRate);
|
||||
LT.setPacketParams(12, LORA_PACKET_VARIABLE_LENGTH, 0, LORA_CRC_ON, LORA_IQ_NORMAL, 0, 0);
|
||||
LT.setRfFrequency(Frequency, Offset);
|
||||
LT.setTxParams(TXpower, RADIO_RAMP_02_US);
|
||||
LT.setRangingMasterAddress(RangingAddress);
|
||||
LT.setRangingSlaveAddress(RangingAddress);
|
||||
LT.setDioIrqParams(IRQ_RADIO_ALL, (IRQ_TX_DONE + IRQ_RANGING_MASTER_RESULT_VALID + IRQ_RANGING_MASTER_RESULT_TIMEOUT), 0, 0); //set for IRQ on RX done
|
||||
LT.setRangingCalibration(LT.lookupCalibrationValue(SpreadingFactor, Bandwidth));
|
||||
LT.setRangingRole(RANGING_MASTER);
|
||||
LT.writeRegister(REG_RANGING_FILTER_WINDOW_SIZE, 8); //set up window size for ranging averaging
|
||||
LT.setHighSensitivity();
|
||||
//***************************************************************************************************
|
||||
|
||||
//LT.setRangingCalibration(Calibration); //override automatic lookup of calibration value from library table
|
||||
|
||||
calvalue = LT.getSetCalibrationValue();
|
||||
Remainder = calvalue / 10;
|
||||
calibrationstart = (Remainder * 10) - 1000;
|
||||
calibrationend = (Remainder * 10) + 1000;
|
||||
Serial.print(F("CalibrationStart,"));
|
||||
Serial.print(calibrationstart);
|
||||
Serial.print(F(",CalibrationEnd,"));
|
||||
Serial.println(calibrationend);
|
||||
Serial.println();
|
||||
|
||||
delay(2000);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
/*****************************************************************************************************
|
||||
Programs for Arduino - Copyright of the author Stuart Robinson - 17/03/20
|
||||
|
||||
This program is supplied as is, it is up to the user of the program to decide if the program is
|
||||
suitable for the intended purpose and free from errors.
|
||||
*******************************************************************************************************/
|
||||
|
||||
//******* Setup hardware pin definitions here ! ***************
|
||||
|
||||
//These are the pin definitions for one of my own boards, the Easy Pro Mini,
|
||||
//be sure to change the definitions to match your own setup. Some pins such as DIO2,
|
||||
//DIO3, BUZZER may not be in used by this sketch so they do not need to be
|
||||
//connected and should be included and be set to -1.
|
||||
|
||||
|
||||
#define NSS 10
|
||||
#define RFBUSY 7
|
||||
#define NRESET 9
|
||||
#define LED1 8
|
||||
#define DIO1 3
|
||||
#define DIO2 -1 //not used
|
||||
#define DIO3 -1 //not used
|
||||
|
||||
#define RX_EN -1 //pin for RX enable, used on some SX1280 devices, set to -1 if not used
|
||||
#define TX_EN -1 //pin for TX enable, used on some SX1280 devices, set to -1 if not used
|
||||
|
||||
#define LORA_DEVICE DEVICE_SX1280 //we need to define the device we are using
|
||||
|
||||
//******* Setup LoRa Parameters Here ! ***************
|
||||
|
||||
//LoRa Modem Parameters
|
||||
const uint32_t Frequency = 2445000000; //frequency of transmissions in hz
|
||||
const int32_t Offset = 0; //offset frequency in hz for calibration purposes
|
||||
const uint8_t Bandwidth = LORA_BW_0800; //LoRa bandwidth
|
||||
const uint8_t SpreadingFactor = LORA_SF8; //LoRa spreading factor
|
||||
const uint8_t CodeRate = LORA_CR_4_5; //LoRa coding rate
|
||||
const uint16_t Calibration = 11426; //Manual Ranging calibrarion value
|
||||
|
||||
const uint8_t RangingRole = RANGING_SLAVE; //Ranging role, RANGING_MASTER or RANGING_SLAVE
|
||||
const uint8_t TXpower = 10; //Transmit power used
|
||||
const uint32_t RangingAddress = 16; //must match address in recever
|
||||
|
||||
const uint16_t waittimemS = 10000; //wait this long in mS for packet before assuming timeout
|
||||
const uint16_t TXtimeoutmS = 5000; //ranging TX timeout in mS
|
||||
const uint16_t RXtimeoutmS = 0xFFFF; //ranging RX timeout in mS
|
||||
const uint16_t packet_delaymS = 250; //forced extra delay in mS between ranging requests
|
||||
const uint16_t rangeingcount = 5; //number of times ranging is cqarried out for each distance measurment
|
||||
float distance_adjustment = 1; //adjustment factor to calculated distance
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 20 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 222 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 18 KiB |
113
lib/SX12XX-LoRa/examples/SX128x_examples/Ranging/ReadMe.md
Normal file
113
lib/SX12XX-LoRa/examples/SX128x_examples/Ranging/ReadMe.md
Normal file
@@ -0,0 +1,113 @@
|
||||
## Ranging Calibration
|
||||
|
||||
**Note:** The ranging feature of the SX128X is not supported if the module uses external RX and TX switching.
|
||||
|
||||
To measure a distance the master device transmits a ranging request which a slave receives and then sends a response, if the request was for that particular slave. The master receives the slaves response and knows by use of a timer how long the master slave response exchange took.
|
||||
|
||||
The total time for the master slave exchange includes a fixed processing time for the master and slave to transmit and receive the appropriate packets. This fixed time should be static and should be the same no matter how far apart the master initiator and slave receiver are.
|
||||
|
||||
This fixed time then needs to be subtracted from the total round trip time. The remainder of the time is then proportional to the distance in a linear way.
|
||||
|
||||
Thus the ranging function needs a calibration value (the fixed time mentioned above) which changes according to the bandwidth and spreading factor used. Bandwidths of 400khz, 800khz and 1600khz are supported for ranging. The calibration value can also vary slightly between different modules or antennas used. So for the best results its suggested to calibrate a pair of modules together. The SX128XLT library does, by default, do a lookup from a pre-determined range of calibration values.
|
||||
|
||||
Its been noticed in testing that variations in distance measurements of +\-10m are not unusual and this is typically the sort of adjustment that calibration might correct for. If your using the SX128x to measure long distances, into several kilometres, then the standard values provided by the library are probably accurate enough, a variation of 10m over 4km is hardly significant.
|
||||
|
||||
There is a calibration method described in a Semtech document;
|
||||
|
||||
[Introduction to Ranging](https://semtech.my.salesforce.com/sfc/p/#E0000000JelG/a/44000000MDiH/OF02Lve2RzM6pUw9gNgSJXbDNaQJ_NtQ555rLzY3UvY)
|
||||
|
||||
My own approach to the ranging calibration has been simplified. The starting base for the calibration numbers was this table produced by Semtech;
|
||||
|
||||

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

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

|
||||
|
||||
You can see a variation in distance of +\- 10m at 100m distance is not unusual. Apart from long term averaging its difficult to see what can be done to reduce these variances.
|
||||
|
||||
It has also been noted that where there is a possibility of reflections such as in urban areas, larger variances than this have been seen particularly if the antenna orientations are moving or otherwise changed.
|
||||
|
||||
|
||||
|
||||
### Stuart Robinson
|
||||
### March 2020
|
||||
Reference in New Issue
Block a user