thotro / arduino-dw1000

A library that offers functionality to use Decawave's DW1000 chips/modules with Arduino.
Apache License 2.0
516 stars 288 forks source link

replyDelayTimeMS value (Ranging) #17

Closed leosayous21 closed 9 years ago

leosayous21 commented 9 years ago

Hi !

Thanks ! Léo

thotro commented 9 years ago

Hi!

The theoretical minimum delay is approx. 6.5ns, but since the uC is slow and needs to perform a few function calls in-between the setting of the delay and the actually toggling of the do-the-transmission bits, the DW1000 internal system counter would have passed the previously set delay already. Hence, the required delay depends on the uC clock and 10ms worked well on the smaller Arduino boards. (Don't know, but maybe you can lower the delay even a bit further!?)

Your calculation gives 25 Hz, in reality I currently experience 10-15 Hz with two Mini Pro Arduinos. Still it is likely that the tag itself doesn't require reports of its own distance, hence the fourth message may be omitted in many cases (+25% speed up ;-)). For multi-anchor systems each added anchor would only require one additional message in the protocol, so for position tracking the rate should not drop too much.

In the mode I have selected (more or less randomly) ranging should work with good accuracy and also for long distances - but that's just based on some infos gathered from the user manual. In this mode the transmissions take longer though, since the message preamble that is sent is long. So even here we may loose 1Hz or 2 in ranging frequency :-) The SHORTDATA, FAST modes are an alternative, although at the cost of maximum range.

Cheers!

leosayous21 commented 9 years ago

Hi, I tried different values, it works until 7ms only. I don't really understand why if the minimum delay is 6.5ns ? Do you know what the difference beetween 16Mhz and 64Mhz for the PRF implies?

cheers !

thotro commented 9 years ago

Hi!

That is just the theoretical IC minimum delay. The uC program runtime gives the actual limit, namely the time that passes from the "setDelay" call until the "startTransmit" call is executed. This time period needs to be smaller than the delay set, otherwise we will trigger a transmission, but have already missed the IC system clock reaching the set delay.

It seems the higher the PRF frequency, the better is ranging accuracy, but at the cost of increased power consumption - at least that's what I read from the user manual.

leosayous21 commented 9 years ago

Hi @thotro ! Thanks for you reply ! I really tried to understand why there is a limit for replyDelayTime of 6ms. They say the lower replyDelayTime is, better accuracy we get.

"3.3 Delayed Transmission [...] Minimising the response time also reduces this error, and in working to minimise this the host microprocessor may sometimes be late invoking the delayed TX, i.e. so that the system clock has passed the specified start time (i.e. internal start time mentioned above) and then the IC has to complete almost a whole clock count period before the start time is reached. [...]"

There is also an other reference of that in the "12 APPENDIX 3: TWO WAY RANGING p.211"

I first tried to go to "DW1000.MODE_LONGDATA_FAST_ACCURACY" because as the data rate is really faster, i thought the datas would pass rapidly and we could decrease the replyDelayTime value. But it doesn't change really things.

I finally find why there is such a minimum delay: you have a delay(1) at the end of wirteBytes and readBytes ! So for a transmitPollAck you have: DW1000.newTransmit() -> idle() --> writeBytes: 1ms -> clearTransmitStatus() --> writeBytes: 1ms DW1000.setData(data, LEN_DATA); -> writeBytes: 1ms DW1000.startTransmit(); -> writeTransmitFrameControlRegister() --> writeBytes: 1ms -> writeBytes: 1ms (-> startReceive(); --> writeBytes: 1ms) the total is a minimum of 5 or 6ms ...

So i tried to decrease this delay(1) in void DW1000Class::writeBytes to delayMicroseconds(10); It seems that all is working fine so i also change the void DW1000Class::readBytes in doing the same.

And now it works with a replyDelayTimeMS = 2; but not 1ms. But with 2ms i obtain a really good frequency : around 11ms for each ranging ! that is: 91Hz

In the user manual at the p.212 they go down to 96uS ! So there is still optimisation we can do:

I will try to decrease that and let you know !

Hope this will be helpful! Cheers, Léopold

EDIT: The minimum duration i get was 1ms repy time and 5ms (200Hz) in total using DW1000.MODE_SHORTDATA_FAST_ACCURACY . But with this mode the accuracy is worth in shortdata. For the longdata, i can't have less than 1.9ms for replytime !

thotro commented 9 years ago

Thanks Léopold for investing your time to greatly optimize the code! I already merged your commit.