John Payson has asked me to forward this message of his to the list. ------- Forwarded Message Follows ------- From: John Payson Subject: Re: Code For Bourns ACE-128 Encoders To: fastfwd@ix.netcom.com Date: Sat, 21 Dec 1996 16:55:11 -0600 (CST) > > [The Bourns encoder is] probably using Gray code to encode the > > shaft angle of the encoder. > > The Bourns encoder does NOT use Gray codes. If you'd bothered to > look at the specs, you'd have seen that they use what appears to be > a completely ad-hoc encoding scheme, instead. Actually, if you look more closely it's not completely ad-hoc, but rather has the interesting property and bit[i] of position [j] matches bit[(i+1) % 8] of position [(j+16) % 128)]. I would guess that they just have one code wheel and eight sensors spaced uniformly around it. Rather clever, really. Anyway, here's my attempt so far at a good decoding method. It's in C rather than PIC-ASM because C is much easier to test. Note that the translation table near the beginning is there merely for purposes of verifying that the "magic" procedure works. Sorry the code isn't commented, but the challenge for y'all is to figure out how it works. My guess is it should translate into a little less than 80 bytes of PIC code (there are two jump tables, one of size 16, one of size 48, plus a little bit of other munging code) and should take about 20-29 cycles to execute for any input. If I were willing to have it return bogus numbers for bogus inputs (rather than flagging them) I could probably shave a dozen or so bytes and a few cycles. #include #include unsigned char foo[256] ={ 255, 56, 40, 55, 24, 255, 39, 52, 8, 57, 255, 255, 23, 255, 36, 13, 120, 255, 41, 54, 255, 255, 255, 53, 7, 255, 255, 255, 20, 19, 125, 18, 104, 105, 255, 255, 25, 106, 38, 255, 255, 58, 255, 255, 255, 255, 37, 14, 119, 118, 255, 255, 255, 107, 255, 255, 4, 255, 3, 255, 109, 108, 2, 1, 88, 255, 89, 255, 255, 255, 255, 51, 9, 10, 90, 255, 22, 11, 255, 12, 255, 255, 42, 43, 255, 255, 255, 255, 255, 255, 255, 255, 21, 255, 126, 127, 103, 255, 102, 255, 255, 255, 255, 255, 255, 255, 91, 255, 255, 255, 255, 255, 116, 117, 255, 255, 115, 255, 255, 255, 93, 94, 92, 255, 114, 95, 113, 0, 72, 71, 255, 68, 73, 255, 255, 29, 255, 70, 255, 69, 255, 255, 35, 34, 121, 255, 122, 255, 74, 255, 255, 30, 6, 255, 123, 255, 255, 255, 124, 17, 255, 255, 255, 67, 26, 255, 27, 28, 255, 59, 255, 255, 255, 255, 255, 15, 255, 255, 255, 255, 255, 255, 255, 255, 5, 255, 255, 255, 110, 255, 111, 16, 87, 84, 255, 45, 86, 85, 255, 50, 255, 255, 255, 46, 255, 255, 255, 33, 255, 83, 255, 44, 75, 255, 255, 31, 255, 255, 255, 255, 255, 255, 255, 32, 100, 61, 101, 66, 255, 62, 255, 49, 99, 60, 255, 47, 255, 255, 255, 48, 77, 82, 78, 65, 76, 63, 255, 64, 98, 81, 79, 80, 97, 96, 112, 255 }; typedef unsigned char ub; ub magic_arr[40] = { 0x48,0xFF,0xFF,0xFF,0x56,0xFF,0xFF,0x40, 0x79,0x47,0xFF,0x43,0x4B,0x55,0xFF,0x31, 0xFF,0xFF,0xFF,0xFF,0xFF,0x3F,0xFF,0x1F, 0xFF,0xFF,0x7A,0x44,0x4C,0x3E,0xFF,0x32, 0x4D,0x3D,0xFF,0x2D,0xFF,0xFF,0xFF,0x1D}; #define ror(x) (x)=(x>>1)|((x & 1)<<7) #define rol(x) (x)=(x<<1)|((x & 128)>>7) #define swap4(x) (x)=(x<<4)|((x & 240)>>4) ub magic(ub x) { ub t,ct; ct=0; t=(x ^ (x>>4)) & 15; switch(t) { case 1: /* 0001 -> 1000 */ case 3: /* 0011 -> 1001 */ case 7: /* 0111 -> 1011 */ ct++; rol(x); case 2: /* 0010 -> 1000 */ case 6: /* 0110 -> 1001 */ case 14: /* 1110 -> 1011 */ ct++; rol(x); case 4: /* 0100 -> 1000 */ case 5: /* 0101 -> 1010 */ case 12: /* 1100 -> 1001 */ case 13: /* 1101 -> 1011 */ ct++; rol(x); break; case 8: /* 1000 -> 1000 */ case 9: /* 1001 -> 1001 */ case 10: /* 1010 -> 1010 */ case 11: /* 1011 -> 1011 */ case 15: /* 1111 -> 1111 */ break; case 0: return 255; } if (!(x & 128)) { swap4(x); ct|=4; } ct<<=4; t=((x ^ (x<<4))/2) & 0x38; if (t & 0x20) t=0x20; t=t+(x & 7); t=magic_arr[t]; if (t > 128) return 255; t=(t+ct) & 0x7F; return t; } void main(void) { int i,v; printf("\r\n\n\n"); for (i=0; i<256; i++) { v=magic(i); if (v==foo[i]) printf("%02X-- ",v); else printf("%02X%02X ",v,foo[i]); } }