Есть esp32. Есть модуль энкодера, в котором пины CLK и DT подтянуты к верхнему уровню. Антидребезговых фильтров нет. Соединены банально:
" + " → +3,3В
GND → GND
CLK → pin10
DT → pin9
Тестовый скетч:
#define CLK 10
#define DAT 9
bool flag = true;
void enc_interrupt() {
if (!flag)
return;
flag = false;
Serial.print("clk changed. clk = ");
Serial.println(digitalRead(CLK));
}
void setup() {
Serial.begin(115200);
pinMode(CLK, INPUT);
pinMode(DAT, INPUT);
attachInterrupt(CLK, enc_interrupt, CHANGE);
}
void loop() {
delay(1000);
Serial.print("clk = ");
Serial.println(digitalRead(CLK));
flag = true;
}
Если энкодер не трогать, то, как и ожидается, в СериалМоитор выводится:
clk = 1
clk = 1
Далее я ожидаю, что при вращении энкодера в СериалМонитор будет выводитьсяclk
clk = 1
clk = 1
changed. clk = 0
При вращении налево так и происходит. А вот при вращении на право выдается:
clk = 1
clk = 1
clk changed. clk = 1
Получается пародоксальная ситуация, на пине CLK была единица, а потом она поменялась на… опять единицу.
Подскажите, пожалуйста, чего конкретно я не понимаю, и почему так происходит? В чем разница в данном случае при вращении налево и направо?
Поведение достаточно стабильно и замена энкодера на аналогичный на результат не влияет.
У меня нет проблемы в работе с энкодером. Он работает нормально, если его подключить нормально и использовать “неплохую библиотеку”.
У меня вопрос, как он работает? Ключевое: почему возникает ситуация, когда на пине была единица и во время срабатывания на этом пине прерывания типа CHANGE на нем снова единица. Причем поведение зависит от направления вращения энкодера.