Popis
Zapojení inkrementálního spínače (rotary encoder) přes posuvný registr 74HC165.
Obvod
Příklad kódu
int pinLatch = 16; // 74HC165 pin 1
int pinClock = 5; // 74HC165 pin 2
int pinData = 7; // 74HC165 pin 9
const int btnDebounce = 20;
const int btnClickInterval = 1000;
int16_t mainLast, mainValue;
bool mainButtonState, mainButtonStateLast;
volatile int16_t timerDelta;
volatile int16_t timerLast;
volatile bool timerButtonPressed;
void timerCall() {
/* rotary movement */
unsigned long now = millis();
int8_t curr = 0;
static unsigned long lastButtonCheck = 0;
static unsigned long lastButtonClick = 0;
digitalWrite(pinLatch, LOW);
delayMicroseconds(20);
digitalWrite(pinLatch, HIGH);
if (digitalRead(pinData) == LOW) {
curr = 3;
}
digitalWrite(pinClock, HIGH);
delayMicroseconds(5);
digitalWrite(pinClock, LOW);
if (digitalRead(pinData) == LOW) {
curr ^= 1;
}
int8_t diff = timerLast - curr;
if (diff & 1) {
timerLast = curr;
timerDelta += (diff & 2) - 1;
}
/* button */
if ((now - lastButtonCheck) >= btnDebounce) {
lastButtonCheck = now;
digitalWrite(pinClock, HIGH);
delayMicroseconds(5);
digitalWrite(pinClock, LOW);
if (digitalRead(pinData) == LOW) {
if ((now - lastButtonClick) >= btnClickInterval) {
timerButtonPressed = true;
lastButtonClick = now;
}
}
}
}
void setup() {
Serial.begin(9600);
Timer1.initialize(1000);
Timer1.attachInterrupt(timerCall);
pinMode(pinLatch, OUTPUT);
pinMode(pinClock, OUTPUT);
pinMode(pinData, INPUT);
mainLast = -1;
mainButtonStateLast = false;
}
void loop() {
/* get rotary encoder value */
cli();
mainValue += timerDelta;
timerDelta = 0;
mainButtonState = timerButtonPressed;
timerButtonPressed = false;
sei();
if (mainValue != mainLast) {
mainLast = mainValue;
Serial.print("Encoder Value: ");
Serial.println(mainValue);
}
if (mainButtonState) {
Serial.println("Button pressed");
mainButtonState = false;
}
}