SX1280 ranging configuration


I am quite new to LoRa and bought a demo board with the SX1280. Currently I am wiriting a driver for the chip and used the datasheet as a reference. Now I am trying to use two chips for ranging as described in chapter 14.5 in the datasheet. I do get results, but the measured distance is way off and there is a rather big deviation between single measurements. In order to find possible mistakes I compared my code and confoguration of both chips (master and slave) with the driver and ranging demo provided by semtech.

Both chips are configured in accordance to the settings shown in chapter 14.5. The ranging result is obtained by the master with the conversion formula as described. The master starts a ranging measurement by calling the SetTx() function. The slave is configured to listen continously by calling the SetRx() function. All in all, I think I am quite close to the solution, but I still might miss a little detail. I provided the configuartion for the master for verifaction. I would be happy to get some help with the proper configuration

// Set standby mode with RC oscillator
sx1280_SetStandby(hSX1280, SX1280_STANDBY_MODE_RC);

// Set packet type ranging
sx1280_SetPacketType(hSX1280, SX1280_PACKET_TYPE_RANGING);

// Set modulation parameters: Spreading factor 7, bandwidth 1625 kHz, coding range 4/7
sx1280_SetModulationParams(hSX1280, SX1280_LORA_SF_7, SX1280_LORA_BW_1600, SX1280_LORA_CR_4_7);

// Set packet parameters:
// Preamble length: 12
// Header Type: 0 (Explicit Header)
// PayloadLength: 10
// CRC: 0x20 (2 Byte CRC)
sx1280_SetPacketParams(hSX1280, 12, 0x00, 10, 0x20, 0x40, 0x00, 0x00);

// Set frequency: 2.4 GHz
sx1280_SetRfFrequency(hSX1280, 12098953);

// Set TX parameters:
// 0 dBm power
// 20us ramp time
sx1280_SetTxParams(hSX1280, 18, SX1280_RADIO_RAMP_TIME_20_US);

// Get calibration value (13220)
uint32_t calibrationValue = sx1280_LookupCalibrationValue(SX1280_LORA_SF_7, SX1280_LORA_BW_1600);

// Store calibration value to buffer
uint8_t calibrationValueBuf[] = {
((calibrationValue >> 16) & 0xFF),
((calibrationValue >> 8) & 0xFF),
(calibrationValue & 0xFF)};

// Write calibration value to register
sx1280_WriteRegister(hSX1280, SX1280_RANGING_CALIBRATION_BYTE_2, (uint8_t*)&calibrationValueBuf, sizeof(calibrationValueBuf));

// Address
uint8_t address[] = {
// Set address to both, device and request register
sx1280_WriteRegister(hSX1280, SX1280_RANGING_REQUEST_ADDRESS_BYTE_3, (uint8_t*)&address, sizeof(address));
sx1280_WriteRegister(hSX1280, SX1280_RANGING_DEVICE_ADDRESS_BYTE_3, (uint8_t*)&address, sizeof(address));

// Set IRQ mask (result valid & timeout)
uint32_t irqMsk = (SX1280_IRQ_RangingMasterResultValid_Msk | SX1280_IRQ_RangingMasterTimeout_Msk);
uint32_t dio1Msk = SX1280_IRQ_RangingMasterResultValid_Msk;
uint32_t dio2Msk = SX1280_IRQ_RangingMasterTimeout_Msk;
uint32_t dio3Msk = 0x00;

// Write masks
sx1280_SetDioIrqParams(hSX1280,irqMsk, dio1Msk, dio2Msk, dio3Msk);

// Set ranging role master
sx1280_SetRangingRole(hSX1280, SX1280_RANGING_ROLE_MASTER);

// Clear all IRQ flags
sx1280_ClearIrqStatus(hSX1280, 0xFFF);

// Start transmission
sx1280_SetTx(hSX1280, SX1280_PERIOD_BASE_1_MS, 0xFFFF);

Way off ?

Rather big deviation ?

Specific figures would be useful.

How did you calibrate your setup ?

The results are off by a factor of 30. For example: When positioning both chips on my desktop about 30 cm apart, the read value is 10 m. This deviation remains constant when increasing the distance between both chips.

Is there further calibration needed?

Yes, see the comment in the datasheet;

“For more details about calibration in ranging, see the Application Note “Introduction to Ranging for SX1280” on

The ranging is not really that effective at sub 100m distances, but works great at 1km or more.