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!

Friday 12 July 2013

Hardware vs Software for product development

I've been pondering whether developing products in software is better than in hardware. It's remarkable what is possible  nowadays with software running on high performance hardware .

Here are my observations.

Hardware tends to drive unit cost.  Components cost money, therefore to reduce the design cost it makes sense to move towards a more software heavy design.

However by increasing the software component, the demands on processors may increase so although the component count will drop the cost of the processor will probably increase.  For modest control applications this is probably negligible however at the extremities of design this may become significant.  For example doing real time 10Gbit/s wire speed processing in software is non trivial.  This tends to push you in the direction of more expensive processors, custom hardware or expensive extremely skilled developers.

The underlying assumption for unit cost is that you will make a lot of the product.  If however you're in a niche and sell very few, the cost of the developer per device need to be factored in. The trade off is the cost of  more expensive hardware versus the cost of the developer.  For example say the market size for your product is 100 units. The cost of a developer is say £50k/year.  Amortised over the units the developer cost is £500.  If the developer uses higher spec hardware at a cost of £100 more per device but can develop in half the time, the saving is actually £150 per product.  It would be cheaper to opt for a heavier hardware design than a heavier software design.

The choice of technology is important.  My first exposure to the Erlang Programming language as a manager taught me that. I had a system written in Java. It performed like a dog. The programmers told me I needed bigger hardware so I spent £2M putting very high end servers in.  The developers lost all credibility with me when the performance barely improved with this expensive hardware. A skunk-work development team knocked together something in Erlang that was several  orders of magnitude better performance than the Java system and running on an old Sun box which was found lying around.

This is an interesting example.  The level of complexity of this system was that it was impossible to build purely in hardware. It absolutely needed software. However the architectural design decision about which software technology to use was actually a critical consideration.  The cost in this situation (with a product size of one unit) was £2M.

Some of the benefits of software over hardware are:
- Very quick to make changes
- Easy to experiment
- Often quick to implement

The downside is:
- Scope creep / developer creep - it becomes easy to add unreequested functionality
- The ease of change leads to a maintenance nightware as potential each customer has a unique product
- Finding bugs in software is often harder than finding bugs in hardware.

However the trend is to run more things in user space. For example the Raspberry Pi has an operating system and that means it's performance is not predictable.  Microcontrollers have much more predictable performance but not as predictable as hardware.

This then creates a new dimension. One of risk.  We all know software has bugs and can go wrong. We therefore need to factor in the cost and consequence of it going wrong.  Medical electronics, aircraft and maybe cars are examples where it may be extremely prudent to have high hardware component to minimise risk.

As you can see I haven't reached a conclusion yet but it is likely the shift towards a larger software component is inevitable.



Friday 5 July 2013

Hacking Cheap Chinese Parking Sensors

Following in the vein that I think we are about to see a revival in tech design/manufacturing in the UK, I am sharing my DIY experiences and getting my hands dirty for the first time in a long time.

About 4 years ago I thought it would be cool to modify Chinese parking sensors and integrate it into the car. Since then I've bought a car with a built in reversing camera so the desire subsided but I still fancied doing it. Recently I stumbled across an article to do exactly that except for a robot project and this let me to discover a few brave individuals that have hacked these cheap parking sensors and integrated it into their car system

Since it's possible to buy these parking sensor systems for £10, I've decided to have a go and have enjoyed playing with hardware again - the first time in over a decade.

The protcols between these systems vary and the one I bought didn't have the same protocol as those who have hacked them. So I bought another one only to find it had exactly the same protocol despite being a different design. I think that kind of reveals something about the design ecosystem which exists in China.

The other people who have hacked these units have all used an arduino so I figured I would too. I have to say I'm really impressed with what you can make the arduino do. It's a really powerful device.

In order to decode the protocol I ended up buying a protocol analyser. It was just £12. Equally remarkable. After lots of detective work I figured out the protocol. 

Mine was more odd than others out there. They all use a form of Pulse Width Modulation (PWM).  What was odd about mine is it's the 0V pulse width which is important rather the +5V which we are classically taught. The other odd thing about mine is the display forms part of the timing chain. The controller shuts down if the display is not attached. I therefore needed to emulate the display timing to make it work.

The parking sensor protocol is based on bursts every 20.7mS with a period of 22.658mS
The high level frame timings are:
1/ Display sets +5V for 20.68 ms
2/ Display sets 0V for 0.138 ms
3/ Display pulls +5V for 1.57ms then goes high impedance
4/ Controller sends data during the 1.57ms duration
5/ Display pulls 0V for 0.27mS
6/ Cycle repeats

Data is sent by the controller during the 1.57ms period. Data pulses are sent by controller in inverted PWM format ie zero volts if where the logic 1 and 0 are and a logic 1 or 0 depends upon how long the period of silence lasts. (Took a while to figure that out).

A logic 0 is a 0V pulse of 34uS and a logic 1 isa 0V of 54uS . The burst starts with a 0V pulse of 78us. Pulses of +5V vary in duration

Personally I prefer interrupt driven code so that's what I've opted for. One of the hacked versions I looked at was polled.  Given the pulse widths are 34us and the arduino takes about 6us to do anything I opted to interrupt driven. It also means the board can do other things when events aren't happening for example it could be updating the screen with data.

I'm using timer1 which is 16 bits to orchestrate the display emulation and turning on and off the interrupts. The data burst is interrupt driven on the edges.

Here's my arduino code:

// Copyright Steve Roberts 2013
// Arduino based car parking sensor protocol decode
// There are plenty of cheap 4 sensor Chinese parking sensors available
// This decodes the protocol between the controller and the display
// The display is a 7 segment LED with left right distance indicators
// The protocols used vary by vendor and are proprietary
// The protocol here is one based on bursts every 20.7mS with a period of 22.658mS
// The controller and display are inter-linked and it will not work without the display
// attached
// The display sends the high level frame information to the controller.
// We therefore need to emulate the display timing frame.
// The controller plugs into an arduino digital pin
// The high level frame timings are:
// Display sets +5V for 20.68 ms
// Display sets 0V for 0.138 ms
// Display pulls +5V for 1.57ms then goes high impedance
// Controller sends data during the 1.57ms duration
// Display pulls 0V for 0.27mS
// Cycle repeats
// Data pulses are sent by controller in inverted PWM format
// A logic 0 is a 0V pulse of 34uS and a logic 1 isa 0V of 54uS
// The burst starts with a 0V pulse of 78uS
//  Pulses of +5V vary in duration
// Use arduino timers which are interrupt driven for the high level timing structure
// Use  timer1 since this is a 16 bit timer. Timers0 and timer2 are only 8 bits long so insufficient
// Use digital pins 2 and 3 which are mapped to interrupts for the digital signal detection
// The data in the burst period relates to one sensor. It is 16 bits long. It consists on an address
// and a 8bit value for distance
// Since the arduino is only working 1.6ms every 22mS we can stagger the timer to support 2 sets
// of parking sensor for front and rear parking sensors on a car (work in progress)

//storage variables
boolean toggle1 = 0;
unsigned long lastChange = 0L;
unsigned long  rearData =0;
int rearDataReady =0;

#define  rearParkingSensorPin 3 
// Pin 3 Interrupt 1
#define rearInterrupt 1
// Interrupt for pin 3

void setup(){
 
  //set pins as outputs

  pinMode(rearParkingSensorPin, OUTPUT);
  Serial.begin(115200);
  pinMode(13, OUTPUT);
 
cli();//stop interrupts

//set timer1 interrupt at duration of 20.6ms
  TCCR1A = 0;// set entire TCCR1A register to 0
  TCCR1B = 0;// same for TCCR1B
  TCNT1  = 0;//initialize counter value to 0
  // set compare match register for 20.6ms duration
  OCR1A = 41190;// = (16*10^6) / (1*1024) - 1 (must be <65536)
  // turn on CTC mode
  TCCR1B |= (1 << WGM12);
 // Set CS21 bit for 8 prescaler
  TCCR1B |= (1 << CS21);  
    // enable timer compare interrupt
  TIMSK1 |= (1 << OCIE1A);


sei();//allow interrupts

}//end setup


ISR(TIMER1_COMPA_vect){
// Timing comes from the display unit to control box
// Single wire working
// We need to emulate the timing sequence
// User interrupt driven timers for this

  switch (toggle1){
    case 0:
          digitalWrite(rearParkingSensorPin,HIGH);
          OCR1A = 41190;// 20.6 ms HIGH
          toggle1 = 1;
          break;
     case 1:
         digitalWrite(rearParkingSensorPin,LOW);
         OCR1A = 275;//138 us LOW
         toggle1 = 2;
         break;
     case 2:
         // Data burst period from controller
         rearData = 1; //Set the first bit
         rearDataReady = 0;
         digitalWrite(rearParkingSensorPin,HIGH);
    
 // We have a total of 140us before we need to start doing edge handling of pulses
         pinMode(rearParkingSensorPin, INPUT);

         // we will get an interrupt on both falling and rising edges:
         // Clear any pending interrupts we may have
        EIFR = 0xff;
        attachInterrupt(1, interrup_isr_onchange, CHANGE);
         OCR1A = 3148;//1.574 ms HIGH
         toggle1 = 3;
         break;
      case 3:
          EIFR = 0xff;
          detachInterrupt(1);
  
          digitalWrite(rearParkingSensorPin,LOW);
          pinMode(rearParkingSensorPin, OUTPUT);
          OCR1A = 548;//0.274ms LOW
          toggle1 = 0;
          break;
  }
}


void interrup_isr_onchange(void)
{

  // ISR latency from edge change 3-6 us
  // We are interested in how long the 0V state was
  // 34uS = 0
  // 56uS = 1
  // 78uS is the first pulse
  unsigned long timeNow;
  unsigned long pulseInterval;
  unsigned int bit;
  timeNow = micros();
  pulseInterval = timeNow - lastChange;
  lastChange = timeNow;
 // Serial.println(pulseInterval);
 
  if (digitalRead(rearParkingSensorPin)  == HIGH && rearData < 131072) {
    // We've had a low pulse
    if (pulseInterval < 45) {
       rearData = rearData << 1;
       rearDataReady++;
    }
    if (pulseInterval > 45 && pulseInterval < 68 ) {
        rearData = rearData ^1;
       rearData = rearData << 1;
      rearDataReady++;
    }
    // Ignore pulses longer than 68uS
  
  }else { // digitalWrite(13,!digitalRead(13));
                rearDataReady = 17;
            }
  // Rising edge only of interest as low pulse

}

void loop(){
 unsigned int address;
 unsigned  int distance;
 // Check we have enough bits of data
 if (rearDataReady >  15 && rearData > 0b1111111111111111) {
   rearData = rearData >> 1; // We're getting an extra 0 - can't figure out why so strip off
// Check bits 9,10,11,12 are all 1's
     address = rearData & 0b0111000000000000 ;
// Get rid of the least significant 12 bits
     address = address >> 12;
// Extract the distance information
     distance = rearData & 0b0000000011111111;
// Discard any dodgy data
// Valid sensor address aree 0,1,2,3,4
// Maximum distance value is 99 (9.9m). Reported in decimeters
     if (address < 5 && distance < 100) {
     Serial.print (address);
     Serial.print (",");
    Serial.println(distance);
     }

  digitalWrite(13,!digitalRead(13));  // Just show we are alive.
  }
}

Currently this just outputs to the Serial port but the plan is to use a MAXIM 7456 to do composite video overlay. I can then overlay the data from the parking sensors which I will install, onto my cars reversing camera. I've looked at my car and it's easy to hook into the camera. Currently the camera selection is basically a tap from the reversing lights (thankfully no CAN bus there) so I can use that and also take control of the screen display selection too. I'm also thinking about installing camera on the front of the car and intelligently switching between front and rear.  This will involve some custom hardware. The arduino allows extension boards.  These are called shields. I plan to create a design and get it made.






Wednesday 3 July 2013

Is the rebirth now?

Since my post the  media now seems to be echo'ing my prediction that manufacturing will return to the UK. Here's a article in the telegraph  and there have been various comments on the BBC.

It's encouraging news however my fear is that there may be a skills gap. Although the UK still runs many high quality electronics courses, the students on them are predominantly foreign. We have over the past 20 years been busily educating China and other countries in how to design electronics, but not our own population.

If I look at the many skilled electronic designers I know, many are no longer in electronic design in fact many are know teachers.  There is also a demographic challenge too. I am now in my 40's and I was one of the last generation of classically trained electronic engineers but many of the skilled designers I worked alongside are now in their late 50's so if electronics does return then we need to have young engineers coming through now to have the knowledge imparted from the veterans.

Or am I worrying too much?  The last few weeks I've been back on the tools and playing with hardware. I've decided to modify the parking sensor system on my car. It currently has a reversing camera but no ultrasonic sensors so I fancied adding these to the on-screen system which is built into the car. I purchased a cheap Chinese made parking sensor system and promptly set about hacking it to get the data out of it. At first I struggled to reverse engineer the protocol used but I bought a logic analyser for £20 and quickly figured out how it works. I'm now well on the way to reading the data from it into a microcontroller (Arduino) which will overlay the information on the car's built in display.

So if I look at this hobby project, there is actually remarkably little hardware design needed on my part. Because of the design of the parking system I need some buffer chips but very little else. My 15 year old son could probably design the circuit with a little guidance. 

So returning to education, the skills needed for digital electronics are more programming and a basic understanding of high level circuits rather than circuit design. Analog still needs a high level of competence. The real skill is one of innovation and seeing the potential to exploit currently available building blocks.  The Arduino is a classic example. This cheap chip is remarkably powerful and flexible.  The trick is knowing how to exploit it's capabilities.

So are we ready for the rebirth?

Thursday 20 June 2013

Rebirth of Hardware?

I started my career in technology in 1985. Back then the UK still made stuff and Japan was seen as the emerging technology supremo.  I studied hardware and system engineering which was basically 40% hardware design 50% system and control theory and 10% software. It was far from clear back then the role software would go on to play so if I was to have my time again I would opt for a more computer science based course however there is still something special about hardware.

Since then we've seen Japan come and go and China emerge as the world's place to manufacture stuff.  Apart from analog electronics, digital hardware has become more and more standard off the shelf chips and software to drive it.  If I think back to 1996 when I was working for Nortel (I had seen the light and was more management than hands-on technologist), we were investing in hardware chips to build an ATM data switch and the state of the art hardware was a 40Gbit/s switching fabric. Less than 10 years prior  this would have seen impossible to achieve in hardware without creating lots of latency through ultra wide data buses.

Today it's perfectly possible to achieve 40Gbit/s on a modest processor - today's processors have the challenge that the input/output (I/O) struggles to  keep up.

Making stuff in China makes sense - it's cheap however there are several trends that make me wonder whether we are about to see a rebirth of hardware and in particular the emergence of this in the UK.

Why do I think this?

- China is great if you want large quantities of stuff but not if you want small volumes of specialised stuff
- China is increasingly becoming more expensive with wage increases. The price delta between making small quantities of stuff in the UK vs making it in China is falling.  A recent TV programme showed there was only about 50p difference between making something like a cushion in China vs making it in the UK!

The other thing I've observed is that the barriers to entry to making hardware have fallen.  Take logic analysers.  In my early days of engineering, to purchase a digital logic analyser it would be £50-100k or maybe rent one for £10k per month.  You can buy a USB based 8 probe logic analyser now for as little as £12 !

The other thing I've observed is the emergence of useful units of computing like the Raspberry Pi and Arduino.  It's possible to build computer controlled hardware at low cost. These boards are designed with expansion in mind so the budding UK hardware company in the UK can design and make (via someone else) a small  board for these devices and develop the software to make it work.  OK software is important in these applications but nether-the-less there may be a small custom hardware component.

As an interesting data point, the country of manufacture of the very low cost Raspberry Pi is Wales! Originally it was made in China but production is shifting to the UK!

The few hardware manufacturers that have survived in the UK are very competitive. There are companies where you can upload your circuit board design from the Internet and you get it back a few days later - not
much different to getting some pictures printed. Shipping from China is slow so the UK has a competitive advantage in lead times in the European market.

Following the banking crisis, I think the mood in the UK has changed and bubbling under the surface is a desire to rebuild manufacturing.  If you make a product you need a case and plastic tooling costs have traditionally meant that the product needed to be high volume. Here there is another interesting technology shift to support my low volume hardware argument.  3D printing is becoming incredibly cheap meaning that printing plastic cases in single quantities is cost effective.  OK not particularly fast but faster than getting them made in China and shipped over.

Historically the UK has had a reputation for technology innovation.  As a nation we may not have fully capitalised on our inventions but we have certainly demonstrated we have the creativity.

I therefore believe with all these trends converging we will see the emergence of low volume specialist hardware companies based in the UK.