Jste zde

Inkrementální spínač + 74HC165

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;
  }
}