/* Rotary encoder handler for arduino. * * Revision: 2020 Dean Souleles, KK4DAS, Licensed under the GNU GPL Version 3. * Contact: kk4das@gmail.com * Added default pins and button handling * * Copyright 2011 Ben Buxton. Licenced under the GNU GPL Version 3. * Contact: bb@cactii.net * */ #include "Arduino.h" #include "RotaryEnc.h" /* * The below state table has, for each state (row), the new state * to set based on the next encoder output. From left to right in, * the table, the encoder outputs are 00, 01, 10, 11, and the value * in that position is the new state to set. */ #define R_START 0x0 #ifdef HALF_STEP // Use the half-step state table (emits a code at 00 and 11) // nulled out to only use full step #define R_CCW_BEGIN 0x1 #define R_CW_BEGIN 0x2 #define R_START_M 0x3 #define R_CW_BEGIN_M 0x4 #define R_CCW_BEGIN_M 0x5 const unsigned char ttable[6][4] = { // R_START (00) {R_START_M, R_CW_BEGIN, R_CCW_BEGIN, R_START}, // R_CCW_BEGIN {R_START_M | DIR_CCW, R_START, R_CCW_BEGIN, R_START}, // R_CW_BEGIN {R_START_M | DIR_CW, R_CW_BEGIN, R_START, R_START}, // R_START_M (11) {R_START_M, R_CCW_BEGIN_M, R_CW_BEGIN_M, R_START}, // R_CW_BEGIN_M {R_START_M, R_START_M, R_CW_BEGIN_M, R_START | DIR_CW}, // R_CCW_BEGIN_M {R_START_M, R_CCW_BEGIN_M, R_START_M, R_START | DIR_CCW}, }; #else // Use the full-step state table (emits a code at 00 only) #define R_CW_FINAL 0x1 #define R_CW_BEGIN 0x2 #define R_CW_NEXT 0x3 #define R_CCW_BEGIN 0x4 #define R_CCW_FINAL 0x5 #define R_CCW_NEXT 0x6 const unsigned char ttable[7][4] = { // R_START {R_START, R_CW_BEGIN, R_CCW_BEGIN, R_START}, // R_CW_FINAL {R_CW_NEXT, R_START, R_CW_FINAL, R_START | DIR_CW}, // R_CW_BEGIN {R_CW_NEXT, R_CW_BEGIN, R_START, R_START}, // R_CW_NEXT {R_CW_NEXT, R_CW_BEGIN, R_CW_FINAL, R_START}, // R_CCW_BEGIN {R_CCW_NEXT, R_START, R_CCW_BEGIN, R_START}, // R_CCW_FINAL {R_CCW_NEXT, R_CCW_FINAL, R_START, R_START | DIR_CCW}, // R_CCW_NEXT {R_CCW_NEXT, R_CCW_FINAL, R_CCW_BEGIN, R_START}, }; #endif /* * Constructor Common */ void Rotary::Constructor_Common() { // Set pins to input. pinMode(pin1, INPUT); pinMode(pin2, INPUT); pinMode(btn, INPUT); #ifdef ENABLE_PULLUPS digitalWrite(pin1, HIGH); digitalWrite(pin2, HIGH); digitalWrite(btn, HIGH); #endif // Initialise state. state = R_START; } /* * Constructor. Each arg is the pin number for each encoder contact. */ Rotary::Rotary(char _pin1, char _pin2,char _btn) { // Assign variables. pin1 = _pin1; pin2 = _pin2; btn = _btn; Constructor_Common(); } Rotary::Rotary() { // Assign variables to defaults pin1 = ENCODER_A; pin2 = ENCODER_B; btn = ENCODER_BTN; Constructor_Common(); } unsigned char Rotary::process() { // Grab state of input pins. unsigned char pinstate = (digitalRead(pin2) << 1) | digitalRead(pin1); // Determine new state from the pins and state table. state = ttable[state & 0xf][pinstate]; // Return emit bits, ie the generated event. return state & 0x30; } byte Rotary::buttonState() { // returns the state of the Encoder button LOW=pressed // return byte(digitalRead(btn)); return digitalRead(btn); }