Monday 15 July 2013

Hacking Chinese Parking Assist - digging to the next level.

Having managed to decode the protocol on some cheap Chinese parking sensors and loading the distance data into an Arduino I discovered a software bug in the Chinese device. My initial thoughts were that it was a bug in my code. The bug is that the unit reports 0m distance from about 40cm - 20cm and that it doesn't report a number of distances correctly.  I bought 2 units (different designs but same microcontroller + proprietary protocol) and they both had the same bug.

I confirmed it was the parking sensor by using the supplied digital display, attaching one sensor and checking the distance displayed.  Both controllers have the same bug so I therefore eliminated my code as the source of the problem.

The controller is based on  a Chinese chip. The Haier HR6P692SHL.

The datasheet is in Chinese so it took a little while to figure out what it was doing.

My plan is to write my own distance calculations and protocol (if needed). I've figured out the following:

Pin 14 (PB5)  is the 50kHz burst to drive the pulse to the ultrasonic senders
Pin 13  (PB6) is where the echo's are received. There is an op amp which means the echo pulses appear as +5V pulses.
Pins 1 (PB4) & 2 (PB3) are the timing information to select each sensor.
Pin 10 (PB0) is the serial data pin to the display and timing source.

I intend to use the existing protocol to tell me which sensor is active and tap into pin 13 and calculate the distance information myself.

Pins 1 and 2 count in binary to control an analogue multiplexer. The basic design is the micro-controller creates a 50kHz burst (20 cycles) and the analogue multiplex routes it to the correct sensor (transmit).  The ultrasonic burst  travels at the speed of sound (roughly 340m/s) and bounces off objects back to the sensor which has switched to a microphone and listens for the echo. Typical distances for parking are 1.6m. We don't really need much longer than that. So the distance travelled is 1.6m to the object and 1.6m back which is 3.2metres. The longest we need to listen for is 10ms.

One of the ultrasonic parking sensor control boards conveniently has a break-out pin for pin 13 (echo).

The next step is to run a protocol analyser on pin 13 and the serial data line. Since the echo pulse is digital (pulse position modulation) the algorithm is very straightforward.  On the rising edge of the pulse, measure how long it was since the pulse was transmitted and you can calculate the distance (not sure how the Chinese managed to screw it up but maybe all will become clear).

So for example if it takes 7.3mS from the transmitted pulse to the receive pulse

Speed of sound = 340m/s

Distance = (340 x 7.3x10-3)/2 = 1.24 metres

Hardly difficult maths.

I want to use as few pins on the Arduino as possible as I need them for other things so my current plan is to run pin 13 as an extra wire from the controller and use pin 13 and the existing serial wire protocol.  The serial wire protocol sensor address information is right but the distance is wrong.  The Arduino will therefore use the distance information from pin 13 and calculate the distance and use the address information from the serial wire protocol. Doing it this way will only use an extra pin per controller whereas using the binary count from the analogue multiplex selection with need 2 more pins (I still need to emulate the timing chain on the serial data wire unless I seriously start hacking the board) in which case I might start doing it in DSP!

I plan to look into more sophisticated echo analysis such as multiple echoes and measuring the return pulse duration to reject false echoes.  Rattle some keys near the sensor and you'll observe false echoes!

I will post another article as my adventure continues.

UPDATE.
Here's some traces from the logic analyser. This one shows the echo pulses


This trace shows the trace with no sensor attached.


The echo pulse distance does correctly change so thee problem with the incorrect distances is probably in the signal processing. The algorithm does  need to measure the pulse width.  The signal rises after the burst which suggests the receive amp gain is high - they should be tuned to 50kHz but the noise is trigging the signal level. Initially I thought the minimum measurable distance was 14cm but actually the signal floor removes with very close pulses. The algorithm is to therefore to measure the time from the rising pulse to the fall edge and compare to the start point. If the pulse is too long then discard.

It should be fine to use pin 13 + the serial data on the Arduino.

UPDATE
Well it seems digital signal processing on the Arduino is not straightforward. The problem is the distance for the echo is to the falling edge.  Unfortunately the signal is prone to glitches in the middle of the pulse so to find the distance you need to do it retrospectively. The glitches are about 4-8uS long which is just long enough for the interrupt to trigger.  Was that edge the right edge or do we need a later one? The Arduino has 2 interrupts which I wanted to use for the front and rear serial detection.  Although it's possible to reassign interrupts to other pins, it's not easy. My code would need to do it whilst it's running.  I had a look at doing the edge detection by polling and it's not fast enough. Basically the algorithm needs to respond to the falling edge, then check the pulse is still low for a reasonable period of time. If not then wait for it to fall again. Once we've done that we can calculate the distance from the start of the transmitted pulse.

If you look at the top trace you can see some examples of the short glitches after the main pulse has finished.

I came to the conclusion it was getting pretty hairy so I went back to  testing the standard sensors outside rather than indoors.  Performance was better but the bug is still there. I noticed that they've deliberately picked the buzzer sounding point to make it less obvious there's a problem with distance detection at short range - who will look at the screen to read the distance anyway!

2 comments:

  1. Just found this blog, very interested in your parking sensor work. a most interesting read.

    ReplyDelete
  2. I know this is ancient, but I'm now in the same boat. Your posts got me along to about the same point. 2016, and a brand new, based on an unmarked chip, design has the same issue. Turns out, I don't think its software. These things are too basic. I don't think the chip is much of a microcontroller. More just acting as a dumb translator.

    So here's what I see. mine is generating 45KHz square waves which get filtered, inverted, and run out the sensors. Note, its a constant 45KHz. The return is processed by the op amp chip and an RC filter and a diode bridge. That in turn drives a transistor with the idea being to generate square wave pulses for echos. In practice, it doesn't work well. The response of the filter creates a very sloppy mess from an otherwise decent signal! Their filtering to a sine wave doesn't seem bad, nor does their inverter, nor does the amplifier. Like most things from china, they went cheap on the expensive part :) So no DSP, and the cheapest sloppiest analog filter they could come up with. I mean I guess it "works", but mine can't seem to distinguish below about 20cm. For us Americans, that's roughly 8 inches. I can park my truck to within 8 inches without a parking sensor!

    By the way, a clean spot to grab the amplified return pulse is a capacitor sitting near the op amp. I'm assuming the design hasn't changed much on your sensors.

    So here's what I'm thinking. I basically want to disconnect the "microcontroller". Maybe even eventually desolder it. Driving the mux, the pulse generation, and having an analog input won't be too much work for an arm based arduino like the teensy. The 3.5/3.6 are coming soon and run pretty fast in a tiny package! Anyhow, that's just step one, get the arduino driving the sensors, and the mux. Forget about the echos...step two would probably be to implement something like a FIR filter for the return pulses. This could still be subject to noise however, and I believe these sensors have a frequency range the respond to, probably 40-50KHz, which would make sense since mine are generating 45KHz, right in the middle of that. So to help with noise rejection, we'd sweep the frequency of the pulses, (known as chirp). Lastly, if we wanted to get real fancy, we could get better close range detection with variable length pulses. Shortening the pulses gives us more opportunity to get really close items. I'm not sure that's really necessary though! I think I can get 1cm just looking at the scope output.

    These are all pretty basic techniques I had figured these sensors were all using. I'm more than a little disappointed to see they aren't. I'll probably throw a blog page up somewhere for it. If I do, I'kll try to remember to come back here and link it. For now, I'm going to use the teensy 3.2's I have and see where I get. I have a few 3.5/3.6's on the kickstarter, so I'll switch to them if I can't get the FIR performance in the 3.2s. Until I get something to show for my work though, I'll probably not put up a blog, its a lot of work...thanks for yours!

    ReplyDelete