Aftermarket automotive backup sensors are cheap and ubiquitous. They use transducers to produce an inaudible ping and receive the reflected response - the time it takes for the ping to return indicates how far away any potential obstacles may be, which is shown on some kind of dash-mounted display. These transducers are very similar to those found in the maxbotix ultrasonic proximity sensor but are significantly cheaper. So what's the difference? The automotive kits don't include the fancy USB interface to programmatically read the data. However, with a little bit of tinkering you can intercept the data signal connected to the dash display and read the data just the same.
Automotive backup sensor kit
Most backup sensor kits include 4 transducers, a control box, a power cable, a display, and a hole saw. The control box generates the pings for the transducers, listens for the ping response time from the transducers, interprets the response times as distances, and finally aggregates those distances to send to the display.
Show me the data!
You can intercept the aggregated distance data by connecting a microcontroller to the display cable, but you'll first need to identify the data pin by taking a look inside the control box. Open the control box by removing the 2 screws in the bottom of the case. If you are lucky, the silkscreen on the board will include a label for each pin as shown in the red box in the image below. G is for ground, D is for data, + is for display power. You might also see a B for buzzer, but not all kits have it.
If you're not so lucky, your board may be completely blank. That's a bummer, but it's not a blocker and you can still figure it out. First, connect the power cable to the control box and a 12v supply. Make sure nothing but the power supply is plugged into the control box. Carefully use a multimeter to check for voltage between ground and each of the display cable pins. If your board has 3 pins one of them should have no voltage - this is ground. Another pin should have 5v - this is the display power. Finally, one should have a low, fluctuating voltage - that's the data pin. If your board has 4 display pins, there will also be a second pin with no voltage, one of which is the buzzer and the other is ground. Change your mulitmeter to measure resistance and compare the two 0 voltage pins with ground. The one with no connection (infinite resistance) to ground is the buzzer. At this point you might want to label the pins so you don't have to do it again.
Understanding the data
If you just want to get the data and move on, you can skip ahead to the next section. If you're compulsively curious about how things work, read on.
Using a Saleae logic analyzer connected between the data pin and ground, you can observe the signals between the control box and the display. You might notice that the board's data line is nominally low and the width of the high pulses changes as you move things around in front of the sensors.
After sufficient arm waving and some strange looks from people in your vicinity, you might start to notice a pattern; there is a consistent 2 ms high pulse followed by a 0.01 ms high pulse, which is then followed by 32 more high pulses of either 0.01 ms or 0.02 ms. At this point you might take a wild guess that a 0.01 ms high pulse represents a 0 and a 0.02 ms high pulse represents a 1.
The 2 ms high pulse followed by the 0.01 ms high pulse is a header flag that indicates the beginning of data. The following 32 pulses represent the data itself - 8 bits for each of the 4 sensors. By observing how the data changes in response to motion in front of the sensors, you can determine which 8 bits correspond to which sensor.
An example trace from the data pin is shown below.
By comparing some physical measurements to the observed data signal, you can determine that the integer data is ~10cm per unit, so a reading of 4 would indicate an object ~40cm away from the sonar. A value of 255 indicates that no obstacle is detected because the sensor did not receive a reflected response from the ping. Note that the maximum range of these sensors appeared to be around 150 cm. Anything further away returned a value of 255. The following table shows an example of how to map the trace shown above to distance measurements.
|Sensor A||Sensor D||Sensor C||Sensor B|
Reading the data
Now that you understand the data format, you can interface with the control box. However, because the data is transmitted in a non-standard format (no, variable pulse width binary is not standard!), you have to write some custom code.
One option for reading the signal is via a GPIO pin on a microcontroller such as an Arduino or an ESP. Using either polling or interrupts to detect a pulse, you can then use a timer to measure the width of each pulse. When the header flag pulses are detected, you can fill a buffer with the following 32 pulse widths. The Sonar RE github project includes code examples for both the polling-based and interrupt-based solutions on an ESP32 thing.
The disadvantages of polling and interrupt based methods include strict timing requirements of your code and heavy processor use, respectively. To get around these problems you can use built in methods of reading data signals, such as SPI.
Instead of using polling or interrupts to check for the pulses, you can use a device that has SPI support by connecting the display data pin to the SPI MISO pin. The SPI communication interface uses low level systems to deal with timing and recording of data pulses so you don't have to do it yourself in the code with polling or interrupts. However, because the display data is not a proper SPI interface, you will have to adjust the SPI data rate and do some additional parsing of the result.
You will have your system read a number of bytes from the MISO pin and to do so it will toggle the SPI clock pin (which you wont connect to anything) and at each toggle it will read the state of MISO pin and return the values it reads as bytes. By setting the SPI data rate to be above the nyquist rate of the display data signal you will be sure to receive every high pulse as a series of 1's in the returned bytes.
You'll need to read enough bytes over SPI to ensure you get the header and all 32 data bits. The read in bytes can then be parsed to find the header and the data bits. An example implementation can be found in the Sonar RE github project (Implemented on a Raspberry Pi).
Differences between backup sensor kits
Two different data formats were found across a variety of kits during testing and one has significantly more useful data than the other. The kits with control boxes that have different data formats are packaged in the same exact physical cases, so another way to determine which kit is which will be necessary (likely the display that comes with the board will be the way to check). TODO(link to a good kit or a way to easily differentiate)
One control box outputs 2 bits of depth information for each sensor and then 8 bits of resolution for whichever one of the sensors is closer. This is not great as 2 bits of depth data works out to only ~0.3 meter resolution, which isn't really enough...
The other control box outputs 8 bits of depth data for each sensor, as is described in detail above.
Number of sensors
There are 8 and 4 sensor kits, and it appears the 8 sensor version is just doubled up circuitry of the 4 sensor version, which is then connected to a mux and switched via a 12v input to the board. This is because it is meant to have 4 sensors on the back of the car and 4 on the front. 12v switching is a little harder than 5v and the 8 sensor kits seem to use the data format with very poor distance resolution so they are not recommended.