// Encoder pins
const byte pinA = 0; // PB0
const byte pinB = 1; // PB1
// Outputs
const byte pinCLK = 2; // PB2
const byte pinDATA = 3; // PB3
volatile byte lastState = 0;
void setup() {
pinMode(pinA, INPUT_PULLUP);
pinMode(pinB, INPUT_PULLUP);
pinMode(pinCLK, OUTPUT);
pinMode(pinDATA, OUTPUT);
// Initialize last state
lastState = (digitalRead(pinA) << 1) | digitalRead(pinB);
// Enable pin change interrupts on A and B
GIMSK |= (1 << PCIE);
PCMSK |= (1 << pinA) | (1 << pinB);
sei();
}
ISR(PCINT0_vect) {
byte a = digitalRead(pinA);
byte b = digitalRead(pinB);
byte curr = (a << 1) | b;
byte trans = (lastState << 2) | curr;
lastState = curr;
switch (trans) {
case 0b0001: case 0b0111: case 0b1110: case 0b1000:
digitalWrite(pinDATA, HIGH); // CW
pulseCLK();
break;
case 0b0010: case 0b0100: case 0b1101: case 0b1011:
digitalWrite(pinDATA, LOW); // CCW
pulseCLK();
break;
default:
break;
}
}
void pulseCLK() {
digitalWrite(pinCLK, HIGH);
delayMicroseconds(200); // adjust
digitalWrite(pinCLK, LOW);
}
void loop() {
// Nothing needed; ISR handles everything
}