Hi all,
I'm currently working on a project that uses a rotary encoder. I got to googling, and found this great page from John Main:
His code at the bottom of the page ("Code for Improved Table Decode") works perfectly, but now I'm trying to understand what it is doing. I'll post the code with some annotated questions -- I think a lot of what is confusing me is syntax, or maybe his more advanced coding for brevity.
I looked up Gray codes, and understand that by only changing one byte, it removes the ambiguity of the changing states of the encoder. I guess I don't understand what part of the code is actually checking this.
// Robust Rotary encoder reading
//
// Copyright John Main - best-microcontroller-projects.com
//
#define CLK 5
#define DATA 4
void setup() {
pinMode(CLK, INPUT);
pinMode(CLK, INPUT_PULLUP);
pinMode(DATA, INPUT);
pinMode(DATA, INPUT_PULLUP);
Serial.begin (9600);
Serial.println("KY-040 Start:");
}
static uint8_t prevNextCode = 0; //Q1: If static is used to create variables visible to one function why is it being used here
static uint16_t store = 0; //to create variables for everything? Why is static the correct choice here?
void loop() {
static int8_t c, val;
if ( val = read_rotary() ) {
c += val;
Serial.print(c); Serial.print(" ");
if ( prevNextCode == 0x0b) {
Serial.print("eleven ");
Serial.println(store, HEX);
}
if ( prevNextCode == 0x07) {
Serial.print("seven ");
Serial.println(store, HEX);
}
}
}
// A vald CW or CCW move returns 1, invalid returns 0.
int8_t read_rotary() {
static int8_t rot_enc_table[] = {0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0}; //Q2: Why the usage of int8_t throughout?
prevNextCode <<= 2;
if (digitalRead(DATA)) prevNextCode |= 0x02; //Q3: What's the syntax here? The if DATA ? prevNextCode OR if... decimal 2?
if (digitalRead(CLK)) prevNextCode |= 0x01;
prevNextCode &= 0x0f;
// If valid then store as 16 bit data.
if (rot_enc_table[prevNextCode] ) { //Q4: What's the argument for this if statement? I see it's checking to see
store <<= 4; // the value of the array at the index [prevNextCode] but then what happens?
store |= prevNextCode;
//if (store==0xd42b) return 1;
//if (store==0xe817) return -1;
if ((store & 0xff) == 0x2b) return -1;
if ((store & 0xff) == 0x17) return 1;
}
return 0;
}
Q1 (Line 17): If static is used to create variables visible to one function, why is it being used to create variables for everything? Why is static the correct choice here?
Q2 (Line 42): Why the usages of int8_t or int16_t. I understand uint8_t is an unsigned char, or one byte. Is this just a different way to declare things? Would using "byte" be the same?
Q3 (Line 45, 46:) What's up with the syntax of these if statements? I'm confused as to what they're doing.
Q4 (Line 51): What's the argument for this if statement? I see it's checking to see the value of the array at the index [prevNextCode] but then what happens?
Thanks for any input or responses,
-TBB
001_robust.ino (1.79 KB)