Оглавление:

Полное решение Arduino Rotary: 5 шагов
Полное решение Arduino Rotary: 5 шагов

Видео: Полное решение Arduino Rotary: 5 шагов

Видео: Полное решение Arduino Rotary: 5 шагов
Видео: ARDUINO ВЗРОСЛЫХ — KernelChip из России 2024, Ноябрь
Anonim
Полное решение для поворотного устройства Arduino
Полное решение для поворотного устройства Arduino

Поворотные энкодеры - это поворотные ручки управления для электронных проектов, часто используемые с микроконтроллерами семейства Arduino. Их можно использовать для точной настройки параметров, навигации по меню, перемещения объектов на экране, установки значений любого типа. Они часто заменяют потенциометры, потому что их можно вращать более точно и бесконечно, они увеличивают или уменьшают одно дискретное значение за раз и часто интегрированы с нажимным переключателем для функций выбора вида. Они бывают всех форм и размеров, но с нижним ценовым диапазоном трудно согласиться, как описано ниже.

Существует бесчисленное количество статей о рабочих деталях и режимах использования поворотных энкодеров, а также множество примеров кодов и библиотек о том, как их использовать. Проблема только в том, что ни один из них не работает со 100% точностью с китайскими поворотными модулями самого низкого ценового диапазона.

Шаг 1: поворотные энкодеры внутри

Датчики вращения внутри
Датчики вращения внутри
Датчики вращения внутри
Датчики вращения внутри
Датчики вращения внутри
Датчики вращения внутри

Поворотная часть энкодера имеет три контакта (и еще два для дополнительной части переключателя). Один - это общая земля (черный GND), два других - для определения направления при повороте ручки (их часто называют синим CLK и красным DT). Оба они подключены к входному выводу PULLUP микроконтроллера, что делает уровень ВЫСОКИМ значением по умолчанию. Когда ручка поворачивается вперед (или по часовой стрелке), сначала синий CLK падает до уровня LOW, затем следует красный DT. Если повернуть дальше, синий CLK снова переходит в HIGH, затем, когда общий патч GND покидает оба соединительных контакта, красный DT также возвращается в HIGH. Таким образом завершается один полный тик FWD (или по часовой стрелке). То же самое происходит в другом направлении BWD (или против часовой стрелки), но теперь красный падает первым, а синий поднимается последним, как показано на изображениях двух уровней соответственно.

Шаг 2: страдания, которые многим причиняют настоящую боль

Несчастье, причиняющее многим настоящую боль
Несчастье, причиняющее многим настоящую боль
Несчастье, причиняющее многим настоящую боль
Несчастье, причиняющее многим настоящую боль
Несчастье, причиняющее многим настоящую боль
Несчастье, причиняющее многим настоящую боль

Распространенная проблема для любителей Arduino заключается в том, что дешевые модули поворотных энкодеров отражают дополнительные изменения выходных уровней, вызывая дополнительные и неправильные показания счетчика направлений. Это предотвращает безупречный подсчет и делает невозможным интеграцию этих модулей в точные ротационные проекты. Эти дополнительные отскоки вызваны механическими движениями пластырей по контактам подключения, и даже установка дополнительных конденсаторов не может полностью их устранить. Отскоки могут появляться где угодно в полных тиковых циклах и проиллюстрированы сценариями реальной жизни на изображениях.

Шаг 3: Решение с конечным автоматом (FSM)

Решение с конечным автоматом (FSM)
Решение с конечным автоматом (FSM)

Изображение показывает полное пространство состояний возможных изменений уровня для двух выводов (синий CLK и красный DT) как для правильных, так и для ложных отскоков. На основе этого конечного автомата можно запрограммировать законченное решение, которое всегда работает со 100% точностью. Поскольку в этом решении нет необходимости в задержках фильтрации, оно также является самым быстрым из возможных. Еще одно преимущество отделения пространства состояний контактов от рабочего режима состоит в том, что каждый может применять режимы опроса или прерывания по своему усмотрению. Опрос или прерывания могут обнаруживать изменения уровня на выводах, а отдельная процедура вычисляет новое состояние на основе текущего состояния и фактических событий изменения уровня.

Шаг 4: Код Arduino

Код Arduino
Код Arduino

Приведенный ниже код подсчитывает тики FWD и BWD на последовательном мониторе, а также интегрирует дополнительную функцию переключения.

// Питер Чургай 2019-04-10

// Контакты поворотного устройства сопоставлены с портами Arduino

#define SW 21 #define CLK 22 #define DT 23

// Текущее и предыдущее значение счетчика, настроенного поворотным

int curVal = 0; int prevVal = 0;

// Семь состояний конечного автомата

#define IDLE_11 0 #define SCLK_01 1 #define SCLK_00 2 #define SCLK_10 3 #define SDT_10 4 #define SDT_00 5 #define SDT_01 6 int state = IDLE_11;

void setup () {

Serial.begin (250000); Serial.println («Пуск…»); // Уровень HIGH будет по умолчанию для всех контактов pinMode (SW, INPUT_PULLUP); pinMode (CLK, INPUT_PULLUP); pinMode (DT, INPUT_PULLUP); // И CLK, и DT будут запускать прерывания для всех изменений уровня attachInterrupt (digitalPinToInterrupt (CLK), rotaryCLK, CHANGE); attachInterrupt (digitalPinToInterrupt (DT), rotaryDT, ИЗМЕНИТЬ); }

void loop () {

// Обработка дополнительного переключателя, встроенного в некоторые поворотные энкодеры if (digitalRead (SW) == LOW) {Serial.println ("Pressed"); в то время как (! digitalRead (SW)); } // Любое изменение значения счетчика отображается в Serial Monitor if (curVal! = PrevVal) {Serial.println (curVal); prevVal = curVal; }}

// Переходы конечного автомата для изменений уровня CLK

void rotaryCLK () {if (digitalRead (CLK) == LOW) {if (state == IDLE_11) state = SCLK_01; иначе, если (состояние == SCLK_10) состояние = SCLK_00; иначе, если (состояние == SDT_10) состояние = SDT_00; } else {если (состояние == SCLK_01) состояние = IDLE_11; иначе, если (состояние == SCLK_00) состояние = SCLK_10; иначе, если (состояние == SDT_00) состояние = SDT_10; иначе, если (состояние == SDT_01) {состояние = IDLE_11; curVal--; }}}

// Переходы конечного автомата для изменений уровня DT

void rotaryDT () {if (digitalRead (DT) == LOW) {if (state == IDLE_11) state = SDT_10; иначе, если (состояние == SDT_01) состояние = SDT_00; иначе, если (состояние == SCLK_01) состояние = SCLK_00; } else {если (состояние == SDT_10) состояние = IDLE_11; иначе, если (состояние == SDT_00) состояние = SDT_01; иначе, если (состояние == SCLK_00) состояние = SCLK_01; иначе, если (состояние == SCLK_10) {состояние = IDLE_11; curVal ++; }}}

Шаг 5: безупречная интеграция

Вы можете проверить в прикрепленном видео, что решение FSM работает точно и быстро даже в случае поворотных энкодеров с низким диапазоном и различными эффектами спорадического дребезга.

Рекомендуемые: