I am customizing my own TWR protocol. However, it takes about 1.6ms for one round. 900us for poll to response and 700us for response to final. I think these numbers are higher than what is given in the SDK examples. I would like to know what is the typical number for TWR turnaround time.
One possible reason is that I enable all the CIA diagnostic registers. I would like to know how large the impact is for the processing latency when I enable these registers.
Otherwise, do you have any other suggestions that I can speedup TWR?
How fast are you running the SPI bus? If you are reading all the CIR data then that’s a lot of information which will take time to read.
The other part that can make a huge difference is what exactly you are transmitting. Long preambles and large data packets take time to send. e.g. a 256 symbol preamble is ~270 us, 512 is over 500 us. If you then add in a lot of data the packet transmission time can severely limit your update rate.
The Step 1 section of the TWR tab of the spreadsheet here Transmission Time - #2 by AndyA can calculate the time taken for any given packet. It was done for the DW1000 but unless you turn on STS the packet structure is the same so the results are still valid.
For reference by stripping everything to the bare minimum I managed to reliably run a DS-TWR exchange (4 packets in total) in 1 ms using 6.8Mb/s or 1.2 ms at 850kb/s. But that was stripping everything back to the absolute minimum.
The other trick is to use the same tag start message to measure to multiple anchors, each anchor then responds at a slightly different time. Since you end up sending less messages total for each set of ranges you can get more ranges in a fixed amount of time. This results in a slower maximum rate per anchor but a higher total range measurment rate. Doing this I can reliably hit 2,400 DS-TWR ranges per second.
Thanks for your detailed explanation. It gives me more inspiration on how to further optimize my program. The spreadsheet is super helpful, thank you for sharing. I will play around and find the best parameters for me.
I use 32Mbps SPI and reads RSSI and PoA from diagnostic registers. (I would like to know if 32M is a reasonable number)
The DW3000 is rated to 38 MHz on the SPI bus so there may be room for a slight improvment there but if you’re only reading a couple of bits of information then it’s probably not going to make any meaningful difference.
I achieved the timings I gave on a DW1000 with the SPI running at half that speed (it has a max of 20 MHz) so as long as you aren’t trying to read the full CIR data it shouldn’t be an issue.
Are you running interrupt based or polling the part? Interrupt based will let you detect things a little bit faster normally but if you are polling at a high enough rate it doesn’t make any meaningful difference.
I am trying your advice that each anchor responds at a slightly different time, with the help of double buffering. I try to enable rx immediately after I receive the data. But I found the time difference between anchors is about 240~250 us; otherwise, the tag will miss the message. This is a little big larger than I expected. Could you help me check whether this number is reasonable or there is something else I am missing that I could improve the time difference.
How long is your radio packet? For hopefully obvious reasons your gap between packets needs to be longer than the packet length.
A preamble of 128 symbols is 138.4 us. 256 symbols is 268 us. So for 240us to work I assume you have a preamble length of 128 or less.
At 6.8 Mb/s and a preamble of 128 symbols 32 bytes of data would make your radio packet 200us long. Which allowing for tim to re-arm the receiver makes me think that’s roughtly the configuration you’re using.
Here is my configuration and my data size is less than 16 bytes. Would that mean it should be about 100us long? I use the calculator you provide and it takes about 120us. Another question I want to ask is that will simultaneous receiving from antenna and SPI reading from diagnostic registers harm rx performance?
Assuming you’re using the double buffered receive buffers you should be able to read one set of receive registers while receiving a radio packet into the other set. I’m not aware of this causing any decrease in performance.
At which point I’d expect you to be able to drop the spacing down to more like 150-200us for that size packet. That is assuming your SPI bus is fast enough and and the amount you’re trying to read from the buffers is small enough to transfer in that time. I can’t think of any fundamental reason why it needs to be quite so high.
Only registers that are explicitly listed as being part of the double buffered set will work while doing that, others could get reset by the rx re-arm. And there are some code complexities in ensuring you keep things in sync between reading and receiving. At least last time I looked into this (it’s been a while) I seem to remember thinking that it was possible to get out of sync and try to read the same buffer as you were receiving into.