Пълно ротационно решение на Arduino: 5 стъпки
Пълно ротационно решение на Arduino: 5 стъпки
Anonim
Пълно ротационно решение на Arduino
Пълно ротационно решение на Arduino

Ротационните енкодери са въртящи се копчета за управление на електронни проекти, често използвани с микроконтролери от семейство Arduino. Те могат да се използват за фина настройка на параметрите, навигиране в менютата, преместване на обекти по екрана, задаване на всякакви стойности. Те са често срещани заместители на потенциометрите, тъй като могат да се въртят по -точно и безкрайно, увеличават или намаляват една по една дискретна стойност наведнъж и често са интегрирани с бутон за натискане за функции за избор на вид. Те се предлагат във всякакви форми и размери, но най -ниският ценови диапазон е труден за взаимодействие, както е обяснено по -долу.

Има безброй статии за работните детайли и режимите на използване на ротационни енкодери, както и множество примерни кодове и библиотеки за това как да ги използвате. Единственият проблем е, че никой от тях не работи 100% точно с най -ниския ценови клас китайски ротационни модули.

Стъпка 1: Въртящи се енкодери отвътре

Ротационни енкодери отвътре
Ротационни енкодери отвътре
Ротационни енкодери отвътре
Ротационни енкодери отвътре
Ротационни енкодери отвътре
Ротационни енкодери отвътре

Ротационната част на енкодера има три щифта (и още два за опционалната част на превключвателя). Едната е обща основа (черен GND), другите две са за определяне на посоката при завъртане на копчето (те често се наричат сини CLK и червени DT). И двете са прикрепени към входен щифт PULLUP на микроконтролера, което прави нивото HIGH тяхното четене по подразбиране. Когато копчето се завърти напред (или по посока на часовниковата стрелка), първо синият 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 на серийния монитор и също така интегрира опционалната функция за превключване.

// Peter Csurgay 2019-04-10

// Игли на ротационно картографирани към Arduino портове

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

// Текуща и предишна стойност на брояча, настроен от въртящото се устройство

int curVal = 0; int prevVal = 0;

// Седем състояния на FSM (машина с крайни състояния)

#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, CHANGE); }

void loop () {

// Работа с опционалния превключвател, интегриран в някои ротационни енкодери if (digitalRead (SW) == LOW) {Serial.println ("Pressed"); while (! digitalRead (SW)); } // Всяка промяна в стойността на брояча се показва в Serial Monitor if (curVal! = PrevVal) {Serial.println (curVal); prevVal = curVal; }}

// Преходи на състоянието на машината за промени на ниво CLK

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

// Преходи на състоянието на машината за промени на нивото на DT

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

Стъпка 5: Безупречна интеграция

Можете да проверите в прикаченото видео, че решението FSM работи точно и бързо дори в случай на ротационни енкодери с нисък обхват с различни спорадични ефекти на отскачане.

Препоръчано: