I am currently participating in a IoT project that uses a hardware platform based on the Espressif ESP32 chipset, with a pluggable module architecture, one of which contains a Decawave DWM1000. The project, of course, involves locating a tag using a couple of anchors with known coordinates, and I am currently performing tests for distance accuracy. However, I am yet to achieve the expected precision in the distance measurement, because the calculation result fluctuates by 50 cm to 1 m, and even sometimes spiking to 2m errors, all with the anchor and tag devices (one of each) completely stationary and in direct line of sight of each other.
- The ESP32 board is powered from a 5V, 2.4A USB power charger for both anchor and tag devices
- The ESP32 board has WiFi active, both as a debugging tool, and as a means to transmit MQTT messages containing the calculated position to plot on a map.
- The DWM1000 plug-in board, as far as I know, runs on its default internal oscillator. No external or temperature-compensated oscillator has been added to the board.
- The code is supposed to use an revised version of asymmetric two-way ranging (all timestamps are in Decawave clock units):
- Tag sends a poll packet with its own EUI every 500ms to announce itself to any anchor in range, and stores the transmission timestamp internally on TX interrupt
- Anchor receives packet, takes note of reception timestamp, waits a bit for radio silence, transmit a poll acknowledge, and stores transmission timestamp internally on TX interrupt
- Tag receives poll acknowledge, takes note of reception timestamp, and sends a range request packet containing the poll transmission timestmap, poll ack reception timestamp, and an estimate of the impending range packet transmission timestamp using the current timestamp plus 3000us converted to Decawave clock units, plus the current TX antenna delay. This transmission uses the delayed-transmission feature of the Decawave.
- Anchor receives range request packet, takes note of reception timestamp, and calculates the time-of-flight using the asymmetric two-way ranging formula
- Anchor converts time-of-flight to distance using the library conversion constant, then (supposedly) corrects the distante using the reception power measurement, and transmits the value back to the tag
The Decawave-specific code has two layers. The lower layer is at https://github.com/yubox-node-org/arduino-dw1000-ng/tree/alex-concurrency-workaround2 which is a personal fork of the arduino-dw1000-ng code with tweaks to make it stable on the ESP32, which include at least the following changes I made:
- 846891bd744172bd8e3859303fff4ad3fe446c7d Use a separate mask to clear SYS_STATUS bits, otherwise I lose event bits
- 08f7a432bc537829aee613a4427cc35056b8932d Move direct interrupt handling to a separate ESP32 task
- f34ca830c775df4ce149d996fa0ef8f6894f0efd Use 64-bit values to handle Decawave timestamps, rather than risking truncation of 5-byte values to 4-byte longs
Additionally, in searching for the cause of the fluctuations, I am now correcting for the following conditions not addressed by the upstream Arduino library:
- The 5-byte Decawave timestamps wrap around every 17 seconds, so two timestamps measurements may fall on opposite ends of the wraparound. This is guarded-for and fixed in my code.
- The Decawave User Manual states in section 3.3 Delayed Transmission that the delayed transmission timestamp will ignore the lower 9 bits of the start-of-transmission value. My code adds the required value so that the resulting future transmission timestamp will have the lower 9 bits set to 0.
As I have noticed that the reception timestamps get scrambled by packet collisions, I have (for now) kept the test to one anchor and one tag. Yet the fluctuations persist.
As stated previously, the problem I am seeing is that the result of the calculation fluctuates by up to 1 meter, even at the distance I attempt to use for a simple antenna delay calibration (6.6m). As a result, the antenna delay calibration converges slowly, and then does not stay in one value, but fluctuates across more than one hour of attempted calibration. Additionally, even with the calibration at the known distance, a shorter distance also fluctuates around an incorrect distance (5m measured as 5.5m, 4m measured as 2.9m). The reception power correction appears to be on the order of a few tens of centimeters, but the errors I am seeing are much greater, and variable.
I have read about the influence of temperature in the internal oscillator, and I have attempted to calibrate after a delay of a few minutes, but this does not stop the timestamp measurements from fluctuating.
What other factors (in software or hardware design) could be influencing and causing the fluctuations in measured distance?