|
|
View previous topic :: View next topic |
Author |
Message |
dima2882
Joined: 13 Jul 2005 Posts: 25 Location: Maryland
|
Aviation Gray Code |
Posted: Wed May 17, 2006 12:48 pm |
|
|
Hi all,
I'm trying to create a system that interfaces to a digitizing altimeter and displays altitude information. As is the norm, my altimeter uses Gray code (aka Gilham code) as the output. However, I wasn't able to pin down a good webpage that shows the difference between Gilham code and the many other Gray codes out there... does anyone have an algorithm, or some code that will convert Gilham code to normal binary?
Thanks for all your help. |
|
|
Aviator
Joined: 17 May 2006 Posts: 1 Location: Finland
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
AvionicsCoder Guest
|
Aviation Gray Code Algorithm |
Posted: Sat Mar 10, 2007 2:37 pm |
|
|
Did you ever find an algorithm to make this conversion? |
|
|
dima2882
Joined: 13 Jul 2005 Posts: 25 Location: Maryland
|
|
|
AvionicsCoder Guest
|
|
Posted: Mon Mar 12, 2007 9:18 am |
|
|
I may not be seeing this right so correct me if I'm wrong. The algorithm shown in the link converts between binary and binary-reflected Gray codes. The Gillham codes do not seem to be binary-reflected Gray codes. I may just be looking at the Gillham codes wrong so I appreciate any insight you might be able to give me on this one. |
|
|
Humberto
Joined: 08 Sep 2003 Posts: 1215 Location: Buenos Aires, La Reina del Plata
|
|
Posted: Mon Mar 12, 2007 12:16 pm |
|
|
Quote: |
I may just be looking at the Gillham codes wrong so I appreciate any insight you might be able to give me on this one.
|
Gillham Code is a Gray Code. It is a 10 bit representation of the barometric
altitude between -1000 and 35000 feet in steps of 100 feet, represented
in a chart and already is a standard used in aviation altimeters output
since many years.
Quote: |
does anyone have an algorithm, or some code that will convert Gilham code to normal binary?
|
Do not need it at all, implementing in any 18F device and using table read
would do the trick.
Humberto |
|
|
poor SSR guy Guest
|
why Gillham doesn't algorithmize |
Posted: Tue Jul 10, 2007 1:47 pm |
|
|
Gillham code is modified Gray code. No you won't find an easy mathematical conversion from base 2 or base 8 to decimal number of feet of altitude. Because its modified. Its modified because of historical analog switch reliability. If you increment from 7 to 8 your bits change from 0111 to 1000 causing four switches to change state. In Gillham code your bits change in a pseudo-shift left pattern where only one bit changes for each increment. See Gray code in Wikipedia.com. This prevents where and tear on the barometric pressure indicator when the altitude is toggling rapidly between two levels.
Thus endeth that mystery. I hope.We're kind of perpetually stuck with that look-up table in avionics. |
|
|
RLScott
Joined: 10 Jul 2007 Posts: 465
|
Re: why Gillham doesn't algorithmize |
Posted: Wed Jul 11, 2007 11:31 am |
|
|
poor SSR guy wrote: | ...In Gillham code your bits change in a pseudo-shift left pattern where only one bit changes for each increment... |
This is a characteristic of every Gray code, not just the Gillham variant. And the reason for it has less to do with wearing out switches than with preventing errors. If more than one bit changes at a time then it is possible to read the switches when only some of them have changed. This can lead to a large error in the decoded value. So I still don't understand why the Gillham code is better than a straight-forward reflected binary Gray code (i.e. a code defined recursively for n+1 bits by taking the n-bit code and repeating it in the opposite order with the extra bit set in the repetition.
Robert Scott
Real-Time Specialties
Embedded Systems Consulting |
|
|
Ttelmah Guest
|
|
Posted: Wed Jul 11, 2007 3:04 pm |
|
|
If I remember correctly, the Gillham code used in altimeters, is simply the standard reflected binary Gray code, with the zero value removed, and an offset of 12 counts applied to allow for negative values.
As such this can be converted using the standard shift and xor Gray to binary algorithm, and the required offset applied after conversion.
So, something like:
Code: |
signed int32 GtoAlt(int16 val) {
int32 result;
val^=(val>>8);
val^=(val>>4);
val^=(val>>2);
val^=(val>>1);
result=val-12;
result*=100;
return(result);
}
|
No guarantees, I am doing this from memory, and have probably got the algorithm and offsets wrong....
Best Wishes |
|
|
djd3of5 Guest
|
Aviation Gillham Code (Mode C Altitude) |
Posted: Tue Dec 11, 2007 4:49 pm |
|
|
The previous post by Ttelmah was a conversion for gray code to binary, not Gillham code to binary (altitude). I have verified the following algorithm (in MS Excel and VB).
Code: | signed int32 GillhamToAltitude( int16 i16GillhamValue ) {
int32 i32Result;
int16 i16TmpRslt;
// Convert Gillham value using gray code to binary conversion algorithm.
i16TmpRslt = i16GillhamValue ^ (i16GillhamValue >> 8);
i16TmpRslt ^= (i16TmpRslt >> 4);
i16TmpRslt ^= (i16TmpRslt >> 2);
i16TmpRslt ^= (i16TmpRslt >> 1);
// Convert gray code converted binary to altitude offset.
i16TmpRslt -= ( ((i16TmpRslt >> 8) * 6) + (((i16TmpRslt % 16) / 5) * 2) );
// Convert altitude offset to altitude.
i32Result = (i16TmpRslt – 13) * 100;
return i32Result;
} |
Hope this helps.
djd3of5 |
|
|
Ttelmah Guest
|
|
Posted: Tue Dec 11, 2007 5:12 pm |
|
|
If you read what I say, I do point out that you will need to apply the offset after this conversion.
Glad to see someone finishing the job off.
Best Wishes |
|
|
kstewart
Joined: 03 Dec 2010 Posts: 2 Location: UK
|
Gillham Code Explained |
Posted: Fri Dec 03, 2010 12:55 pm |
|
|
After searching endlessly on the web for info on decoding the Gillham code from an altitude encoder I found this thread which seemed to provide the answer. Unfortunately I struggled to understand the function above and couldn't make it work so I set off to try and understand how the Gillham code worked and write my own function to decode it.
I thought that I would publish my findings in case they are of assistance to others struggling like me.
During my investigation this is what I have discovered:
1. The order of the bits from MSB to LSB is D1 D2 D4 A1 A2 A4 B1 B2 B4 C1 C2 C4.
2. When the code was designed I suspect that the method for encoding dealt with multiples of 500ft separately from multiples of 100ft. This may be why the bits from D1-B4 store the number of 500ft increments and C1-C4 store the number of 100ft increments +1 from the lowest altitude datum (-1200ft).
3. The 500ft values are coded in standard Gray code.
4. The C1-4 bits are coded using a non-linear Gray code. That is to say if you convert these bits from Gray code to binary you find that the values follow a pattern: 1, 2, 3, 4, 7, 7, 4, 3, 2, 1, 1, 2, 3, 4, 7 which repeats ramping up and down.
5. If you change any 7 into a 5 and reverse the order of the values if the 500ft count is even then the 100ft count goes 1, 2, 3, 4, 5, 1, 2, 3, 4, 5 ....
6. Multiplying the number of 500ft increments by 500 and adding the number of 100ft increments multiplied by 100 and subtracting the 1300ft offset gives you the altitude. Subtracting 1300 instead of 1200 deals with the fact that the hundreds are 1 too high.
Here is my function below. I have added a simple check for invalid codes in the C bits and returned a rogue value to allow error trapping. Feel free to use it, modify it and post any improvements or errors that you find. I would be most interested if anyone could explain the function proposed by djd3of5.
Code: |
signed int32 GillhamToAltitude( int16 GillhamValue )
// Data must be in following order (MSB to LSB)
// D1 D2 D4 A1 A2 A4 B1 B2 B4 C1 C2 C4
{
signed int32 Result;
int16 FiveHundreds;
int16 OneHundreds;
// Convert Gillham value using gray code to binary conversion algorithm.
// Get rid of Hundreds (lower 3 bits).
FiveHundreds = GillhamValue >> 3;
// Strip off Five Hundreds leaving lower 3 bits.
OneHundreds = GillhamValue & 0x07;
FiveHundreds = GrayToBinary(FiveHundreds);
OneHundreds = GrayToBinary(OneHundreds);
// Check for invalid codes.
if (OneHundreds == 5 || OneHundreds == 6 || OneHundreds == 0)
{
Result = -9;
return Result;
}
// Remove 7s from OneHundreds.
if (OneHundreds == 7) OneHundreds = 5;
// Correct order of OneHundreds.
if (FiveHundreds % 2) OneHundreds = 6 - OneHundreds;
// Convert to feet and apply altitude datum offset.
Result = (signed int32)((FiveHundreds * 500) + (OneHundreds *100)) - 1300;
return Result;
}
unsigned int GrayToBinary(unsigned int num)
{
unsigned int temp;
temp = num ^ (num>>8);
temp ^= (temp>>4);
temp ^= (temp>>2);
temp ^= (temp>>1);
return temp;
} |
|
|
|
kstewart
Joined: 03 Dec 2010 Posts: 2 Location: UK
|
|
|
nunojpg
Joined: 11 Aug 2014 Posts: 1
|
|
Posted: Mon Aug 11, 2014 9:38 pm |
|
|
djd3of5 code didn't work for me, but changing
i16TmpRslt -= ( ((i16TmpRslt >> 8) * 6) + (((i16TmpRslt % 16) / 5) * 2) );
to
i16TmpRslt -= ( ((i16TmpRslt >> 4) * 6) + (((i16TmpRslt % 16) / 5) * 2) );
Makes it work.
A complete C++ test program is:
Code: |
//Format MSB to LSB: D2 D4 A1 A2 A4 B1 B2 B4 C1 C2 C4
//Acording to ICAO documents D1 is not used.
int GillhamToAltitude(int value) {
value ^= (value >> 8);
value ^= (value >> 4);
value ^= (value >> 2);
value ^= (value >> 1);
value -= (((value >> 4) * 6) + ((((value) % 16) / 5) * 2));
return (value - 13)*100;
}
int test_values[][2]{
{0b00000000010, -1000},
{0b00000000110, -900},
{0b00000000100, -800},
{0b00000001100, -700},
{0b00000001110, -600},
{0b00000001010, -500},
{0b00000001011, -400},
{0b00000001001, -300},
{0b00000011001, -200},
{0b00000011011, -100},
{0b00000011010, 0},
{0b00000011110, 100},
{0b00000011100, 200},
{0b00000010100, 300},
{0b00000010110, 400},
{0b00000010010, 500},
{0b00000010011, 600},
{0b00000010001, 700},
{0b00000110001, 800},
{0b00000110011, 900},
{0b00000110010, 1000},
{0b00000110110, 1100},
{0b00000110100, 1200},
{0b01110000100, 46300},
{0b11011110100, 73200},
{0b10000000011, 126600},
{0b10000000001, 126700}
};
int main(int argc, char *argv[]) {
for (auto e : test_values) {
printf("Gillham: %6d Altitude: %6d Test:", e[0], e[1]);
if (GillhamToAltitude(e[0]) == e[1])
printf("OK \n");
else
printf("FAIL \n");
}
return 0;
}
|
Any corrections or optimizations are welcomed! |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|