Non linear rotary encoder - option selection

Hi!
I’m trying to create a system which would allow users to pick an option using a knob. The issue I’m encountering is that my rotary encoder is not changing values linearly for every “click”. The values seem to be in the range of 1-7 for every click of the rotary encoder.

The solution I’ve come up with to solve this is to listen for interrupts. Thus, when a click is detected it would wait 1 second before allowing arduino to listen to another interrupt, but I’m not sure how to go about this.

The main aim is to allow the user to switch between options every second.

Refer to attachment for my current version of the code

Thanks for reading through my first post!
Regards

Potentiometer-optionChoice_2.ino (2.09 KB)

I faced a similar problem with my mechanical encoder. I had to add small capacitors to the data and clock pins to eliminate switch bounce. Just attach them between the pin and ground. To big is a carriage and you won't be able to turn the knob very fast try 10 uf to start
Z

Hi,
Thanks for the reply. I researched further on the matter as I did not have a capacitor, and found out that the issue occurs due to debouncing. For anyone else also encountering the same issue, this link helped me a lot: http://www.instructables.com/id/Improved-Arduino-Rotary-Encoder-Reading/?ALLSTEPS
Best regards

Twerter:
Hi,
Thanks for the reply. I researched further on the matter as I did not have a capacitor, and found out that the issue occurs due to debouncing. For anyone else also encountering the same issue, this link helped me a lot: http://www.instructables.com/id/Improved-Arduino-Rotary-Encoder-Reading/?ALLSTEPS
Best regards

Here's my code for encoders:
I usually use a capacitor for the debounce but I added a timer to save you the trouble since it is only used for user input.

#define SwitchPin 2 // interrupt 0
#define ClockPin  3 // interrupt 1
#define DataPin   4 // this can be any pin

volatile uint8_t EncodeCTR;
volatile uint8_t EncoderChange;
volatile uint8_t SwitchCtr;

void setup() {
  Serial.begin(115200);
  pinMode(SwitchPin , INPUT_PULLUP); // switch is not powered by the + on the Encoder breakout
  pinMode(ClockPin , INPUT);
  pinMode(DataPin , INPUT);
  attachInterrupt(digitalPinToInterrupt(SwitchPin), Switch, FALLING);
  attachInterrupt(digitalPinToInterrupt(ClockPin), Encode, FALLING);
}

void loop() {
  if (EncoderChange || SwitchCtr) {
    EncoderChange = 0;
    Serial.print("EncodeCTR: ");
    Serial.print(EncodeCTR);
    Serial.println();
    Serial.print("Switch Pressed ");
    Serial.println(SwitchCtr);
    SwitchCtr = 0;
  }
  // This is non blocking so other code can go here
}

void Switch() {
  static unsigned long DebounceTimer;
  if ((unsigned long)(millis() - DebounceTimer) >= (100)) {
    DebounceTimer = millis();
    if (!SwitchCtr) {
      SwitchCtr++;
    }
  }
}
void Encode() { // we know the clock pin is low so we only need to see what state the Data pin is and count accordingly
  static unsigned long DebounceTimer;
  if ((unsigned long)(millis() - DebounceTimer) >= (100)) { // standard blink without delay timer
    DebounceTimer = millis();
    if (digitalRead(DataPin) == HIGH) // switch to LOW to reverse direction of Encoder counting
    {
      EncodeCTR++;
    }
    else {
      EncodeCTR--;
    }
    EncoderChange++;
  }
}

Z