// https://wokwi.com/projects/384136329791339521
// for https://forum.arduino.cc/t/setting-up-a-16-position-absolute-rotary-encoder/1200508/10?u=davex
const byte gray1 = 8;
const byte gray2 = 9;
const byte gray4 = 10;
const byte gray8 = 11;
bool bit0=0;
bool bit1=0;
bool bit2=0;
bool bit3=0;
int lastCode = -1;
int newCode;
// per https://en.wikipedia.org/wiki/Gray_code
int untangled [] = {0,1,3,2, 7,6,4,5, 15,14,12,13, 8,9,11,10};
// From https://en.wikipedia.org/wiki/Gray_code#Converting_to_and_from_Gray_code
typedef unsigned int uint;
// This function converts an unsigned binary number to reflected binary Gray code.
uint BinaryToGray(uint num)
{
return num ^ (num >> 1); // The operator >> is shift right. The operator ^ is exclusive or.
}
// This function converts a reflected binary Gray code number to a binary number.
uint GrayToBinary(uint num)
{
uint mask = num;
while (mask) { // Each Gray code bit is exclusive-ored with all more significant bits.
mask >>= 1;
num ^= mask;
}
return num;
}
void setup() {
// put your setup code here, to run once:
pinMode(gray1,INPUT_PULLUP);
pinMode(gray2,INPUT_PULLUP);
pinMode(gray4,INPUT_PULLUP);
pinMode(gray8,INPUT_PULLUP);
Serial.begin(9600);
}
void loop() {
// put your main code here, to run repeatedly:
bit0=digitalRead(gray1)==LOW;
bit1=digitalRead(gray2)==LOW;
bit2=digitalRead(gray4)==LOW;
bit3=digitalRead(gray8)==LOW;
newCode = bit3<<3 | bit2<<2 | bit1 <<1 | bit0;
if (newCode != lastCode) {
lastCode = newCode;
Serial.print("Gray:");
Serial.print(newCode);
Serial.print(" 0x");
Serial.print(newCode,HEX);
Serial.print(" 0b");
Serial.print(newCode,BIN);
Serial.print(" \tLookup:");
Serial.print(untangled[newCode]);
Serial.print(" \tGrayToBinary:");
Serial.print(GrayToBinary(newCode));
Serial.println();
}
delay(3); // comment to see effect of bouncy switches
}8
4
2
1