[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 distance between the modules using time-of-flight
measurement. 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 For default module settings, see the wiki page
https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx128x---lora-modem https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx128x---lora-modem
@ -57,12 +60,24 @@ void loop() {
int state = radio.range(false, 0x12345678); 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) { if (state == RADIOLIB_ERR_NONE) {
// ranging finished successfully // ranging finished successfully
Serial.println(F("success!")); Serial.println(F("success!"));
Serial.print(F("[SX1280] Distance:\t\t\t")); Serial.print(F("[SX1280] Distance:\t\t\t"));
Serial.print(radio.getRangingResult()); Serial.print(radio.getRangingResult());
Serial.println(F(" meters")); Serial.println(F(" meters (raw)"));
} else if (state == RADIOLIB_ERR_RANGING_TIMEOUT) { } else if (state == RADIOLIB_ERR_RANGING_TIMEOUT) {
// timed out waiting for ranging packet // 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 // start ranging
int16_t state = startRanging(master, addr); int16_t state = startRanging(master, addr, calTable);
RADIOLIB_ASSERT(state); RADIOLIB_ASSERT(state);
// wait until ranging is finished // wait until ranging is finished
@ -31,7 +31,7 @@ int16_t SX1280::range(bool master, uint32_t addr) {
return(state); 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 // check active modem
uint8_t modem = getPacketType(); uint8_t modem = getPacketType();
if(!((modem == RADIOLIB_SX128X_PACKET_TYPE_LORA) || (modem == RADIOLIB_SX128X_PACKET_TYPE_RANGING))) { 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); state = setDioIrqParams(irqMask, irqDio1);
RADIOLIB_ASSERT(state); RADIOLIB_ASSERT(state);
// set calibration values // this is the default calibration from AN1200.29
uint8_t index = (_sf >> 4) - 5; uint16_t calTbl[3][6] = {
static const uint16_t calTable[3][6] = {
{ 10299, 10271, 10244, 10242, 10230, 10246 }, { 10299, 10271, 10244, 10242, 10230, 10246 },
{ 11486, 11474, 11453, 11426, 11417, 11401 }, { 11486, 11474, 11453, 11426, 11417, 11401 },
{ 13308, 13493, 13528, 13515, 13430, 13376 } { 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; uint16_t val = 0;
switch(_bw) { switch(_bw) {
case(RADIOLIB_SX128X_LORA_BW_406_25): case(RADIOLIB_SX128X_LORA_BW_406_25):
val = calTable[0][index]; val = calTbl[0][index];
break; break;
case(RADIOLIB_SX128X_LORA_BW_812_50): case(RADIOLIB_SX128X_LORA_BW_812_50):
val = calTable[1][index]; val = calTbl[1][index];
break; break;
case(RADIOLIB_SX128X_LORA_BW_1625_00): case(RADIOLIB_SX128X_LORA_BW_1625_00):
val = calTable[2][index]; val = calTbl[2][index];
break; break;
default: default:
return(RADIOLIB_ERR_INVALID_BANDWIDTH); return(RADIOLIB_ERR_INVALID_BANDWIDTH);

View file

@ -30,9 +30,11 @@ class SX1280: public SX1281 {
\param addr Ranging address to be used. \param addr Ranging address to be used.
\param calTable Ranging calibration table - set to NULL to use the default.
\returns \ref status_codes \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. \brief Interrupt-driven ranging method.
@ -41,9 +43,11 @@ class SX1280: public SX1281 {
\param addr Ranging address to be used. \param addr Ranging address to be used.
\param calTable Ranging calibration table - set to NULL to use the default.
\returns \ref status_codes \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. \brief Gets ranging result of the last ranging exchange.