[SX128x] Added option to set custom ranging calibration (#293)

This commit is contained in:
jgromes 2023-01-01 18:31:03 +01:00
parent 088207df4c
commit a0884bf120
3 changed files with 39 additions and 13 deletions

View file

@ -6,7 +6,10 @@
distance between the modules using time-of-flight
measurement.
Only SX1280 and SX1282 support ranging!
Only SX1280 and SX1282 without external RF switch support ranging!
Note that to get accurate ranging results, calibration is needed!
The process is described in Semtech SX1280 Application Note AN1200.29
For default module settings, see the wiki page
https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx128x---lora-modem
@ -57,12 +60,24 @@ void loop() {
int state = radio.range(false, 0x12345678);
*/
// if ranging calibration is known, it can be provided
// this should improve the accuracy and precision
/*
uint16_t calibration[3][6] = {
{ 10299, 10271, 10244, 10242, 10230, 10246 },
{ 11486, 11474, 11453, 11426, 11417, 11401 },
{ 13308, 13493, 13528, 13515, 13430, 13376 }
};
int state = radio.range(true, 0x12345678, calibration);
*/
if (state == RADIOLIB_ERR_NONE) {
// ranging finished successfully
Serial.println(F("success!"));
Serial.print(F("[SX1280] Distance:\t\t\t"));
Serial.print(radio.getRangingResult());
Serial.println(F(" meters"));
Serial.println(F(" meters (raw)"));
} else if (state == RADIOLIB_ERR_RANGING_TIMEOUT) {
// timed out waiting for ranging packet

View file

@ -5,9 +5,9 @@ SX1280::SX1280(Module* mod) : SX1281(mod) {
}
int16_t SX1280::range(bool master, uint32_t addr) {
int16_t SX1280::range(bool master, uint32_t addr, uint16_t calTable[3][6]) {
// start ranging
int16_t state = startRanging(master, addr);
int16_t state = startRanging(master, addr, calTable);
RADIOLIB_ASSERT(state);
// wait until ranging is finished
@ -31,7 +31,7 @@ int16_t SX1280::range(bool master, uint32_t addr) {
return(state);
}
int16_t SX1280::startRanging(bool master, uint32_t addr) {
int16_t SX1280::startRanging(bool master, uint32_t addr, uint16_t calTable[3][6]) {
// check active modem
uint8_t modem = getPacketType();
if(!((modem == RADIOLIB_SX128X_PACKET_TYPE_LORA) || (modem == RADIOLIB_SX128X_PACKET_TYPE_RANGING))) {
@ -86,23 +86,30 @@ int16_t SX1280::startRanging(bool master, uint32_t addr) {
state = setDioIrqParams(irqMask, irqDio1);
RADIOLIB_ASSERT(state);
// set calibration values
uint8_t index = (_sf >> 4) - 5;
static const uint16_t calTable[3][6] = {
// this is the default calibration from AN1200.29
uint16_t calTbl[3][6] = {
{ 10299, 10271, 10244, 10242, 10230, 10246 },
{ 11486, 11474, 11453, 11426, 11417, 11401 },
{ 13308, 13493, 13528, 13515, 13430, 13376 }
};
// check if user provided some custom calibration
if(calTable != NULL) {
memcpy(calTbl, calTable, sizeof(calTbl));
}
// set calibration values
uint8_t index = (_sf >> 4) - 5;
uint16_t val = 0;
switch(_bw) {
case(RADIOLIB_SX128X_LORA_BW_406_25):
val = calTable[0][index];
val = calTbl[0][index];
break;
case(RADIOLIB_SX128X_LORA_BW_812_50):
val = calTable[1][index];
val = calTbl[1][index];
break;
case(RADIOLIB_SX128X_LORA_BW_1625_00):
val = calTable[2][index];
val = calTbl[2][index];
break;
default:
return(RADIOLIB_ERR_INVALID_BANDWIDTH);

View file

@ -30,9 +30,11 @@ class SX1280: public SX1281 {
\param addr Ranging address to be used.
\param calTable Ranging calibration table - set to NULL to use the default.
\returns \ref status_codes
*/
int16_t range(bool master, uint32_t addr);
int16_t range(bool master, uint32_t addr, uint16_t calTable[3][6] = NULL);
/*!
\brief Interrupt-driven ranging method.
@ -41,9 +43,11 @@ class SX1280: public SX1281 {
\param addr Ranging address to be used.
\param calTable Ranging calibration table - set to NULL to use the default.
\returns \ref status_codes
*/
int16_t startRanging(bool master, uint32_t addr);
int16_t startRanging(bool master, uint32_t addr, uint16_t calTable[3][6] = NULL);
/*!
\brief Gets ranging result of the last ranging exchange.