Popis
Zapojení inkrementálního spínače (rotary encoder) přes posuvný registr 74HC165.
Obvod
Příklad kódu
#include <TimerOne.h> 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; } }