ESP32 using HW-040 encoder

Thread Starter

zazas321

Joined Nov 29, 2015
668
Hey. I want to use an encoder to increment a counter when i rotate the encoder handle. I have encoder module HW-040:
1598333206558.png\
It already comes with pre-installed pull ups on A and B data lines.

Code:
#define outputB  35    // DATA signal
#define outputA 34    // CLOCK signal
int counter = 0;
int aState;
int aLastState;

void setup() {
   pinMode (outputA,INPUT);
   pinMode (outputB,INPUT);
  
   Serial.begin (115200);
   // Reads the initial state of the outputA
   aLastState = digitalRead(outputA);  
}

void loop() {
   aState = digitalRead(outputA); // Reads the "current" state of the outputA
   // If the previous and the current state of the outputA are different, that means a Pulse has occured
   if (aState != aLastState){    
     // If the outputB state is different to the outputA state, that means the encoder is rotating clockwise
     if (digitalRead(outputB) != aState) {
       counter ++;
     } else {
       counter --;
     }
     Serial.print("Position: ");
     Serial.println(counter);
   }
   aLastState = aState; // Updates the previous state of the outputA with the current state
}
I was trying to find as simple as possible code to do that and managed to find the code above. It seems to work alright except that sometimes it prints multiple lines at once when I make a single rotation on my encoder:


1598333360995.png

As you can see from my serial monitor above, I am getting multiple prints (I just barely touched the encoder and rotated it by only 1 position). I should be getting Position:1 and instead is bouncing back and forth for multiple times. Could someone suggest a simple solution to this problem?
 
Last edited:

Thread Starter

zazas321

Joined Nov 29, 2015
668
So I managed to find slightly more complex code with debounce implemented and that should have worked:
https://www.brainy-bits.com/arduino-rotary-encoder-ky-040/

Initilaizing variables:

Code:
typedef struct{
  long TimeOfLastDebounce = 0;
  int DelayofDebounce = 1;
// Store previous Pins state
  int PreviousCLK;  
  int PreviousDATA;
  int displaycounter=0;
  int flag_ready_to_read=1;
  }encoder_struct;
encoder_struct encoder;

Code:
void check_rotary() {

if ((encoder.PreviousCLK == 0) && (encoder.PreviousDATA == 1)) {
    if ((digitalRead(PinCLK) == 1) && (digitalRead(PinDT) == 0)) {
      encoder.displaycounter++;
      Serial.println(encoder.displaycounter);
    }
    if ((digitalRead(PinCLK) == 1) && (digitalRead(PinDT) == 1)) {
      encoder.displaycounter--;
      Serial.println(encoder.displaycounter);
    }
  }

if ((encoder.PreviousCLK == 1) && (encoder.PreviousDATA == 0)) {
    if ((digitalRead(PinCLK) == 0) && (digitalRead(PinDT) == 1)) {
      encoder.displaycounter++;
      encoder.flag_ready_to_read=1;
      Serial.println(encoder.displaycounter);
    }
    if ((digitalRead(PinCLK) == 0) && (digitalRead(PinDT) == 0)) {
      encoder.displaycounter--;
      encoder.flag_ready_to_read=1;
      Serial.println(encoder.displaycounter);
    }
  }

if ((encoder.PreviousCLK == 1) && (encoder.PreviousDATA == 1)) {
    if ((digitalRead(PinCLK) == 0) && (digitalRead(PinDT) == 1)) {
      encoder.displaycounter++;
      encoder.flag_ready_to_read=1;
      Serial.println(encoder.displaycounter);
    }
    if ((digitalRead(PinCLK) == 0) && (digitalRead(PinDT) == 0)) {
      encoder.displaycounter--;
      encoder.flag_ready_to_read=1;
      Serial.println(encoder.displaycounter);
    }
  } 

if ((encoder.PreviousCLK == 0) && (encoder.PreviousDATA == 0)) {
    if ((digitalRead(PinCLK) == 1) && (digitalRead(PinDT) == 0)) {
      encoder.displaycounter++;
      encoder.flag_ready_to_read=1;
      Serial.println(encoder.displaycounter);
    }
    if ((digitalRead(PinCLK) == 1) && (digitalRead(PinDT) == 1)) {
      encoder.displaycounter--;
      encoder.flag_ready_to_read=1;
          Serial.println(encoder.displaycounter);
    }
  }           
}

void encoder_inside_loop(){
   if ((millis() - encoder.TimeOfLastDebounce) > encoder.DelayofDebounce) {
   
    check_rotary();  // Rotary Encoder check routine below
   
    encoder.PreviousCLK=digitalRead(PinCLK);
    encoder.PreviousDATA=digitalRead(PinDT);
   
    encoder.TimeOfLastDebounce=millis();  // Set variable to current millis() timer
  }
 
  // Check if Rotary Encoder switch was pressed
  if (digitalRead(PinSW) == LOW) {
      EEPROM.write(12, encoder.displaycounter);
      EEPROM.commit();
      encoder.flag_ready_to_read=0;
      Serial.print("device set to=");
      Serial.print(encoder.displaycounter);
  }
}

and my void loop:

Code:
void loop() {
  if (!client.connected()){
    reconnect();
  }
  client.loop();
  Read_sensor();//READING SENSOR EVERY
  check_button_state();
  encoder_inside_loop();
Since I have other functions running inside void loop, I believe that makes my encoder not work properly. When I tested this code in a brand new project, just calling encoder functions inside void loop, it seemed counting fine, but now my counter incrementing does not work properly:
I have tried to rotate the encoder to one direction ( just incrementing) and the result is:
1598335774466.png

As you can see its working very unreliably. It is supposed to just increment since I am only rotating in one direction.

The decrementing works fine.
 
Top