/* 
  KY-040 Encoder Rotativo
  https://docs.wokwi.com/parts/wokwi-ky-040
  2021, Uri Shaked
*/

#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4);

const int ENCODER_CLK = 2;
const int ENCODER_DT = 3;
const int ENCODER_SW = 4;

int counter = 0;

void setup() {

  lcd.init();
  lcd.backlight();

  pinMode(ENCODER_CLK, INPUT);
  pinMode(ENCODER_DT, INPUT);
  pinMode(ENCODER_SW, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(ENCODER_CLK), readEncoder, FALLING);
}

void loop() {

  lcd.setCursor(3, 0);
  lcd.print("Contador:");
  lcd.setCursor(7, 1);
  lcd.print(getCounter());
  lcd.print("        ");

  if (digitalRead(ENCODER_SW) == LOW) {
    resetCounter();
  }
}

void readEncoder() {
  int dtValue = digitalRead(ENCODER_DT);
  if (dtValue == HIGH) {
    counter++;
  }
  if (dtValue == LOW) {
    counter--;
  }
}

// Obtiene el valor del contador, deshabilitando las interrupciones.
// Esto asegura que readEncoder() no cambie el valor mientras lo leemos.
int getCounter() {
  int result;
  noInterrupts();
  result = counter;
  interrupts();
  return result;
}

void resetCounter() {
  noInterrupts();
  counter = 0;
  interrupts();
}