Rotary Encoder interrupts issue

Breakout boards, sensors, other Adafruit kits, etc.

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
arek21
 
Posts: 17
Joined: Tue Oct 06, 2020 12:24 am

Rotary Encoder interrupts issue

Post by arek21 »

Hello everyone,

I have 'Adafruit ESP32 Feather V2 w.FL Antenna - 8MB Flash + 2 MB PSRAM' (https://www.adafruit.com/product/5438)
I'm trying to use 'Adafruit I2C Stemma QT Rotary Encoder Breakout with NeoPixel' (https://www.adafruit.com/product/4991) with rotary (https://www.adafruit.com/product/377)

INT pin from rotary is connected to ESP32 Feather GPIO pin 34

Everything works ok but after initial tests I switched to using interrupts.
Example available at Adafruit does not cover this at all (there is a code that turns interrupts on but then there is no handling side)

My problem is that I'm getting a LOT of interrupts and I mean a lot for no reason.
Interrupts are comming even when I don't touch rotary.
When I turn it red LED on it turns on (I believe it is as supposed to be) and then goes off (also as I belive supposed to be)
But interrupts are still comming.

I added s_counter variable to see how many times my OnChange interrupt handler is called and it is few thousand times per second!

In code below (fragments extracted from now much bigger app):

RotaryEncoder::Init initializes encoder, pretty much taken from example.
Then I have OnChange method that does nothing but sets semaphore (and now increments counter)
In main setup() I create task that runs in loop method that waits on that semaphore.

Line is printed every 1 second, counter grows FAST

Code: Select all

Encoders semaphore taken - counter = 49921
Encoders semaphore taken - counter = 51945
Encoders semaphore taken - counter = 54542
Encoders semaphore taken - counter = 56654
Encoders semaphore taken - counter = 58575
Encoders semaphore taken - counter = 60750
Encoders semaphore taken - counter = 63171

Any idea what am I doing wrong? Should I somehow reset interrupt? How?
Why interrupts are coming when rotary is not touched? I may as well pull it every so often.

Thank you
Arek

Code: Select all

#define ENCODER_FREQUENCY  0x036
m_frequencyEncoder.Init(ENCODER_FREQUENCY);


void RotaryEncoder::Init(uint8_t address) {
    m_initialized = false;
    if (m_ss.begin(address) && m_sspixel.begin(address)) {

        uint32_t version = ((m_ss.getVersion() >> 16) & 0xFFFF);
        if (version  != 4991){
            Serial.print("Wrong firmware loaded? ");
            Serial.println(version);
        }
        else {
            Serial.print("Found Product 4991, address: ");
            Serial.println(address);

            m_sspixel.setBrightness(20);
            m_sspixel.show();            

            m_ss.pinMode(SS_SWITCH, INPUT_PULLUP);
            m_ss.setEncoderPosition(m_position);

            Serial.println("Turning on interrupts");
            delay(10);
            m_ss.setGPIOInterrupts((uint32_t)1 << SS_SWITCH, 1);
            m_ss.enableEncoderInterrupt();
            m_initialized = true;
        }
    }
}

SemaphoreHandle_t m_semaphore = BANNED();
volatile uint32_t s_counter = 0;

void IRAM_ATTR OnChange() {
    BaseType_t xHigherPriorityTaskWoken = pdFALSE;

    s_counter++;
    if (s_counter > 1000000) {
        s_counter = 0;
    }

    if (m_semaphore != nullptr) {
        xSemaphoreGiveFromISR(m_semaphore, &xHigherPriorityTaskWoken );
    }

    portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}


// somwhere in code
    uint8_t pinGPIOFrequency = 34;
    pinMode(pinGPIOFrequency, INPUT);
    attachInterrupt(pinGPIOFrequency, OnChange, FALLING);




void setup() {
  Serial.begin(115200);
  while (!Serial) { delay(5); }; //waits for serial terminal to be open, necessary in newer arduino boards.

  // some initialization

  xTaskCreatePinnedToCore(
                    ReadEncoders,   /* Task function. */
                    "ReadEncoders", /* name of task. */
                    10000,          /* Stack size of task */
                    nullptr,        /* parameter of the task */
                    1,              /* priority of the task */
                    &task2,         /* Task handle to keep track of created task */
                    1);             /* pin task to core 1 */
}


void ReadEncoders(void *pvParameters){
  for(;;) {
    RotaryEncoder::Read();
    // do something…
    delay(1000); // it spins like crazy without delay because so many interrupts are comming
  } 
}

void RotaryEncoder::Read() {
    if (m_semaphore == nullptr) {
        return;
    }
    if(xSemaphoreTake(m_semaphore, portMAX_DELAY) == pdTRUE) {
        Serial.printf("Encoders semaphore taken - counter = %d\n", s_counter); 
    }
}
Last edited by arek21 on Tue Aug 30, 2022 10:35 pm, edited 1 time in total.

User avatar
arek21
 
Posts: 17
Joined: Tue Oct 06, 2020 12:24 am

Re: Rotary Encoder interrupts issue

Post by arek21 »

No idea why in code above it shows m_semaphore = banned();
It should be:
SemaphoreHandle_t m_semaphore = BANNED();
And it shows correctly in edit mode

Ok, here it also shows banned, hmm...
it should say: x Semaphore Create Binary;
No spaces of course :-)

User avatar
adafruit_support_carter
 
Posts: 29056
Joined: Tue Nov 29, 2016 2:45 pm

Re: Rotary Encoder interrupts issue

Post by adafruit_support_carter »

Code: Select all

    pinMode(pinGPIOFrequency, INPUT);
Try enabling internal pull ups here.

User avatar
arek21
 
Posts: 17
Joined: Tue Oct 06, 2020 12:24 am

Re: Rotary Encoder interrupts issue

Post by arek21 »

It is enabled

Part of the fragment of code in original post:

Code: Select all

// somwhere in code
    uint8_t pinGPIOFrequency = 34;
    pinMode(pinGPIOFrequency, INPUT);
    attachInterrupt(pinGPIOFrequency, OnChange, FALLING);

User avatar
arek21
 
Posts: 17
Joined: Tue Oct 06, 2020 12:24 am

Re: Rotary Encoder interrupts issue

Post by arek21 »

Didn't mention it but now I think this may be important.
I have 'Adalogger FeatherWing - RTC + SD Add-on' on top of ESP32 feather.
Is it possible it writes something to this pin?
I thought only pins that are used by it are actually connected to vias on edges.

User avatar
adafruit_support_carter
 
Posts: 29056
Joined: Tue Nov 29, 2016 2:45 pm

Re: Rotary Encoder interrupts issue

Post by adafruit_support_carter »

INPUT only configures the pin as an input, it does nothing with regard to internal pull ups. To configure input and enable internal pull ups, use INPUT_PULLUP.

It's possible the input is floating without any form of pull up resistors when using just INPUT. That'd make the reading essentially noise when not asserted to a known state. The noise would lead to numerous random firings of the ISR.

The Adalogger FeatherWing pinouts are here:
https://learn.adafruit.com/adafruit-ada ... ng/pinouts
The Feather ESP32 V2 pintouts are here:
https://learn.adafruit.com/adafruit-esp ... v2/pinouts

34 is the pin labeled A2 on the Feather. Nothing on the Adalogger FeatherWing uses that pin.

User avatar
arek21
 
Posts: 17
Joined: Tue Oct 06, 2020 12:24 am

Re: Rotary Encoder interrupts issue

Post by arek21 »

Changed to pinMode(pinGPIOFrequency, INPUT_PULLUP);
Still lots of interrupts is coming without touching rotary.

Looks like it has nothing to do with rotary
I disconnected I2C cable from ESP32 and interrupts are still coming.
Then I took off Adalogger feather and without it they stop.

I connected INT pin from rotary directly to pin 34 on ESP32 board and it works as supposed to!
I get interrupt only when I turn rotary or push its button.

Need to take closer look at this Adalogger.

User avatar
arek21
 
Posts: 17
Joined: Tue Oct 06, 2020 12:24 am

Re: Rotary Encoder interrupts issue

Post by arek21 »

Just want to confirm, on Adalogger each pair of vias at the edge is connected together and ones that are not used by Adalogger are not connected anywhere else. Is that true?

User avatar
adafruit_support_carter
 
Posts: 29056
Joined: Tue Nov 29, 2016 2:45 pm

Re: Rotary Encoder interrupts issue

Post by adafruit_support_carter »

Do you mean the two rows of header pads? If so, then yes. The schematic and fab print can help verify this:
https://learn.adafruit.com/adafruit-ada ... /downloads

User avatar
arek21
 
Posts: 17
Joined: Tue Oct 06, 2020 12:24 am

Re: Rotary Encoder interrupts issue

Post by arek21 »

Yes, that's what I thought.
I'm going away for about week but when I'm back I will try figuring out where this pin is getting input from.

User avatar
arek21
 
Posts: 17
Joined: Tue Oct 06, 2020 12:24 am

Re: Rotary Encoder interrupts issue

Post by arek21 »

I'm back. Reassembled everything, resoldered INT wires, checked all connections.
Rotary interrupts work fine until I connect Adalogger.
With Adalogger on top of ESP32 board interrupts are coming in thousands.

I don't have any more ideas :-(

User avatar
arek21
 
Posts: 17
Joined: Tue Oct 06, 2020 12:24 am

Re: Rotary Encoder interrupts issue

Post by arek21 »

Seems like something is messed up with code.
Apparently it has nothing to do with Adalogger.
Seems to happen randomly even without it, just seems less often.
I created new project and started moving stuff piece by piece beginning with rotary encoder and its interrupts.
So far it works with exactly same code related to rotary.
Not everything is moved yet, hopefully it will stay working.
I will update if I find what it was.

User avatar
arek21
 
Posts: 17
Joined: Tue Oct 06, 2020 12:24 am

Re: Rotary Encoder interrupts issue

Post by arek21 »

Ok, good news and worse news :-)

Interrupts are ok until I initialize Bluetooth.
As soon as I call from code BLEDevice::init() I start receiving fake interrupts.
Not that many now, like 1-2 every second.
In original code I was sending sensors data, now I still didn't move everything and I have just basic setup of BLE. Nothing is being send.

Any idea what can be done with it.
I believe it should not be using pins I have for interrupt in any way (GPIO 34 & 39)

Is this interference from radio?
Can I shield something? I'm using feather with external antenna.

EDIT: I see I'm not a first with this problem
https://github.com/espressif/esp-idf/issues/5967

User avatar
arek21
 
Posts: 17
Joined: Tue Oct 06, 2020 12:24 am

Re: Rotary Encoder interrupts issue

Post by arek21 »

Seems like BLE is somehow using these pins (34, 39), changed to pins 14 and 15 and it works as expected.
Hopefully it will stay that way.

Locked
Please be positive and constructive with your questions and comments.

Return to “Other Products from Adafruit”