Pass data in messages used for TWR

In the DWM3000 API, there are some examples, among which there is a TWR-example that has an initiator and a responder. The intiator sends a poll message, the responder responds with a response-message and the initiator sends back a Final message, enabling the responder to calculate the TOF from time-stamps (among other included in the final message). However, I need to get this distance measurement to the initiator, and for efficiency reasons, I would like to include it in the RESP-message. But how should I do this? If I simply increase the message-size in the code, it seems to mess with the time-stamps, and I get negative values for the distance measurement. So hence the question:

How to efficiently (optimize w.r.t. time) execute TWR, and at the same time do some data-transfer?


Is all the information known at that time? To calculate a TWR distance you need to know the responders Rx time for the final message. Without this it’s purely single sided ranging and so the errors will be large unless you have some other way to correct for clock errors.

Two possible solutions are that after receiving the final message the responder sends one more message containing all of the required time measurements to the initiator. The times for this message are unimportant, it’s purely a data message.

The other option is to increase the size of the RESP message to include the extra data. The amount of data needed is small in comparison to things like headers and preamble so it’s not a significant performance hit. But since you don’t know all the information at that time you have to run one range behind. e.g. the second range measurement attempts RESP packet includes the measurement time information for for the first ranges measurement. Less packets but more latency.

To give you a ballpark for what is possible, at 6.8Mb/s data rate I was able to perform a 4 packet TWR (3 timed packets plus one data) in just under 1 ms. At 850kb/s that increased to 1.25 ms.
Going to a group based system where one initiator message triggers multiple anchors to respond at fixed intervals increased to 2400 measurements per second split evenly across 8 anchors.

Hi AndyA,

Thank you for your answer. Indeed, we would have a one sample-time delay if we would send distance with the RESP-message. It’s just that I haven’t managed to increase the size of the RESP-message without messing up the distance-measurement. (I can either use the example and get ok distance measurement, or I increase the size of the RESP message and send some data successfully, but then my distance measurement is incorrect…). I seem to be doing something wrong in increasing the size of the RESP message. How is this done properly?

But judging from the performance figures you give, the 4-packet TWR seems to do very well either way. So I’ll probably give that a try too.



I’ve not used the example code myself but taking a quick look at it I can’t see any obvious reasons why increasing the size would cause any issues as long as you increase the buffers and packet size values appropriately. You may also have to increase some timeouts slightly since longer messages take more time.

The advantage of the 4 packet method is that each range is stand alone which makes the code simpler, you don’t need to keep track of multiple measurements data at the same time. I like things that make life simpler :slight_smile:

My system that gave those numbers is highly optimised for speed and has the times & packet sizes as small as I could get, I doubt you’d be able to hit those rates with the standard examples. But it doesn’t sound like having to deviate from the example is an issue for you if you need to.

Thank you for the leads! I suspect it might indeed be an incorrect timeout. But in the end I’ll probably go for the 4-messages approach (simple life is a happy life :)).

regarding ss-twr: used it once for a project and by using the carrier integrator value to compensate clock drift the calculated range was similar to the quality of ds-twr (as long as the antenna delay is calibrated correctly).
I worked with the dwm1000, but I think it will be quite the same for the dwm3000.