/*
 Project: Blink Plus Rotary Encoder
 Project By: Jim F, Calgary AB Canada
 Started: 23 June 2025
 Updated: 23 June 2025
 */
// Defines
#define encoder0PinA 2
#define encoder0PinB 3
#define rotOutA 4
#define rotOutB 5
// Global Variables
int ctr = 0;
int a0=0;
int dir=0;
int prevVal = -1;
int rotStatus=0;
unsigned long rotVal = 0;
unsigned long blinkMs=0;
// Functions
unsigned long milsec(unsigned long prevMs) {
  return millis()-prevMs;
}
void blinkLed() {
  if(milsec(blinkMs)>250) {
    digitalWrite(LED_BUILTIN,!digitalRead(LED_BUILTIN));
    blinkMs=milsec(0);
  }
}
void rotSim(int rotA, int rotB) {
  digitalWrite(rotOutA, rotA);
  digitalWrite(rotOutB, rotB);
  delay(1);
}
int getRotVals() {
  int a = 1 - digitalRead(encoder0PinA);
  int b = 1 - digitalRead(encoder0PinB);
  int val= a*2+b;
  if (val == prevVal && ctr == 0) {
    rotStatus=0;
  }
  rotVal = rotVal * 10 + val;
  if (val == 0) {
    // Serial.print(rotVal);
    if (rotVal == 3210) {
      rotStatus=1;
    }
    if (rotVal == 1230) {
      rotStatus=-1;
    }
    rotVal = 0;
  }
  prevVal = val;
  return val;
}
void getDir() {
  a0 = analogRead(A0);
  if (a0 > 512 + 150) {
    dir = 1;
  }
  if (a0 < 512 - 150) {
    dir = -1;
  }
  ctr = (ctr + 1) % 4;
  if (dir == 1) {
    if (ctr == 0) {
      rotSim(LOW, LOW);
    }
    if (ctr == 1) {
      rotSim(LOW, HIGH);
    }
    if (ctr == 2) {
      rotSim(HIGH, LOW);
    }
    if (ctr == 3) {
      rotSim(HIGH, HIGH);
    }
  }
  if (dir == -1) {
    if (ctr == 0) {
      rotSim(HIGH, HIGH);
    }
    if (ctr == 1) {
      rotSim(HIGH, LOW);
    }
    if (ctr == 2) {
      rotSim(LOW, HIGH);
    }
    if (ctr == 3) {
      rotSim(LOW, LOW);
    }
  }
}
void updateDisplay() {
  if(rotStatus !=0) {
    Serial.print(a0);
    Serial.print(",");
    Serial.println(rotStatus);
  }
}
// Setup
void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(encoder0PinA, INPUT_PULLUP);
  pinMode(encoder0PinB, INPUT_PULLUP);
  pinMode(rotOutA, OUTPUT);
  pinMode(rotOutB, OUTPUT);
  Serial.begin(9600);
}
// Main Loop
void loop() {
  getRotVals();
  getDir();
  blinkLed();
  updateDisplay();
  delay(10);
}