Arduino Nano - Rotary Encoder

Deze handleiding legt uit hoe u een rotary encoder gebruikt in combinatie met een Arduino Nano. We behandelen:

Hardware Benodigd

1×Official Arduino Nano
1×Alternatief: DIYables ATMEGA328P Nano Development Board
1×USB A naar Mini-B USB kabel
1×Draaiencoder
1×Jumper Wires (verbindingsdraden)
1×(Aanbevolen) Schroefklem Uitbreidingsboard voor Arduino Nano
1×(Aanbevolen) Breakout Uitbreidingsboard voor Arduino Nano
1×(Aanbevolen) Stromsplitter voor Arduino Nano

Of u kunt de volgende kits kopen:

1×DIYables Sensorkit (30 sensoren/displays)
1×DIYables Sensorkit (18 sensoren/displays)
Openbaarmaking: Sommige van de links in deze sectie zijn Amazon-affiliate links. We kunnen een commissie ontvangen voor aankopen die via deze links worden gedaan, zonder extra kosten voor u. We waarderen uw steun.

Over de Rotary Encoder

Een rotary encoder is een draaiende knop die rotaties omzet in een signaal. Het geeft aan hoeveel er gedraaid is en waar de knop staat. Er zijn twee hoofdtypen:

  • Incremental encoder: gebruikt snelle pulsen om te meten hoeveel iets is bewogen.
  • Absolute encoder: geeft voor elke positie een unieke code, zodat u exact kunt bepalen waar iets staat, zelfs bij stroomuitval.

Deze gids richt zich op de incremental encoder.

Rotary Encoder Module Pinout

rotary encoder pinout

Een rotary encoder module heeft 4 pinnen:

  • CLK pin (Output A): dit is de hoofdimpuls die aangeeft hoeveel rotatie heeft plaatsgevonden. Elke keer dat u de knop één detent (klik) draait in welke richting dan ook, geeft de CLK pin een signaal dat een volledige cyclus doorloopt (LAAG → HOOG → LAAG).
  • DT pin (Output B): werkt gelijk aan de CLK pin maar het signaal loopt 90 graden achter op dat van CLK. Dit helpt ons de draairichting te bepalen (met de klok mee of tegen de klok in).
  • SW pin: de uitgang van de drukknop in de encoder. Normaal gesproken is deze open. Als we deze pin met een pull-up weerstand verbinden, is de SW pin HOOG als de knop niet ingedrukt is, en LAAG als deze wel ingedrukt is.
  • VCC pin (+): moet worden verbonden met VCC (tussen 3,3 en 5 volt)
  • GND pin: moet worden verbonden met GND (0V)

Rotary Encoder versus Potentiometer

Een rotary encoder wordt soms verward met een potentiometer, maar het zijn verschillende componenten. Hier een vergelijking:

  • De rotary encoder kan worden gezien als de moderne variant van een potentiometer, met meer functionaliteit.
  • De rotary encoder kan oneindig draaien zonder te stoppen, terwijl een potentiometer slechts ongeveer driekwart van een volle draai kan maken.
  • De rotary encoder produceert pulsen, de potentiometer een analoge spanning.
  • Als u alleen wilt weten hoeveel de knop is gedraaid zonder de exacte positie te weten, is een rotary encoder handig. Heeft u nauwkeurige positie-informatie nodig, dan is een potentiometer beter.

Hoe de Rotary Encoder Werkt

rotary encoder output

Binnenin de encoder zit een schijf met gleuven die verbonden is met een pen C, dat fungeert als de gemeenschappelijke grond. Er zijn nog twee pinnen, A en B.

  • Wanneer u de knop draait, maken pin A en B op bepaalde momenten contact met de gemeenschappelijke grondpen C, in een specifieke volgorde afhankelijk van de draairichting (met of tegen de klok in).
  • Deze contacten creëren twee signalen die in tijd iets verschillen, omdat één pin eerder contact maakt dan de ander. De signalen lopen 90 graden uit fase, dit noemen we quadratuur codering.
  • Draait u met de klok mee, dan raakt pin A eerst de grond voordat pin B dat doet. Draait u tegen de klok in, dan raakt pin B eerst de grond voordat pin A dat doet.
  • Door te monitoren wanneer elke pin contact maakt of verbreekt met de grond, bepalen we de draairichting. Dit doen we door te controleren wat er met pin B gebeurt wanneer pin A van toestand verandert.
Hoe rotary encoder werkt

Als pin A van LAAG naar HOOG verandert:

  • Als pin B LAAG is, draait de knop met de klok mee.
  • Als pin B HOOG is, draait de knop tegen de klok in.

※ Notiz:

Pin A en B zijn verbonden met respectievelijk CLK en DT pinnen. Afhankelijk van de fabrikant kan de volgorde verschillen. De hieronder gegeven code is getest met de rotary encoder van DIYables.

Hoe Programmeert u voor de Rotary Encoder

  • Controleer het signaal van de CLK pin
  • Als de toestand verandert van LAAG naar HOOG, controleer dan de toestand van de DT pin.
    • Als de DT pin HOOG is, draait de knop tegen de klok in, verhoog dan de teller met 1
    • Als de DT pin LAAG is, draait de knop met de klok mee, verlaag dan de teller met 1

Bedradingsschema

Arduino Nano rotary encoder Bedradingsschema

This image is created using Fritzing. Click to enlarge image

Arduino Nano Code – Rotary Encoder

De onderstaande Arduino Nano code doet het volgende:

  • Detecteert de draairichting en hoeveelheid rotatie van de encoder.
    • Detecteert u een detent (klik) draaiing met de klok mee, wordt de teller met één verhoogd.
    • Detecteert u een detent draaiing tegen de klok in, wordt de teller met één verlaagd.
  • Detecteert of de knop ingedrukt is.
/* * Deze Arduino Nano code is ontwikkeld door newbiely.nl * Deze Arduino Nano code wordt zonder enige beperking aan het publiek beschikbaar gesteld. * Voor volledige instructies en schema's, bezoek: * https://newbiely.nl/tutorials/arduino-nano/arduino-nano-rotary-encoder */ #include <ezButton.h> // The library to use for SW pin #define CLK_PIN 2 #define DT_PIN 3 #define SW_PIN 4 #define DIRECTION_CW 0 // clockwise direction #define DIRECTION_CCW 1 // anticlockwise direction int counter = 0; int direction = DIRECTION_CW; int CLK_state; int prev_CLK_state; ezButton button(SW_PIN); 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 anticlockwise 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("Twisted direction: "); if (direction == DIRECTION_CW) Serial.print("CLOCKWISE"); else Serial.print("ANTICLOCKWISE"); Serial.print(" - counter: "); Serial.println(counter); } // save last CLK state prev_CLK_state = CLK_state; if (button.isPressed()) { Serial.println("The button is pressed"); } }

Om de code voor het ontbouncen van de knop eenvoudiger te maken, gebruiken we de ezButton bibliotheek.

Snel aan de slag

  • Installeer de ezButton bibliotheek in de Arduino IDE. Zie How To
  • Kopieer de bovenstaande code en open deze in de Arduino IDE
  • Klik op de Upload knop in de Arduino IDE om de code naar de Arduino Nano te uploaden
  • Draai de knop met de klok mee, en daarna tegen de klok in
  • Druk op de knop
  • Bekijk het resultaat in de Seriële Monitor.
COM6
Send
Twisted direction: CLOCKWISE - counter: 1 Twisted direction: CLOCKWISE - counter: 2 Twisted direction: CLOCKWISE - counter: 3 Twisted direction: CLOCKWISE - counter: 4 Twisted direction: CLOCKWISE - counter: 5 Twisted direction: ANTICLOCKWISE - counter: 4 Twisted direction: ANTICLOCKWISE - counter: 3 Twisted direction: ANTICLOCKWISE - counter: 2 Twisted direction: ANTICLOCKWISE - counter: 1 Twisted direction: ANTICLOCKWISE - counter: 0 The button is pressed
Autoscroll Show timestamp
Clear output
9600 baud  
Newline  

Code Uitleg

Bekijk de regel-voor-regel opmerkingen in de code.

Arduino Nano Code – Rotary Encoder met Interrupt

In de vorige voorbeeldcode gebruiken we polling, waarbij continu de toestand van de pin wordt gecontroleerd. Dit heeft twee nadelen:

  • Het belast de Arduino Nano onnodig
  • Sommige tellingen kunnen gemist worden als ander codeblok lang duurt

Een oplossing hiervoor is het gebruik van interrupts. Interrupts zorgen ervoor dat de Arduino alleen actie onderneemt als er een event plaatsvindt, waardoor de Arduino andere taken kan blijven uitvoeren zonder events te missen.

Hieronder een voorbeeld van het uitlezen van een rotary encoder met interrupts.

/* * Deze Arduino Nano code is ontwikkeld door newbiely.nl * Deze Arduino Nano code wordt zonder enige beperking aan het publiek beschikbaar gesteld. * Voor volledige instructies en schema's, bezoek: * https://newbiely.nl/tutorials/arduino-nano/arduino-nano-rotary-encoder */ #include <ezButton.h> // The library to use for SW pin #define CLK_PIN 2 // The Arduino Nano pin D2 connect to the pin CLK of the rotary encoder #define DT_PIN 3 // The Arduino Nano pin D3 connect to the pin DT of the rotary encoder #define SW_PIN 4 // The Arduino Nano pin D4 connect to the pin SW of the rotary encoder #define DIRECTION_CW 0 // clockwise direction #define DIRECTION_CCW 1 // anticlockwise direction volatile int counter = 0; volatile int direction = DIRECTION_CW; volatile unsigned long last_time; // for debouncing int prev_counter; ezButton button(SW_PIN); void INTERRUPT_handler() { if ((millis() - last_time) < 50) // debounce time is 10ms return; if (digitalRead(DT_PIN) == HIGH) { // The encoder is rotating in anticlockwise 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(); } 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 INTERRUPT_handler() when CLK pin changes from LOW to HIGH attachInterrupt(digitalPinToInterrupt(CLK_PIN), INTERRUPT_handler, RISING); } void loop() { button.loop(); // MUST call the loop() function first if (prev_counter != counter) { Serial.print("Twisted direction: "); if (direction == DIRECTION_CW) Serial.print("CLOCKWISE"); else Serial.print("ANTICLOCKWISE"); Serial.print(" - counter: "); Serial.println(counter); prev_counter = counter; } if (button.isPressed()) { Serial.println("The button is pressed"); } // TO DO: your other work here }

Als u de knop draait, ziet u informatie verschijnen in de Seriële Monitor, vergelijkbaar met de eerdere code.

※ Notiz:

  • Als u interrupts gebruikt, moet u de CLK pin van de encoder aansluiten op een Arduino Nano pin die interrupts ondersteunt. Niet alle Arduino Nano pinnen kunnen dat; alleen pin 2 en 3 kunnen interrupts verwerken.
  • Sommige tutorials gebruiken twee interrupts voor één encoder, maar dat is onnodig en inefficiënt. Eén interrupt is voldoende.
  • Het is belangrijk de volatile keyword te gebruiken voor globale variabelen die in de interrupt worden gebruikt om onverwachte problemen te voorkomen.
  • Houd de code binnen de interrupt zo simpel mogelijk. Gebruik geen Serial.print() of Serial.println() in een interrupt.

Arduino Nano Rotary Encoder Toepassingen

Met de Rotary Encoder kunt u onder andere de volgende toepassingen maken:

  • Arduino Nano - Rotary Encoder regelt de positie van een servo motor
  • Arduino Nano - Rotary Encoder regelt de helderheid van een LED
  • Arduino Nano - Rotary Encoder regelt de snelheid van een stappenmotor

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.

Bekijk onze video-tutorial voor een visuele begeleiding bij dit project! De video biedt extra inzichten en stap-voor-stap instructies voor een succesvolle implementatie.

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!