Fifty Shades of Gray Code
hackaday.com
hackaday.com
A normal binary code would have a race between multiple signals toggling and when they showed up on across the boundary. You can convert between normal binary and gray codes with a tree of XOR gates.
Many years ago I was working with ultrasonic distance sensors to measure water levels in cisterns. These things had a pretty good resolution: something around 2-3mm (cisterns were typically 6' to 12' deep/high). Enough that the waves/splashing during filling could cause the level to fluctuate and so we'd build the software so alarms had a separate 'on' and 'off' level. If you were to just say '<1500L = alarm', it would rapidly trigger on and off, so instead it would turn on at <=1500L and off at >1800L to both account for splashing and reduce repeat/nuisance alarms due to regular fluctuation in use.
I regularly use this as my go-to example whenever I'm talking with someone about why you can't directly map the physical world to binary state.
Just like the classic genies, "be careful what you wish for"! This is also called hysteresis filtering for anyone wondering.
You will see it in web page menus, or rather the easier to use web page menus, where when your mouse leaves briefly the menu does not instantly disappear.
This was built before Arduino's and Raspberry Pi's were around (and the environment is humid), so I devised a fairly simple mechanical solution of just enclosing the float switch inside a pipe that had a small hole in the bottom. The water level inside the pipe would change slower than the real level, providing the needed hysteresis.
Btw. using keyboard controllers to poll many switches isn't actually that unusual, but definitely a nice hack.
All even numbers should be possible though. For example, here is 6 positions: 000, 001, 011, 111, 110, 100 - and this strategy can generalize to any even number.
Example with 6:
000
100
110
111
101
001
Proof: Adjacent gray codes have hamming distance 1, so the graph of gray codes is cycle on a hypercube. All cycles on a hypercube graph are even, so every sequence of gray codes is even.Or rather, I was about to post about hypercubes and cycles myself :D
0110
0010
1010
1011
1111
1101
0101
0111
0011
0001
0000
0100You can create a Gray code for exactly the numbers 0 to n-1, for any n, by the following steps: 1. Create the binary reflected Gray code for the next higher power of 2. 2. Take just the first n numbers of that binary reflected Gray code. 3. Bitwise exclusive-or each of these n numbers in the Gray code with the binary representation of floor(n/2) (i.e., n shifted right by one bit).
To create a cyclic Gray code for exactly the numbers 0 to n-1, n must be even. (It's easy to prove that you cannot get a cyclic Gray code for odd n.) 1. Generate the Gray code for 0 to n/2-1, as above. 2. Concatenate the reflection of that Gray code to itself. 3. Shift each of the n numbers you now have left by one bit. The first half gives you all the even numbers 0 to n-2, with the Gray-code property. 4. Put a 1 in the least significant bit in the second half The second half gives you all the odd numbers 1 to n-1, again with the Gray-code property.
The whole sequence gives you 0 to n-1, with the Gray-code property, and it's cyclic.
If you'd like a PDF of the paper, email me: thc@cs.dartmouth.edu.
Tom Cormen Professor of Computer Science Dartmouth College
0000
0001
0011 <
0010 <
0110 <
0111 <
0101 <
0100 <
1100 <
1101 <
1111 <
1110 <
1010 <
1011 <
1001
1000One question: when you need to know exact angle of something, say a steering wheel, if you used a grey code you'd need a really fine grained code with a huge set of numbers if you used this approach. Is that how it's done? Or is there a different way?
1: https://upload.wikimedia.org/wikipedia/commons/a/a8/Gray_cod...
2: https://en.wikipedia.org/wiki/Gray_code#Position_encoders
[1] http://www.allegromicro.com/en/Products/Magnetic-Linear-And-...
A Gray code, as the article states, is only referenced by the Hamming distance between codes, not the bit size of the encoding. If you repeat the two-bit code: 00,01,11,10 90 times, you'll get a one-degree resolution around a circle, which is plenty for a steering wheel and usually works just as well as a 9-bit encoding (512 states).
The problem becomes "how do I know where the wheel is at any arbitrary time?"
The answer is: you continuously monitor the wheel by counting up or down on each code transition, and have a Home sensor to set the initial position. But now you have to remember the position when you power it off, and perhaps make sure no one can move the wheel while you're not monitoring it. Is that sufficient for your application? (hint: it is for 90% of such applications) If so, problem solved. If not, then we need to get more complex.
More complex can mean: Non-Volatile Memory so we can power off and remember the last position[1], continuous battery-backup so even if main power is off, we track the wheel position, or ta-da: a 9-bit encoding so even with power off, we can encode 512 discrete states. Historically, that last solution was by far the most expensive.
1: I've worked with such a system where the position of a critical gantry was updated while it was running, then when power was off, the last (X,Y) position of the gantry encoders was remembered. Battery-powered electronics then monitored the state of an access door. If the door was opened, then the X,Y position was invalidated (someone could have moved the gantry while the encoders weren't being read) and the software would not allow the system to restart until a manual alignment procedure was done to reset the gantry to a known position and clear the "lockdown" bit. The alternative would have required two 10-bit absolute encoders that cost more than the electronics to do what I described.
Some of the industrial equipment I've designed at work uses Omron servos with encoders that use their own motion to provide power to the position tracking electronics, so you can disconnect the cable or otherwise lose power and not lose your zero, even if the machine is moved in the interim. No batteries required. Very cool product!
With a tad bit of math involving the gear box attached to the servo you know that one tick is real world distance X. From there it is a matter of establishing a "home" position, and counting your ticks as you move.