Arduino UNO R4 - Rotary Encoder

In deze handleiding leren we hoe u een incrementele encoder kunt gebruiken met Arduino UNO R4. We behandelen:

Arduino UNO R4 rotary encoder

Over Rotary Encoder

Een rotary encoder is een apparaat dat draaiende beweging omzet in een elektrisch signaal. Het controleert de draaiing en positie van een as of knop. Er zijn twee hoofdtypen:

  • Incrementele encoder: Deze genereert pulsen om veranderingen in positie te meten.
  • Absolute encoder: Deze geeft een unieke digitale code voor elke positie, waardoor het perfect is voor nauwkeurige positionering, zelfs wanneer de stroom uitvalt.

Deze tutorial gaat over de incrementele encoder.

Rotary Encoder Module Pinout

rotary encoder pinout

Een rotary encoder module heeft vier pinnen:

  • CLK pin (Output A): Deze pin zendt een signaal elke keer dat u de knop één klik draait in welke richting dan ook, waarbij een volledige signaalgolf van LOW naar HIGH naar LOW wordt getoond. Dit vertelt ons hoeveel de knop is gedraaid.
  • DT pin (Output B): Vergelijkbaar met de CLK pin, maar het signaal van deze pin is enigszins vertraagd en treedt op 90 graden na het CLK signaal op. Deze vertraging helpt ons bepalen of de draaiing met de klok mee of tegen de klok in is.
  • SW pin: Deze verbindt met de interne drukknop van de encoder, die normaal gesproken open is. Het gebruik van een pull-up weerstand op deze pin betekent dat deze HIGH zal tonen wanneer de knop niet wordt ingedrukt en LOW wanneer deze wel wordt ingedrukt.
  • VCC pin (+): Sluit deze pin aan op een voeding die tussen 3.3 en 5 volt levert.
  • GND pin: Sluit deze pin aan op de massa (0V).

Rotary Encoder vs Potentiometer

U zou de rotary encoder kunnen verwarren met de potentiometer, maar het zijn verschillende onderdelen. Hier is hoe ze vergelijken:

  • Een rotary encoder kan volledig rond blijven draaien, maar een potentiometer kan slechts driekwart van een volledige cirkel draaien.
  • Een rotary encoder geeft pulsen af, terwijl een potentiometer analoge spanning afgeeft.
  • Een rotary encoder is nuttig om te weten hoeveel een knop is gedraaid, maar niet de exacte positie. Een potentiometer is goed voor het vinden van de precieze positie van een knop.

Hoe Rotary Encoder Werkt

rotary encoder output

In de encoder zit een schijf met sleuven verbonden aan een pin genaamd C, die fungeert als gemeenschappelijke massa. Er zijn ook twee extra pinnen, A en B.

  • Wanneer u de knop draait, maken pinnen A en B contact met de gemeenschappelijke massa pin C, maar in een specifieke volgorde gebaseerd op de richting van de draaiing, ofwel met de klok mee of tegen de klok in.
  • Dit contact genereert twee signalen die enigszins verschillend zijn in hun timing omdat de ene pin eerder contact maakt met de massa dan de andere. Deze signalen zijn 90 graden uit fase, en dit wordt kwadratuur-codering genoemd.
  • Het draaien van de knop met de klok mee zorgt ervoor dat pin A eerder contact maakt met de massa dan pin B. Het tegen de klok in draaien zorgt ervoor dat pin B eerder contact maakt met de massa dan pin A.
  • Door te observeren wanneer elke pin contact maakt of breekt met de massa, kunnen we de richting van de draaiing van de knop bepalen. We doen dit door de veranderingen in pin B ten opzichte van pin A te analyseren.
How rotary encoder works

Wanneer A schakelt van LOW naar HIGH:

  • Draai de knop met de klok mee als B LOW is.
  • Draai de knop tegen de klok in als B HIGH is.

※ Notiz:

Pin A en B zijn verbonden met de CLK en DT pinnen. De opstelling kan variëren afhankelijk van de fabrikant. De hier gegeven codes zijn getest met de rotary Encoder van DIYables.

Hoe te Programmeren voor Rotary Encoder

  • Controleer het signaal van de CLK pin.
  • Wanneer het signaal verandert van LOW naar HIGH, controleer wat de DT pin toont.
    • Als de DT pin HIGH toont, wordt de knop tegen de klok in gedraaid. Tel 1 op bij de teller.
    • Als de DT pin LOW toont, wordt de knop met de klok mee gedraaid. Trek 1 af van de teller.

Bedradingsdiagram

Arduino UNO R4 rotary encoder Wiring Diagram

This image is created using Fritzing. Click to enlarge image

Zie De beste manier om Arduino Uno R4 en andere componenten van stroom te voorzien.

Arduino UNO R4 Code – Rotary Encoder zonder Interrupt

Deze Arduino UNO R4 code voert de volgende acties uit:

  • Het detecteert hoe en hoeveel de encoder draait.
    • Als het detecteert dat de knop één klik naar rechts wordt gedraaid, telt het één op bij de teller.
    • Als het detecteert dat de knop één klik naar links wordt gedraaid, vermindert het de teller met één.
  • Het merkt op of de knop wordt ingedrukt.
/* * Deze Arduino UNO R4 code is ontwikkeld door newbiely.nl * Deze Arduino UNO R4 code wordt zonder enige beperking aan het publiek beschikbaar gesteld. * Voor volledige instructies en schema's, bezoek: * https://newbiely.nl/tutorials/arduino-uno-r4/arduino-uno-r4-rotary-encoder */ #include <ezButton.h> // the library to use for SW pin #define CLK_PIN 2 // The Arduino UNO R4 pin connected to the CLK pin of encoder #define DT_PIN 3 // The Arduino UNO R4 pin connected to the DT pin of encoder #define SW_PIN 4 // The Arduino UNO R4 pin connected to the SW pin of encoder #define DIRECTION_CW 0 // clockwise direction #define DIRECTION_CCW 1 // counter-clockwise direction int counter = 0; int direction = DIRECTION_CW; int CLK_state; int prev_CLK_state; ezButton button(SW_PIN); // create ezButton object that attach to pin 4 void setup() { Serial.begin(9600); // configure encoder pins as inputs pinMode(CLK_PIN, INPUT); pinMode(DT_PIN, INPUT); button.setDebounceTime(50); // set debounce time to 50 milliseconds // read the initial state of the rotary encoder's CLK pin prev_CLK_state = digitalRead(CLK_PIN); } void loop() { button.loop(); // MUST call the loop() function first // read the current state of the rotary encoder's CLK pin CLK_state = digitalRead(CLK_PIN); // If the state of CLK is changed, then pulse occurred // React to only the rising edge (from LOW to HIGH) to avoid double count if (CLK_state != prev_CLK_state && CLK_state == HIGH) { // if the DT state is HIGH // the encoder is rotating in counter-clockwise direction => decrease the counter if (digitalRead(DT_PIN) == HIGH) { counter--; direction = DIRECTION_CCW; } else { // the encoder is rotating in clockwise direction => increase the counter counter++; direction = DIRECTION_CW; } Serial.print("DIRECTION: "); if (direction == DIRECTION_CW) Serial.print("Clockwise"); else Serial.print("Counter-clockwise"); Serial.print(" | COUNTER: "); Serial.println(counter); } // save last CLK state prev_CLK_state = CLK_state; if (button.isPressed()) { Serial.println("The button is pressed"); } }

We gebruiken de ezButton bibliotheek om de knop-debouncecode eenvoudiger te maken.

Snelle Stappen

Volg deze instructies stap voor stap:

  • Als dit uw eerste keer is met de Arduino Uno R4 WiFi/Minima, raadpleeg dan de tutorial over het opzetten van de omgeving voor Arduino Uno R4 WiFi/Minima in de Arduino IDE.
  • Sluit de rotary encoder aan op de Arduino UNO R4 volgens het meegeleverde diagram.
  • Verbind het Arduino Uno R4 board met uw computer via een USB-kabel.
  • Start de Arduino IDE op uw computer.
  • Selecteer het juiste Arduino Uno R4 board (bijv., Arduino Uno R4 WiFi) en COM-poort.
  • Voeg de ezButton bibliotheek toe aan de Arduino IDE. Voor instructies, bezoek deze link: [ezButton library](https://arduinogetstarted.com/tutorials/arduino-button-library#content_how_to_install
  • Kopieer de meegeleverde code en open deze in de Arduino IDE.
  • Klik op de Upload knop in Arduino IDE om de code naar de Arduino UNO R4 te uploaden.
  • Draai de knop met de klok mee en dan tegen de klok in.
  • Druk op de knop.
  • Controleer de resultaten op de Serial Monitor.
COM6
Send
DIRECTION: Clockwise | COUNTER: 1 DIRECTION: Clockwise | COUNTER: 2 DIRECTION: Clockwise | COUNTER: 3 DIRECTION: Clockwise | COUNTER: 4 DIRECTION: Clockwise | COUNTER: 5 DIRECTION: Counter-clockwise | COUNTER: 4 DIRECTION: Counter-clockwise | COUNTER: 3 DIRECTION: Counter-clockwise | COUNTER: 2 DIRECTION: Counter-clockwise | COUNTER: 1 DIRECTION: Counter-clockwise | COUNTER: 0 The button is pressed
Autoscroll Show timestamp
Clear output
9600 baud  
Newline  

Code Uitleg

Bekijk de opmerkingen in de code voor elke regel.

Arduino UNO R4 Code – Rotary Encoder met Interrupt

In het vorige codevoorbeeld gebruikten we de polling-methode, die constant de toestand van de pin controleert. Deze methode heeft twee nadelen:

  • Inefficiënt gebruik van Arduino UNO R4 bronnen
  • Sommige tellingen kunnen worden overgeslagen als andere code te lang duurt om uit te voeren.

Een methode om dit te controleren is door interrupts. Interrupts helpen de constante noodzaak om te controleren op een specifieke gebeurtenis te vermijden. Dit laat de Arduino UNO R4 andere taken uitvoeren terwijl deze nog steeds gebeurtenissen monitort.

Laten we de onderstaande code bekijken die interrupt gebruikt om waarden uit de encoder te lezen.

/* * Deze Arduino UNO R4 code is ontwikkeld door newbiely.nl * Deze Arduino UNO R4 code wordt zonder enige beperking aan het publiek beschikbaar gesteld. * Voor volledige instructies en schema's, bezoek: * https://newbiely.nl/tutorials/arduino-uno-r4/arduino-uno-r4-rotary-encoder */ #include <ezButton.h> // the library to use for SW pin #define CLK_PIN 2 // The Arduino UNO R4 pin connected to the CLK pin of encoder #define DT_PIN 3 // The Arduino UNO R4 pin connected to the DT pin of encoder #define SW_PIN 4 // The Arduino UNO R4 pin connected to the SW pin of encoder #define DIRECTION_CW 0 // clockwise direction #define DIRECTION_CCW 1 // counter-clockwise direction volatile int counter = 0; volatile int direction = DIRECTION_CW; volatile unsigned long last_time; // for debouncing int prev_counter; ezButton button(SW_PIN); // create ezButton object that attach to pin 4 void setup() { Serial.begin(9600); // configure encoder pins as inputs pinMode(CLK_PIN, INPUT); pinMode(DT_PIN, INPUT); button.setDebounceTime(50); // set debounce time to 50 milliseconds // use interrupt for CLK pin is enough // call ISR_encoderChange() when CLK pin changes from LOW to HIGH attachInterrupt(digitalPinToInterrupt(CLK_PIN), ISR_encoderChange, RISING); } void loop() { button.loop(); // MUST call the loop() function first if (prev_counter != counter) { Serial.print("DIRECTION: "); if (direction == DIRECTION_CW) Serial.print("Clockwise"); else Serial.print("Counter-clockwise"); Serial.print(" | COUNTER: "); Serial.println(counter); prev_counter = counter; } if (button.isPressed()) { Serial.println("The button is pressed"); } // TO DO: your other work here } void ISR_encoderChange() { if ((millis() - last_time) < 50) // debounce time is 50ms return; if (digitalRead(DT_PIN) == HIGH) { // the encoder is rotating in counter-clockwise direction => decrease the counter counter--; direction = DIRECTION_CCW; } else { // the encoder is rotating in clockwise direction => increase the counter counter++; direction = DIRECTION_CW; } last_time = millis(); }
  • Kopieer de meegeleverde code en open deze in de Arduino IDE.
  • Klik op de Upload knop in Arduino IDE om de code naar de Arduino UNO R4 te uploaden.

Nu, wanneer u de knop draait, zult u informatie zien verschijnen op de Serial Monitor, vergelijkbaar met wat u eerder in de vorige code opmerkte.

※ Notiz:

  • Om de CLK pin van de encoder aan te sluiten op een Arduino UNO R4 met een interrupt, moet u pinnen 2 of 3 gebruiken. Dit zijn de enige pinnen die interrupts ondersteunen.
  • Sommige online gidsen suggereren mogelijk het gebruik van twee interrupts voor één encoder, maar dit is niet nodig. Het gebruik van slechts één interrupt is voldoende.
  • Zorg ervoor dat u het volatile sleutelwoord gebruikt voor alle globale variabelen in de interrupt om problemen te voorkomen.
  • Houd de programmering binnen de interrupt eenvoudig. Gebruik daar geen Serial.print() of Serial.println().

Video Tutorial

We overwegen het maken van videotutorials. Als u videotutorials belangrijk vindt, abonneer u dan op ons YouTube-kanaal om ons te motiveren de video's te maken.

Functiereferenties

Gerelateerde Tutorials

※ ONZE BERICHTEN

  • U bent welkom om de link naar deze tutorial te delen. Gebruik onze inhoud echter niet op andere websites. We hebben veel moeite en tijd gestoken in het maken van de inhoud, respecteer alstublieft ons werk!