Rotary encoder. Suddenly not counting again

Hi

I am having issues with a rotary encoder. Thought I had it sussed out, but tonight is is playing up again.

Its one of those standard cheapy rotary modules.

Don't really want to post all the code... its huge, complicated and now a bit messy.
If I strip out everything, it still doesn't work correctly.

Connected to an ESP32. Button works fine. Held high with 10k, triggers low.
Encoder buttons A and B held high to 3.3v with 10k.

So, I set the interrupt to look for a FALLING signal.

#define rotary_encoder_A_pin 1
#define rotary_encoder_B_pin 3
#define rotary_encoder_button 39

int rotary_state;                                                                       
int rotary_laststate;
int timevalue;
int oldtimevalue;

----------------------------

In setup I have:

  pinMode(rotary_encoder_button, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(rotary_encoder_A_pin), encodermoved, FALLING);
  attachInterrupt(digitalPinToInterrupt(rotary_encoder_B_pin), encodermoved, FALLING);

----------------------------

Then a subroutine for the interrupt:

void encodermoved() {

    rotary_state = digitalRead(rotary_encoder_A_pin);

    if (rotary_state != rotary_laststate) {

      if (digitalRead(rotary_encoder_B_pin) != rotary_state) {
        timevalue --; if (timevalue < 2) {
          timevalue = 120;
        }
      } else {
        timevalue ++; if (timevalue > 120) {
          timevalue = 2;
        }
      }
    }
    rotary_laststate = rotary_state;
}


------------------------

Finally in the main loop:

    if (oldtimevalue != timevalue) {                                                                          
      Serial.println(int(timevalue/2));                            // Encoder counts in 2's
      oldtimevalue = timevalue;
    }

It just doesn't seem to want to count. If you change the interrupt to CHANGE, it does count in both directions, but then gets stuck on certain values (possibly a rotary encoder issue?) and constantly reports the timevalue/2 (so it must be stuck between readings).

Tried several encoders and same result

It counts in 2's, so I have to divide the result.

Couldn't find a library that played nice with the ESP32. Maybe it's the pins I am using?

Weirdly. if I put noInterrupts(); in my main loop, inside a routine that isn't called.... the whole ESP32 hangs.
That routine is only called at a later time when I wanted to disable the rotary encoder.
Not sure why it hangs the code when it's not even called.

Please post the entire code, not selected snippets.
There are numerous of decoder code out there. Compare with them.
All failed attempts only makes it take more time to find the useful information. Drop them. They tell You have randomly tried things.

OK. I will have to tidy it up first, 2000+ Lines and a bit of a mess

Then just post your Minimum Reproducible Example.

Do you have pull-ups on the A & B lines ?

They are usually on the back of these modules already..........

If you're going to use variables modified inside the ISR they should be declared with the volatile - Arduino Reference keyword.

Firstly, the variables used in interrupt handlers must be volatile as @dougp said.

Secondly, the rotary encoder does not need to use two interrupts. One is enough.

You can try to run the example code with a single interrupt and without interrupt in this Arduino rotary encoder tutorial

Hello all. Sorry for the delay. I had a bit of an emergency to deal with.

OK. I sat and trawled through all the rotary encode libraries I could find for ESP32 and standard Arduino's.

Found one called AiEsp32Rotary that actually seems to work fine.
I did need to alter the pins on the ESP32 however, as in certain positions, the rotary encoder stopped any uploads.
You only needed to rotate the encoder one notch, but better to fix it in hardware I suppose.
Must have been holding a pin high.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.