DW1000 WRONG range when using 2 or above anchors and 1 tag

Hello everyone!

I start learning DW1000 chip, Arduino Uno and this lib https://github.com/thotro/arduino-dw1000.
When using 1 Tag and 1 Anchor, measured range is quite correct, but when using 1 Tag and 2 Anchor, only first Anchor that Tag connected shows correct range, second Anchor shows very wrong range: measured range = real range - x (x is very huge). So sometimes, if second Anchor is near the Tag, measured range will be negative. If I shutdown 1 of 2 active anchor, the remaining anchor show correct range.

Arduino Code

I am using example tag code, anchor code of above lib (https://github.com/thotro/arduino-dw1000)

  • DW1000Ranging_ANCHOR
  • DW1000Ranging_TAG

For each anchor, I was set with different address.

Pin Connection

Arduino Uno DWM1000
10 CS
13 CLK

Processes that I log when using 2 anchor, 1 tag (no mention to BLINK, RANGING_INIT message)

  • Tag send POLL message (broadcast).
  • 2 Anchor receives POLL message and send POLL_ACK message back.
  • Tag receive 2 POLL_ACK message from 2 anchor and then send RANGE message (Broadcast)
  • 2 Anchor receives POLL_ACK and compute range then send RANGE_REPORT message back to the tag.

Maybe i need connect some more DW1000 pin, but i’m not sure because 1 anchor and 1 tag working fine.
Does anyone face this issue? Please help me, thanks all.

What are you doing to ensure the two replies from the anchors aren’t being sent at the same time as each other and so interfering? Your code needs to ensure you avoid two radios transmitting at the same time. The gap needs to be long enough not only for the packet to be sent but for the tag to read the packet and re-arm the DW1000 receiver.
Is the tag correctly tracking which reply is from which anchor?

Each anchor have its own relay delay (anchor 1: 7000us, anchor 2: 21000us). This is process that i log in the tag

Send Poll: Broadcast
Set timePollSent
_networkDevicesNumber: 2
Recieve: 1300
Receive POLL_ACK
Set timePollAckReceived
Recieve: 1320
Receive POLL_ACK
Set timePollAckReceived
Send Range: Broadcast
Set timeRangeSent
_networkDevicesNumber: 2
Recieve: 1300
82-130: 0.24
Recieve: 1320
84-132: -0.92

82 - 130 - 1300: Anchor 1 short address
84 - 132 - 1320: Anchor 2 short address

  • The anchor 2 (The second anchor that connect to the tag): have wrong range (nagative range)


I am attempting to calculate the distance, but I am receiving incorrect results, and the distance is showing as negative. Here is the code for distance calculation:

static void rx_ok_cb(const dwt_cb_data_t *cb_data)
uint32 frame_len;

/* Clear good RX frame event in the DW1000 status register. */
dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_RXFCG);

/* A frame has been received, read it into the local buffer. */
frame_len = dwt_read32bitreg(RX_FINFO_ID) & RX_FINFO_RXFLEN_MASK;

/* Clear local RX buffer to avoid having leftovers from previous receptions. This is not necessary but is included here to aid reading the RX
 * buffer. */
for (int i = 0 ; i < frame_len; i++ )
	rx_buffer[i] = 0;

if (frame_len <= RX_BUF_LEN)
	dwt_readrxdata(rx_buffer, frame_len, 0);

/* Check that the frame is the expected response from the companion "SS TWR responder" example.
 * As the sequence number field of the frame is not relevant, it is cleared to simplify the validation of the frame. */
rx_buffer[ALL_MSG_SN_IDX] = 0;
if (memcmp(rx_buffer, rx_resp_msg, ALL_MSG_COMMON_LEN) == 0)
	uint32 poll_tx_ts, resp_rx_ts, poll_rx_ts, resp_tx_ts;
	int32 rtd_init, rtd_resp;
	float clockOffsetRatio ;

	/* Retrieve poll transmission and response reception timestamps. See NOTE 9 below. */
	poll_tx_ts = dwt_readtxtimestamplo32();
	resp_rx_ts = dwt_readrxtimestamplo32();

	/* Read carrier integrator value and calculate clock offset ratio. See NOTE 11 below. */
	clockOffsetRatio = dwt_readcarrierintegrator() * (double)((FREQ_OFFSET_MULTIPLIER * HERTZ_TO_PPM_MULTIPLIER_CHAN_2) / 1.0e6) ;

	/* Get timestamps embedded in response message. */
	resp_msg_get_ts(&rx_buffer[RESP_MSG_POLL_RX_TS_IDX], &poll_rx_ts);
	resp_msg_get_ts(&rx_buffer[RESP_MSG_RESP_TX_TS_IDX], &resp_tx_ts);

	/* Compute time of flight and distance, using clock offset ratio to correct for differing local and remote clock rates */
	rtd_init = resp_rx_ts - poll_tx_ts;
	rtd_resp = resp_tx_ts - poll_rx_ts;

	tof = ((rtd_init - rtd_resp * (1.0f - (double)clockOffsetRatio)) / 2.0f) * DWT_TIME_UNITS;
	distance = (tof * SPEED_OF_LIGHT);
     /* Set corresponding inter-frame delay. */
tx_delay_ms = DFLT_TX_DELAY_MS;