Зачем? Для подключения одного энкодера с кнопкой нужно три выхода микроконтроллера - "жаба душит", особенно если нужна только "крутилка" для навигации по меню или в качестве регулятора громкости, а самих "крутилок" будет несколько. Примеров такого подключения в Интернет я не нашел - поэтому схему и код придумал сам. Насколько это правильно или криво пишите в комментариях.
Подключать будем механический энкодер EC11
У него всего 20 положений вала на один оборот, а поскольку вращается он весьма не спешно пальцами руки - по идее проблем с обработкой событий возникнуть не должно.
Нам нужно считывать 4 состояния:
- ничего не нажато и не вращается;
- нажата кнопка SB1;
- замкнуты контакты AB;
- замкнуты контакты BC;
Есть еще промежуточное 5-е состояние - замкнуты оба контакта одновременно AB и BC - но для распознавания вращения ручки оно не принципиально - поэтому попробуем избавиться от него схемотехникой.
Очевидно, что для определения любого из 4-х состояний потребуется 2-х битный АЦП. Платформа ESP32 умеет измерять напряжение в диапазоне от 0....3,3V. АЦП у платформы 12 битный, хотя по факту толку от него чуть больше чем нисколько, о чем я писал в этой статье:
Но! Нам требуются АЦП с разрешением 2 бита.
Поэтому:
- уменьшаем аппаратное разрешение АЦП до 9 bit с помощью c помощью функции: (по слухам оно так даже быстрее работает)
analogReadResolution(9); - с помощью оператора побитового сдвига вправо (>>) получаем информацию из нужных нам старших битов 8 и 7:
enc1Val = analogRead(enc1Pin)>> 7;
Если вам не понятно, как с помощью "пары закорючек" диапазон 511....0 перекочевал в диапазон 3....0, рекомендую посмотреть это видео.
Получившийся самодельный аппаратно-программный двух-битный колхоз будет оцифровывать входящее напряжение следующим образом:
Подавать на вход пограничные напряжения например в районе 2475mV разумеется не следует, так как за счет шума АЦП будет находиться в глубоком раздумье вернуть ему значение 2 или 3.
Вот пример - как это можно сделать правильно:
- нажата на кнопка < 413mV;
- контакт CB = 1238mV;
- не нажато, и не крутится = 2063mV;
- контакт AB > 2888mV;
- AB+BC хорошо бы попасть в диапазон ничего не нажато.
Поматерившись поколдовав с онлайн калькулятором делителя напряжений, из номиналов резисторов из стандартного ряда E24 нарисовалась следующая схема:
- S1 < 413mV - получилось 0mV;
- CB = 1238mV - получилось 1264mV;
- не нажато, и не крутится = 2063mV - получилось 2075mV;
- контакт AB > 2888mV - получилось 2870mV; - работать будет.
- AB+CB -> получилось 2357mV (т.е. диапазоне ничего не нажато!).
Конденсатор емкостью 0.01 мкФ в данной схеме устраняет дребезг контактов энкодера и шум самого АЦП.
Воспользовавшись бесполезными по мнению некоторых Дзен-читателей номиналами резисторов из стандартного ряда E24:
кидаем на макетной плате прототип.
Почему нельзя было просто разделить опорное напряжение на равные части например используя одинаковые резисторы 1 кОм? Сделать то так, конечно можно, только тогда в программе придется писать огромную пачку операторов if else. А подобрав резисторы делителя более точно - можно обойтись всего одним оператором побитового сдвига вправо (>>), что как упрощает саму программу, так и увеличивает её быстродействие.
Заливаем в ESP32 супер-пупер сложную программу из 12 строк кода.
Открываем плоттер по последовательному соединению, и вращая ручку и нажимая кнопку получаем красивую картинку.
- ничего не нажато - всегда получаем значение 2;
- вращение туда - получаем последовательность 3-2-1 (цифра 1 на картинке);
- вращение обратно - получаем последовательность 1-2-3 (цифра 2 на картинке);
- нажимаем кнопку - получаем ноль;
С этими данными можно работать, но пример перевода этого графика в количество щелчков при повороте ручки, обработка нажатия кнопки, и заталкивание этого кода в процедуру прерываний будут разобраны в следующей статье.
Оглавление канала тут:
Всем удачи!