How to Use Rotary Encoders with ESP8266

In this tutorial, I am going to show you how you can use rotary encoders in your projects with an ESP8266 NodeMCU. These devices measure mechanical rotation and can be used to control or measure the rotation of a shaft.

Parts Required

The Rotary Encoder

The device we are working with today is a KY-040 Rotary Encoder (Figure 1). It is an electro-mechanical device that converts the angular position to a digital output signal through PWM technology. This device can be found in many applications, such as industrial controls, robotics, printers and even CNC machines [1].

Figure 1 – Rotary encoder – KY-040

Regarding rotary encoders’ operation, these have two sensors (A and B) located in two distinct positions, as shown in Figure 2. Each one of these sensors emits a signal which, when passing the holes of the circular plate in rotation, outputs a pulse. Counting the pulses allows us to know how much it has rotated. Moreover, due to the positions of the sensors in the encoder, the two signals have a phase difference of 90 degrees, which makes it possible for us to know the direction of the rotation, depending on which pulse is ahead.

Figure 2 – Rotary encoder’s operation (adapted from [2])

In this tutorial, I am going to control the rotation angle of a servo motor, while indicating the direction of the rotation and also use the incorporated switch in the encoder to increase the rotation speed (for more detailed information about servo motors, take a look at our tutorial).

Circuit

The rotary encoder only has 5 pins, as shown in Figure 3.

Figure 3 – KY-040 pinout
  • Vcc: Power supply between (5 V);
  • GND: Ground (0V);
  • SW: Push Switch output (it is normally set as HIGH and is LOW when pressed);
  • DT: Output A
  • CDS: CDS photocell output. It is possible to install a photocell sensor on this module.

Start by connecting the GND to ground and the Vcc pin to 5V in the ESP8266. Then, connect the CLK, DT and SW pins to the digital pins D1, D2 and D3 of the ESP8266, respectively. As for the servo motor, connect its GND pin (brown) to ground, its Vcc pin (red) to 5V and its control pin (orange) to pin D4 of the ESP8266. Finally, connect the anode of the red, green and yellow LEDs to pins D5, D6 and D7 of the ESP8266, respectively, the cathode of the LEDs to their respective 220 Ω resistor and its remaining terminals to ground. In the end, your circuit should be set as shown in Figure 4.

Figure 4 – Circuit’s schematics

Code

As previously mentioned, the KY-040 rotary encoder will be used to control the rotation of the servo motor. When the motor is rotating clockwise, the green LED shall light up, while the red LED is on when the motor is rotating in the counterclockwise direction. Additionally, the encoder’s internal switch is used to increase the speed of the rotation while it is being pressed. In this situation, the yellow LED shall be on to indicate the speed mode is on.

Although the servo motor can rotate more than 180 degrees, it only accepts a value between 0 and 180, and hence the result is limited to this range. I advise you to open the Serial Monitor of the Arduino IDE to see the values being sent to the servo motor.

 // Include the Servo Library
 #include <Servo.h>
 
 // Rotary Encoder Inputs
 #define encoderCLK 5   //D1
 #define encoderDT 4    //D2
 #define encoderSW 0    // D3
 
 // Create a Servo object
 Servo servo;
 
 // LED pins in ESP8266 NodeMCU
 #define ledCCW 12    //D6
 #define ledCW 14     //D5
 #define ledSpeed 13  //D7
 
 int servoAngle = 0; 
 int crntCLK;
 int prvsCLK;
 int SWstate = 0;
 
 void setup() { 
   
   // Set LEDs and rotary encoder pins as inputs  
   pinMode (encoderCLK,INPUT);
   pinMode (encoderDT,INPUT);
   pinMode (encoderSW, INPUT);
   pinMode (ledCW,OUTPUT);
   pinMode (ledCCW,OUTPUT);
   pinMode (ledSpeed,OUTPUT);

   // Attach servo on pin D4 to the servo object
   servo.attach(2);
   
   // Setup Serial Monitor to see rotation angle
   Serial.begin (9600);
   
   // Read the initial state of encoderCLK and assign it to prvsCLK variable
   prvsCLK = digitalRead(encoderCLK);
    
 } 
 
 void loop() {
  
   // Read the current state of encoderCLK
   crntCLK = digitalRead(encoderCLK);
   // Read the state of the encoder's pushbutton value
   SWstate = digitalRead(encoderSW);

   // Lights the yellow LED to indicate increasing rotation speed
   if (SWstate == LOW){
    digitalWrite(ledSpeed, HIGH);
   } else{
    digitalWrite(ledSpeed, LOW);
   }
    
   // A pulse occurs if the previous and the current state differ
    if (crntCLK != prvsCLK){
      // If the encoderDT state is different than the encoderCLK state then the rotary encoder is rotating counterclockwise
        if (digitalRead(encoderDT) != crntCLK) {
          if (SWstate == HIGH){
            servoAngle --;
          }else{
            servoAngle = servoAngle - 10;
          }
          digitalWrite(ledCW, LOW);
          digitalWrite(ledCCW, HIGH);
          if (servoAngle<0){
            servoAngle=-0;
          }
        } 
        else {
          // Encoder is rotating clockwise
          if (SWstate == HIGH){
            servoAngle ++;
          }else{
            servoAngle = servoAngle + 10;
          }
        digitalWrite(ledCW, HIGH);
        digitalWrite(ledCCW, LOW);
        if (servoAngle>180){
          servoAngle= 180;
        }
      }

      // Move servo
      servo.write(servoAngle);
     
      Serial.println(servoAngle);
    } 
    // Update prvsCLK with the current state
    prvsCLK = crntCLK; 
 }

That’s it! If you enjoyed this tutorial, you can visit our YouTube channel and watch our many tutorials. Thanks for following us and be sure to rate, comment and share our content.

References

[1] https://dronebotworkshop.com/rotary-encoders-arduino/

[2] http://hades.mech.northwestern.edu/index.php/Rotary_Encoder

Towards the Future !!! 😉

Leave a Reply

Your email address will not be published. Required fields are marked *

Ads Blocker Image Powered by Code Help Pro

Ads Blocker Detected!!!

We have detected that you are using extensions to block ads. Please support us by disabling these ads blocker.

Powered By
Best Wordpress Adblock Detecting Plugin | CHP Adblock