Interrupt problem

Hello,

I have a pair of ESP32-WROOM-32 chips, both are doing the same thing.

I am attempting to use interrupts to detect a button press.

I started with some pretty clean code from LastMinuteEngineers, a straight copy and paste. (Configuring & Handling ESP32 GPIO Interrupts In Arduino IDE)

But I have a problem. As soon as I connect any wire to the interrupt pin, the interrupt fires, constantly. Hundreds of times in a few seconds. To be clear, this is just a floating jumper wire. I tried on both chips and on a few different pins (modifying the code accordingly) and it keeps happening.

Leave nothing connected to the pin, no problem, connect a jumper lead, instant, constant interrupts.

Tried with the chip removed from the prototype board, tried a chip with no pins.

I tried pulling the pin up with an external resistor, but when I do that the interrupt does not fire when I pull the pin down by grounding it.

Can anyone help me figure out what I am doing wrong?

Here is the code from Lastminute, I have also written a couple of versions from scratch, using other sites, all do the same thing.

struct Button {
  const uint8_t PIN;
  volatile uint32_t numberKeyPresses;
  volatile bool pressed;
};

Button button1 = { 18, 0, false };

void IRAM_ATTR isr() {
  button1.numberKeyPresses++;
  button1.pressed = true;
}

void setup() {
  Serial.begin(115200);
  pinMode(button1.PIN, INPUT_PULLUP);
  attachInterrupt(button1.PIN, isr, FALLING);
}

void loop() {
  if (button1.pressed) {
    Serial.printf("Button has been pressed %u times\n", button1.numberKeyPresses);
    button1.pressed = false;
  }
}

Why do you think you need an interrupt for a button press? Inerrupts are for things that must be dealt with quickly, on the speed scale of a microcontroller a button press is about as slooooooooooow as it gets.

I'm using my tablet at the moment, when I turn my PC on I'll give you some links to relevant tutorials, unless someone beats me to it.

The project needs interrupts. Quite a few actually. Global variable changes during program execution.

Human interface stuff.

What is keeping the pin HIGH when the button is not pressed ?

It is very likely that is not the case but without more details it is impossible to say. Typically an interrupt is used to change the value of a variable and that change is detected by the main program loop. What are you planning to do within the interrupts, bearing in mind that interrupts are disabled at that point ?

How many interrupts do you anticipate needing and which Arduino board are you using ?

Can you post a picture of the board you are using, because on a nor mal ESP32(S) , GPIO10 is connected to the flash chip and can not be used.

Please try on a different pin, for instance GPIO 25

Yes, I know, that is why I am using 18, but I also tried 19.

I do need interrupts.

As per my initial post, I tried pulling it high with a resistor. (4.7k)

According to the documentation I am reading, setting the pinMode to pullup does the same thing in the esp32 hardware.

But yes, tried both.

Feels almost like induction in the patch lead is enough to make the pin think it is falling. Which is odd, because I am in a pretty low electrical noise environment. (Offgrid, no mains, no AC induction.)

What is the sketch doing besides reading human input that takes so much time ?

Please answer my questions

I second the point that you likely don't need interrupts, it's more a matter of designing your code so that the loop loops quickly and deals with user input but that's not your question.

A floating or bare wire acts as a tiny antenna, it picks up mains hum and RF noise, which swings the pin voltage across the logic threshold hundreds of times a second. Each crossing fires your FALLING interrupt. This happens on any MCU; it's not your code or your chip although ESP32's internal pull-ups are also quite weak (~45kΩ), so it's easily overpowered by that noise, more so than on boards like an Uno.

Can you share exactly how you wired the external pull-up like resistor value, and which two points it connects (pin to 3.3V, and pin to the switch/GND)? Also, how are you grounding the pin to test — a solid jumper into a GND rail, or touching a bare wire by hand?

PS:
to @UKHeliBob

this is a different discussion than OP's question. a valid one, but still not the ask. I don't think we should divert the conversation until we answer his initial question.

As promised, here are some tutorials relevant to button presses.

You keep asserting that you need interrupts, but have not said why you think this. Please explain.

Sorry mate, too big to explain the project here.

It needs interrupts.

I tried a 4.7k ohm resistor between the 3.3v pin and pin 18. Then I grounded pin 18 using a good quality momentary push button.

That SHOULD have worked. Got me scratching my head, tried it on 19 too.

As also noted, I am actually in a super low electrical noise environment. Off grid, mostly DC, no major AC sources or loads anywhere nearby.

I do need interrupts. Really.

Respectfully, I don't need to explain. Please just accept that I do know I need them.

I came here for help with the interrupt problem I described. I am hoping someone has seen it before, or knows if it is maybe an issue with the chipset I am using.

Hmmm... seems someone else ran into difficulty. I missed this one. Digging through the resistors now to see if I can find a 220 ohm resistor. A much harder pull high. I can't see how it would help, but I am going to try.

OK, well, I shall leave you with your project. Good luck.

18 and 19 are VSPI, not sure if this is an issue.

if you run this with your button setup

constexpr uint8_t buttonPin = 18;

int lastState;

void setup() {
  Serial.begin(115200);
  pinMode(buttonPin, INPUT_PULLUP);
  lastState = digitalRead(buttonPin);
}

void loop() {
  int state = digitalRead(buttonPin);
  if (state != lastState) {
    Serial.printf("%lu ms: pin = %s\n", millis(), state == HIGH ? "HIGH" : "LOW");
    lastState = state;
  }
}

does it behave as it should ? (including possible bounces)

I will give that code a try and report back.

All the documentation I could find suggested both of those pins were safe, actually, they were recommended. And most of the tutorials seemed to focus on 18.

yes if your sketch has no SPI library involved then it should not matter.

also as you use INPUT_PULLUP, just wire

pin 18 --- button --- GND

and if you use those 4 pins buttons, make sure you wire in diagonal (across the button) so that you don't take the connected pins by mistake.

Interesting result, this happens as soon as I connect the patch lead to the pin...

37897 ms: pin = HIGH
37897 ms: pin = LOW
37901 ms: pin = HIGH
37901 ms: pin = LOW
37901 ms: pin = HIGH
37901 ms: pin = LOW
37901 ms: pin = HIGH
38039 ms: pin = LOW
38039 ms: pin = HIGH
38039 ms: pin = LOW
38039 ms: pin = HIGH
38039 ms: pin = LOW
38040 ms: pin = HIGH
38172 ms: pin = LOW
38172 ms: pin = HIGH
38172 ms: pin = LOW
38172 ms: pin = HIGH
38179 ms: pin = LOW
38179 ms: pin = HIGH
38179 ms: pin = LOW

Etc.

If I ground the patch lead, or connect it to 3.3v, immediately the flow stops.

Time to try some different value pull up resistors I think.

Any recommendations other than the 220 ohm used in the thread I linked above?

Noted.