As we mentioned before, we're using the ESP-NOW protocol for our radio layer. The primary purpose is to synchronize the two devices and give the receiver a reference point to use in calculating distance. A second benefit is that we can "squelch" the receiving transducers until we are expecting a signal to show up which helps avoid random triggers. ESP-NOW is lightweight compared to full blown WIFI, and Espressif even advertises it as having "millisecond-level" delay for an application like a remote control - this is all fine. In our application, however, the consistency of the timing is more important than the overall latency.
In this image the yellow edge is triggered by the transmitting device, and the blue edge is a pin on the receiving device that is pulled high when the message is received.
As you can see, the time between the two edges is not completely consistent. I believe there are a variety of reasons, but the main one is that the protocol doesn't operate in real-time like other code does, meaning that the time between receiving the signal and processing the data is not deterministic. It looks like the variation falls inside a 60 microsecond window, with the occasional (1 out of 100ish) even that deviates by a few hundred microseconds.
In practice we think this is good enough:
343 m/s (speed of sound) / 1000000 microseconds/second = .000343 meters/microsecond
.000343 * 60 microseconds (variability) = .020 meters
Having 20 mm of uncertainty is pretty acceptable for the applications we have in mind. This wouldn't make a great ruler, but the error from this source is probably less significant than other issues like line-of-sight and echoes. We can also clean this up with some averaging in software.
On the bright side, this only affects the distance measurement: the angle measurement only compares the arrival of the two ultrasound signals to each other.
Why not use something better?
We might be able to use an external radio and a proper interrupt on one of the ESP pins to mitigate this issue, but here are some reasons we haven't (yet):
- No additional components needed
- We can encode additional information in the packet, a stop/start signal for example, or data to implement a complete remote control
- It's easy to use an implement
- It doesn't affect the angle measurement
- The result is good enough
That's all for this one. We can see how this affects the real-world results later.