ESP32 - Rotary Encoder

In deze handleiding leert u hoe u een rotary encoder gebruikt met een ESP32. Dit is wat we zullen behandelen:

Hardware Benodigdheden

1×ESP32 ESP-WROOM-32 Ontwikkelingsmodule
1×USB-kabel Type-C
1×Draaiencoder
1×Breadboard (experimenteerprint)
1×Jumper Draden (mannelijk-mannelijk)
1×(Aanbevolen) Schroefklem Uitbreidingsboard voor ESP32
1×(Aanbevolen) Breakout Expansion Board for ESP32
1×(Aanbevolen) Stromsplitter voor ESP32

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 Rotary Encoder

Een draai-knop, zoals op een radio, kan signalen uitsturen die omgezet worden in elektrische signalen. Dit helpt ons te weten hoeveel hij gedraaid is en waar hij staat. Er zijn twee hoofdtypen:

  • Incrementele encoder: deze gebruikt snelle pulsen om te meten hoeveel een positie veranderd is.
  • Absolute encoder: dit type geeft een unieke code voor elke positie, wat helpt om exact te weten waar iets is, ook als de stroom uitvalt.

Deze les gaat vooral over het eerste type, de incrementele encoder.

Rotary Encoder Module Pinout

rotary encoder pinout

Een rotary encoder module heeft 4 pins:

  • CLK pin (Output A): is de hoofd-puls die ons vertelt hoeveel rotatie heeft plaatsgevonden. Elke keer dat u de knop met een klik (detent) draait in welke richting dan ook, geeft de CLK pin een signaal dat een volledige cyclus voltooit (LOW HIGH LOW).
  • DT pin (Output B): werkt vergelijkbaar met de CLK pin maar het signaal loopt 90 graden achter op het CLK signaal. Dit helpt ons om te bepalen in welke richting (met de klok mee of tegen de klok in) gedraaid wordt.
  • SW pin: komt van de knop in de encoder. Deze is normaal open. Als we een pull-up weerstand aan deze pin toevoegen, is de SW pin HIGH als de knop niet ingedrukt is en LOW als hij wel ingedrukt is.
  • VCC pin (+): moet aangesloten worden op VCC (tussen 3.3 en 5 volt)
  • GND pin: moet aangesloten worden op GND (0V)

Rotary Encoder vs Potentiometer

U kunt een rotary encoder verwarren met een potentiometer, maar het zijn verschillende componenten. Hier een vergelijking:

  • Een rotary encoder is als een moderne versie van een potentiometer maar kan meer.
  • Een rotary encoder kan een volledige cirkel ronddraaien zonder te stoppen, terwijl een potentiometer ongeveer drie kwart van een cirkel kan draaien.
  • Een rotary encoder levert pulsen (digital signals), een potentiometer levert analoge spanning.
  • Een rotary encoder is handig als u alleen wilt weten hoeveel de knop is verplaatst, niet exact waar hij staat. Een potentiometer is nuttig als u precies wilt weten waar een knop staat.

Hoe werkt een Rotary Encoder

rotary encoder output

Binnenin de encoder zit een schijfje met uitsparingen dat verbonden is met een pin genaamd C, die functioneert als een gedeelde massa (ground). Verder zijn er twee pins, A en B.

  • Wanneer u de knop draait, maken pinnen A en B contact met die gedeelde grondpin C, maar in welke volgorde ze dat doen hangt af van de draairichting (met de klok mee of tegen de klok in).
  • Deze contacten creëren twee signalen die iets in timing verschillen omdat de ene pin eerder dan de andere contact maakt. Deze signalen lopen 90 graden uit fase ten opzichte van elkaar, dit heet quadratuur codering.
  • Als u de knop met de klok mee draait, maakt pin A als eerste contact met de grond, daarna pin B. Draait u tegen de klok in, dan maakt pin B eerst contact voordat pin A dat doet.
  • Door te controleren wanneer elke pin contact maakt of verbreekt, kunnen we bepalen in welke richting de knop draait. Dit doen we door te kijken wat er gebeurt met pin B als pin A verandert.
How rotary encoder works

Wanneer A van LOW naar HIGH gaat:

  • Als B HIGH is, wordt de knop tegen de klok in gedraaid.
  • Als B LOW is, wordt de knop met de klok mee gedraaid.

※ Notiz:

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

Hoe Programmeert u de Rotary Encoder

  • ESP32 leest het signaal van de CLK pin
  • Als de staat verandert van LOW naar HIGH, leest ESP32 de staat van de DT pin.
    • Als de DT pin HIGH is, wordt de knop tegen de klok in gedraaid en verhoogt ESP32 de teller met 1.
    • Als de DT pin LOW is, wordt de knop met de klok mee gedraaid en verlaagt ESP32 de teller met 1.

Aansluitschema

ESP32 rotary encoder Aansluitschema

This image is created using Fritzing. Click to enlarge image

ESP32 Code – Rotary Encoder

De onderstaande ESP32 code doet het volgende:

  • Detecteert de draairichting en hoeveelheid rotatie van de encoder.
    • Als wordt gedetecteerd dat de knop één klik (detent) met de klok mee is gedraaid, verhoogt de teller met één.
    • Als wordt gedetecteerd dat de knop één klik tegen de klok in is gedraaid, verlaagt de teller met één.
  • Detecteert of de knop is ingedrukt.
/* * Deze ESP32 code is ontwikkeld door newbiely.nl * Deze ESP32 code wordt zonder enige beperking aan het publiek beschikbaar gesteld. * Voor volledige instructies en schema's, bezoek: * https://newbiely.nl/tutorials/esp32/esp32-rotary-encoder */ #include <ezButton.h> // the library to use for SW pin #define CLK_PIN 25 // ESP32 pin GPIO25 connected to the rotary encoder's CLK pin #define DT_PIN 26 // ESP32 pin GPIO26 connected to the rotary encoder's DT pin #define SW_PIN 27 // ESP32 pin GPIO27 connected to the rotary encoder's SW pin #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 7; 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("Rotary Encoder:: direction: "); if (direction == DIRECTION_CW) Serial.print("Clockwise"); else Serial.print("Counter-clockwise"); Serial.print(" - count: "); 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 ontkrachten van de knop (debouncing) te vereenvoudigen, wordt de ezButton bibliotheek gebruikt.

Snelle Stappen

Als u voor het eerst werkt met ESP32, zie dan hoe u de omgeving instelt voor ESP32 in Arduino IDE.

  • Installeer de ezButton bibliotheek in Arduino IDE.
  • Kopieer bovenstaande code en open die in Arduino IDE.
  • Klik op de Upload-knop in Arduino IDE om de code naar de ESP32 te uploaden.
  • Draai de knop met de klok mee en daarna tegen de klok in.
  • Druk op de knop.
  • Bekijk het resultaat in de Serial Monitor.
COM6
Send
Rotary Encoder:: direction: CLOCKWISE - count: 1 Rotary Encoder:: direction: CLOCKWISE - count: 2 Rotary Encoder:: direction: CLOCKWISE - count: 3 Rotary Encoder:: direction: CLOCKWISE - count: 4 Rotary Encoder:: direction: CLOCKWISE - count: 5 Rotary Encoder:: direction: ANTICLOCKWISE - count: 4 Rotary Encoder:: direction: ANTICLOCKWISE - count: 3 Rotary Encoder:: direction: ANTICLOCKWISE - count: 2 Rotary Encoder:: direction: ANTICLOCKWISE - count: 1 Rotary Encoder:: direction: ANTICLOCKWISE - count: 0 The button is pressed
Autoscroll Show timestamp
Clear output
9600 baud  
Newline  

Code Uitleg

Bekijk de commentaarregels in de code voor een regel-voor-regel uitleg.

ESP32 Code – Rotary Encoder met Interrupt

In de vorige code kan gebruik van polling om continu de status van de pin te controleren, ESP32 bronnen verspillen en tellingen missen als andere code langzaam draait.

Een effectieve oplossing is het gebruik van een interrupt, waarmee polling overbodig wordt gemaakt. Dit stelt de ESP32 in staat om andere taken uit te voeren zonder tellingen te missen. Hieronder staat de ESP32 code die interrupts gebruikt om richting en positie van de rotary encoder uit te lezen.

/* * Deze ESP32 code is ontwikkeld door newbiely.nl * Deze ESP32 code wordt zonder enige beperking aan het publiek beschikbaar gesteld. * Voor volledige instructies en schema's, bezoek: * https://newbiely.nl/tutorials/esp32/esp32-rotary-encoder */ #include <ezButton.h> // the library to use for SW pin #define CLK_PIN 25 // ESP32 pin GPIO25 connected to the rotary encoder's CLK pin #define DT_PIN 26 // ESP32 pin GPIO26 connected to the rotary encoder's DT pin #define SW_PIN 27 // ESP32 pin GPIO27 connected to the rotary encoder's SW pin #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 7; void IRAM_ATTR ISR_encoder() { 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(); } 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_encoder() when CLK pin changes from LOW to HIGH attachInterrupt(digitalPinToInterrupt(CLK_PIN), ISR_encoder, RISING); } void loop() { button.loop(); // MUST call the loop() function first if (prev_counter != counter) { Serial.print("Rotary Encoder:: direction: "); if (direction == DIRECTION_CW) Serial.print("CLOCKWISE"); else Serial.print("ANTICLOCKWISE"); Serial.print(" - count: "); Serial.println(counter); prev_counter = counter; } if (button.isPressed()) { Serial.println("The button is pressed"); } // TO DO: your other work here }

Terwijl u de knop draait ziet u informatie verschijnen in de Serial Monitor, vergelijkbaar met de vorige code.

※ Notiz:

  • U komt misschien tutorials tegen die twee interrupts voor één encoder gebruiken, maar dat is onnodig en inefficiënt. Eén interrupt is voldoende.
  • Het is belangrijk om de volatile keyword te gebruiken bij globale variabelen die in de interrupt worden gebruikt. Het nalaten hiervan kan onvoorziene problemen veroorzaken.
  • Houd de code binnen de interrupt zo eenvoudig mogelijk. Vermijd het gebruik van Serial.print() of Serial.println() binnen de interrupt.

ESP32 Rotary Encoder Toepassingen

Met de Rotary Encoder kunnen de volgende toepassingen worden gerealiseerd, maar deze zijn niet beperkt tot:

  • ESP32 - Rotary Encoder bestuurt positie van een Servo Motor
  • ESP32 - Rotary Encoder bestuurt helderheid van een LED
  • ESP32 - Rotary Encoder bestuurt 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.

Functiereferenties

※ 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!