Как работает энкодер?

Ок. сделал так:

#define CLK 10
#define DAT 9

bool flag = true;
bool clkGlb = true;

void enc_interrupt() {
  if (!flag)
    return;
  flag = false;

  clkGlb = 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));
  
  Serial.print("on last interrup clk was ");
  Serial.println(clkGlb);
  flag = true;
}

Результат:

//Старт программы
21:31:03.153 → clk = 1
21:31:03.153 → on last interrup clk was 1
21:31:04.150 → clk = 1
21:31:04.150 → on last interrup clk was 1
21:31:05.188 → clk = 1
21:31:05.188 → on last interrup clk was 1
21:31:06.178 → clk = 1
21:31:06.178 → on last interrup clk was 1
// поворот энкодера влево
21:31:07.155 → clk = 1
21:31:07.155 → on last interrup clk was 0
21:31:08.190 → clk = 1
21:31:08.190 → on last interrup clk was 0
// поворот энкодера вправо
21:31:09.204 → clk = 1
21:31:09.204 → on last interrup clk was 1
21:31:10.164 → clk = 1
21:31:10.164 → on last interrup clk was 1
21:31:11.200 → clk = 1
21:31:11.200 → on last interrup clk was 1
// поворот энкодера влево
21:31:12.199 → clk = 1
21:31:12.199 → on last interrup clk was 0
21:31:13.195 → clk = 1
21:31:13.195 → on last interrup clk was 0
21:31:14.207 → clk = 1
21:31:14.207 → on last interrup clk was 0
// поворот энкодера вправо
21:31:15.194 → clk = 1
21:31:15.194 → on last interrup clk was 1
21:31:16.205 → clk = 1
21:31:16.205 → on last interrup clk was 1
21:31:17.227 → clk = 1
21:31:17.227 → on last interrup clk was 1
21:31:18.209 → clk = 1
21:31:18.209 → on last interrup clk was 1
21:31:19.212 → clk = 1
21:31:19.212 → on last interrup clk was 1

Я бы спросил почему, но боюсь это уведет далеко от темы.

обе две эти переменные должны быть volatile

1 лайк

Сделал. Поведение не изменилось.
С вашего позволения вставлять вывод не буду.

Возможно, дело в том, что нет антидребезга

Антидребезг скорее всего позволит обойти ситуацию. Мне бы хотелось понять, почему она вообще возникает.

Входим в прерывание - был один лог. уровень. Когда делаем digitalRead() уже дребезг.
P.S.
Добавьте конденсатор 0.01 - 0…033мкф

Было такое предположение. Но тогда это скорее было бы случайным событием, а тут оно повторяется с завидным постоянством и почему-то именно при повороте направо.

Подкиньте ваш код в симулятор WOKWI, он дребезг не “симулирует” вроде))

По поводу подавления дребезга я, пожалуй, воспользуюсь советом @v258 и буду гуглить. Просто не хочется отходить от основного вопроса.

Вроде где-то есть галочка “Debounce”. Так что может и симулирует.

Быстрее “подкинуть”, чем писать посты
Куда не крути…

Спойлер

P.S. И в прерывании, не проще ли FALLING использовать, чем с флагом заморачиваться?

В отсутствие дребезга, наверное, проще. Скорее даже флаг вообще не нужен. А вот при наличии дребезга я что-то не могу сходу придумать, как FALLING может помочь.

ТС а ты в курсе, что при одном щелчке твоего энкодера у тебя проходит полный цикл переключения ?

Так что хз, что ты там пытаешься поймать в прерывании на вывод.
А если ещё дребезг добавить …

В курсе.
Это как-то объясняет единицу отлавливаемую в прерывании при повороте вправо?

Ты код свой видел ?
Прерывание только по изменению CLK и вывод раз в секунду. При этом чтение текущих значений .
Ещё раз на картинку, что я скинул посмотри и ответь на свой вопрос сам.

Нет, вслепую писал.
Короче, вопрос закрыт. Всем спасибо!
Тем, кто хоть попытался понять, в чем вопрос, даже искреннее. Остальным - сами придумайте.

Проблема в том, что вы даже не попытались понять, в чем проблема. Но то ваше дело - у нас проблем нету :wink:

Там понимать то нечего , у него в монитор выходит всегда только последнее прерывание, а там данные будут отличатся в зависимости от направления вращения.
Но он тугой, да и хер с ним.

P.S. Чтобы легче было разобраться, желательно сделать “железный” антидребезг, тем более он прост.

Спойлер

Я знаю как сделать “железный” антидребезг. Мне известен принцип работы энкодера (по крайней мере такого). Более того, у меня все работает, если использовать энкодер так, как его предполагается использовать. Просто в процессе наладки я столкнулся с ситуацией, которую не могу объяснить. С ситуацией, в которой энкодер по сути - странная кнопка, нажатие на которую происходит путем поворота вала (Две кнопки, но вторая не используется). и для меня очень странно, что от способа нажатия на эту кнопку меняется результат. Ситуация, в которой кажется(!), что состояния пина “меняется с 1 на 1” (Объяснение

возможно, но я сильно сомневаюсь, что дело именно в этом). Очевидно, что я чего-то не понимаю или чего-то не учитываю. Я пришел сюда именно для того, чтобы кто-то из форумчан, кто гораздо опытнее меня, навел меня на объяснение именно этой конкретной ситуации.
Может там неучтенная наводка от работающей рядом(но не используемой) “второй кнопки” энкодера. Может сигналы из космоса, к которым все давно привыкли, а я столкнулся впервые (Этот абзац я сам считаю бредом, не нужно об этом писать; было бы у меня не бредовое объяснение, я бы сюда и не пошел)
Когда @MMM верно указал, что используемые переменные необходимо сделать volatile, я даже подумал, что это и есть неучтенное мной “Что-то” , но, к сожалению, результат не изменился. Возможно, это была лишь часть ошибки.
Мне не нужны лекции, как правильно использовать энкодер, правильно он у меня работет. И уж тем более не нужны оценки моих умственных способностей.
Спасибо, что еще раз попытались помочь, однако сейчас вопрос не решен, но закрыт. По крайней мере в рамках данного форума. Не тратьте больше на него свое время.