#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// LCD Display setup (change address and size as necessary)
LiquidCrystal_I2C lcd(0x27, 16, 2); // I2C address, columns, rows
// Pin definitions
const int pinA = 2; // Encoder A input
const int pinB = 3; // Encoder B input
const int pinZ = 4; // Z input pulse
const int pinZled = 5; // Z LED output
const int pinINC = 6; // INC output
const int pinLatch = 10; // Latch output
const int pinInvLatch = 11; // Inverted Latch output
volatile int counter = 0;
volatile bool newZPulse = false;
volatile bool updateCounter = false;
// Previous state of encoder A and B
volatile int lastAState = LOW;
volatile int lastBState = LOW;
void setup()
{
pinMode(pinA, INPUT_PULLUP);
pinMode(pinB, INPUT_PULLUP);
pinMode(pinZ, INPUT_PULLUP);
pinMode(pinZled, OUTPUT);
pinMode(pinINC, OUTPUT);
pinMode(pinLatch, OUTPUT);
pinMode(pinInvLatch, OUTPUT);
digitalWrite(pinZled, LOW);
digitalWrite(pinINC, LOW);
// digitalWrite(pinLatch, LOW);
//digitalWrite(pinInvLatch, HIGH);
// Initialize LCD
lcd.begin(0,10,8);
lcd.backlight();
lcd.print("ENCODER POSITION ");
attachInterrupt(digitalPinToInterrupt(pinA), encoderA, RISING);
attachInterrupt(digitalPinToInterrupt(pinB), encoderB, RISING);
attachInterrupt(digitalPinToInterrupt(pinZ), encoderZ, RISING);
}
void loop()
{
if (updateCounter)
{
updateCounter = false;
// Display the counter value
lcd.setCursor(6, 1);
lcd.print(" "); // Clear previous value
lcd.setCursor(6, 1);
lcd.print(counter);
// Set output pins based on counter
if (counter == 10)
{
digitalWrite(pinLatch, HIGH);
digitalWrite(pinInvLatch, LOW);
delayMicroseconds(104);
digitalWrite(pinLatch, LOW);
digitalWrite(pinInvLatch, HIGH);
}
else
{
digitalWrite(pinLatch, LOW);
digitalWrite(pinInvLatch, HIGH);
}
}
if (digitalRead(pinZ) == HIGH)
{
// Reset counter on Z pulse
digitalWrite(pinZled, HIGH);
digitalWrite(pinINC, HIGH);
delayMicroseconds(1104);
digitalWrite(pinZled, LOW);
digitalWrite(pinINC, LOW);
counter = 0; // Reset counter
updateCounter = true;
}
}
void encoderA()
{
// A leads B
if (digitalRead(pinB) == HIGH)
{
counter++;
// if (counter > 360) counter = 360; // Limit to maximum
if (counter > 15) counter = 0 ; // Limit to maximum
updateCounter = true;
}
}
void encoderB()
{
// B leads A
if (digitalRead(pinA) == HIGH)
{
counter--;
if (counter < 0) counter = 0; // Limit to minimum
updateCounter = true;
}
}
void encoderZ()
{
if (digitalRead(pinZ) == HIGH)
{
// Reset counter on Z pulse
digitalWrite(pinZled, HIGH);
digitalWrite(pinINC, HIGH);
delayMicroseconds(1104);
digitalWrite(pinZled, LOW);
digitalWrite(pinINC, LOW);
counter = 0; // Reset counter
updateCounter = true;
}
}