Seeed-Studio / Seeed_Arduino_DopplerRadar

Arduino library for DopplerRader
MIT License
3 stars 6 forks source link

Timing issues cause getSpeed() to wrongly return the maximum speed of 65535 #3

Open adriaanb opened 4 years ago

adriaanb commented 4 years ago

The library appears to be timing sensitive, the code examples use delays to produce accurate readings.

Using non-blocking alternatives (such as millis()) when working with other timing-sensitive libraries does not work reliably.

Calling getSpeed() too frequently causes it to intermittently return the maximum speed of 65535. This also happens when calling it right after getTargetState(), which is implemented using a 20 millisecond delay.

A non-blocking implementation of getTargetState() may solve some of these issues. It would also be helpful if the library could provide a way to ask if a function is ready to be called again/generate a new reading.

This behavior was observed on an Arduino Nano 33 IoT (SAMD21).

x29a commented 1 year ago

As far as i now understand, both getSpeed() and getTargetState() call the same serial command BGT24LTR11_COMMAND_GET_TARGET and just evaluate the response data differently.

Neither checks the checksum though, so that itself might help as well.

x29a commented 1 year ago

Please see this PR #9 to work without the delay. An even better improvement would be to do all the reading of serial data, and then do the parsing independently, but this is a bigger change

x29a commented 1 year ago

Having worked more with this board, i can confirm that sometimes, when calling a query function very often and very quickly, the board simply does not return any data, so the parsing loop while (_serial->available() > 0) { returns immediately and the getSpeed() method uses -1 as error return which will then rollover to the maximum uint16_t value that you describe. With my additions, this can also happen on a checksum mismatch. I stuck with the -1 for consistency, albeit a speed of 0 might not be considered a speed ;)

I tried to mitigate this scenario by clearing the RX buffer, then sending the C1 command, then flushing the serial port, then waiting for up to 3ms when there is no data, then starting with the protocol parsing. didnt help.

i assume (but dont know) that this might be a collision with the periodic automatic sending of the data by the board (every 300ms), so its too busy to respond at all.