Page 1 of 2

Problem with interrupt callback being called all the time without button being pressed

Posted: Thu Oct 29, 2020 7:20 pm
by solarjoe
Hello all,

I have a strange problem and hope that you have some ideas.

Hardware is a ESP32-PICO D4 in a M5Stack Atom Lite.

My first program to test interrupts in general works like a charm, it changes the color
of the LED when the button is pressed. There are not bounces, color skips or
what ever.

The second program is supposed to send a MQTT message when certain events occur.
This also works fine.

Now I wanted to combine the two and also trigger a MQTT message when the button is pressed.

But the result is completely messed up. For whatever reason, the callback function fires
all the time after reboot without the button ever being touched.

When I wanted to check if the first program, with the color LED, still works I got
the same behaviour there: right from the reboot the LED colors start to cycle
without the button being pressed.

So I erased and flashed the firmware again. Same behaviour. LED color cycle works at first, once
I upload and run the MQTT program the IRQ gets messed up and stays that way.

I found this viewtopic.php?t=8655#p48904
Two possible reasons for that:
a) bouncing of the input signal, if that comes from a switch. There are lots of discussions in this forum about de-bouncing.
b) false triggers due to slow slope of the input signal. That happens with the ESP32. Either increase the slope of the signal, or use the de-bouncing method.
but I don't think that's the issue in my case.

Any ideas what could cause this?

Re: Problem with interrupt callback being called all the time without button being pressed

Posted: Thu Oct 29, 2020 8:36 pm
by Roberthh
I do not know how you implement the pull-up for the switch, but it may be worth a trial to add an external pull-up resistors AND a small cap (~10 nF) between switch input and GND. Which GPIO pin do you use for the switch?

Re: Problem with interrupt callback being called all the time without button being pressed

Posted: Thu Oct 29, 2020 9:58 pm
by solarjoe
It's GPIO39 of the ESP32-PICO. The pull-up for the switch is just done

Code: Select all

pin = machine.Pin(39, machine.Pin.IN, machine.Pin.PULL_UP)
And at least for the build-in button, I think it's not possible to tinker with it.

There is a little schematic at the bottom https://docs.m5stack.com/#/en/core/atom_lite
and links to the datasheet, but I am not very familiar with reading the wiring diagrams.

It's really weird, but the callback seems to be triggered in a rather constant way.
This is a part of the code for debugging:

Code: Select all

last_value_change_ms = time.ticks_ms()

def callback(pin):

    global last_value_change_ms

    t1 = time.ticks_ms()
    dt = time.ticks_diff(t1, last_value_change_ms)

    print('dt', dt)
    if dt > 1000:
        last_value_change_ms = t1
And it prints the same time differences over and over again, down to the millisecond:

Code: Select all

dt 102
dt 205
dt 307
dt 409
dt 512
dt 614
dt 717
dt 819
dt 921
dt 1024
(here is the reset if dt > 1000)
dt 102
dt 205

Re: Problem with interrupt callback being called all the time without button being pressed

Posted: Thu Oct 29, 2020 10:49 pm
by jimmo
Just to make sure I understand:

- Simple program that changes the LED colour on button press -- works totally fine
- Simple program that occasionally sends MQTT messages -- works totally fine
- First program that now sends an MQTT message instead of setting the LED colour -- causes reboots and repeat messages

Thanks

Re: Problem with interrupt callback being called all the time without button being pressed

Posted: Fri Oct 30, 2020 6:56 am
by solarjoe
Simple program that changes the LED colour on button press -- works totally fine
Yes.
Simple program that occasionally sends MQTT messages -- works totally fine
Yes.
First program that now sends an MQTT message instead of setting the LED colour -- causes reboots and repeat messages
No, the MQTT message is the main function of the program. Now I would like to add the LED to show the current status send by MQTT and send another MQTT message if the button is pressed.
Basically it is supposed to be the second program with the few lines of the first integrated. The second program is much more complex. It is supposed to be used for machine surveillance, evaluate the motion sensor and send a MQTT message if the machine is not moving anymore.

Re: Problem with interrupt callback being called all the time without button being pressed

Posted: Fri Oct 30, 2020 7:21 am
by solarjoe
I have more information on this.

I tried another ESP32 dev kit, the M5Stack Atom Matrix, instead of the Atom Lite, but the issue stays the same.
So the hardware is not broken.

The interrupt is defined as

Code: Select all

pin = machine.Pin(39, machine.Pin.IN, machine.Pin.PULL_UP)
trigger_all = Pin.IRQ_FALLING | Pin.IRQ_RISING
pin.irq(trigger=trigger_all, handler=callback)
and I just saw that if the button is pressed and hold the callbacks stop to trigger automatically and
the main loop works as expected, sending the MQTT messages.

If the button is not pressed the callback is called over and over again, but the main loop also
works and sends the MQTT messages.

Re: Problem with interrupt callback being called all the time without button being pressed

Posted: Fri Oct 30, 2020 7:31 am
by solarjoe
I tried if there is a difference when I change the trigger, but there is none

Code: Select all

trigger = Pin.IRQ_FALLING | Pin.IRQ_RISING
trigger = Pin.IRQ_RISING
trigger = Pin.IRQ_FALLING
All show the same behaviour and the automatic triggering of the callback always stops it the button is pressed and hold.

I would have expected that the automatic triggering starts if the button is pressed and hold and stops if it is released in
at least one of the cases above.

Re: Problem with interrupt callback being called all the time without button being pressed

Posted: Fri Oct 30, 2020 7:56 am
by Roberthh
All show the same behaviour and the automatic triggering of the callback always stops it the button is pressed and hold.
The callback is called when the level changes. In your case, IRQ_FALLING should be the right one, with the button connected between input and GND. If the level is stable, then the callback is not called. Holding the button pushed enforces a stable state at the input. Since the callbacks are then not triggered, you have most likely a signal problem at the input. Could be both direct coding or hardware related.
But I guess it is hardware related. The GPIO39 has no internal pull-up, so it is subject to all kinds of interference, like the one coming for the WiFi antenna. So you need an external pull-up. That was the reason for me to suggest a lower impedance pull up resistor (e.g. 1 kOhm) and the capacitor. You may also try to use a different pin for the button.

Re: Problem with interrupt callback being called all the time without button being pressed

Posted: Fri Oct 30, 2020 8:40 am
by solarjoe
Ok, I get it now. You could be onto something.

With the very simple program that cycles the LED color on button press the trigger is IRQ_FALLING,
and that works fine. But there is also no WiFi. That could indeed be the reason. I will dig into this.

Above I mentioned that the timing of the callback is very regular, every 103 ms.
Could that be related to the WiFi?

Is there a reliable way to check for the button press without an interrupt?
I could for example use that counting debouncing method and the
user has to hold the button for a second.

Re: Problem with interrupt callback being called all the time without button being pressed

Posted: Fri Oct 30, 2020 8:50 am
by solarjoe
Ok, now that I know what to search for:

https://github.com/m5stack/M5Stack/issues/52

https://forum.lvgl.io/t/problems-with-i ... twork/2130
Meanwhile I also contacted m5stack support via email, directed them to this post and they told me this:
"…btn read can`t use irq event, must use poll to read btn state.
There is definitely something of an interaction beween button A of the M5Stack and Wifi. If I activate wifi and connect to a hotspot, then the pulse counting hardware counts a short pulse about once a second on button A (gpio 39)
Do not use ISR/IRQs to read buttons with an ESP32!
They are flaky, and there is some interference on the M5Stack implementation with the wifi module (hardware or esp-idf related). Use the pulse counter instead
https://forum.m5stack.com/topic/174/m5- ... -with-wifi
The M5Stack’s hardware (or worse, the underlying ESP32) has an issue. If the wifi is turned on, then pin 39, the gpio linked to button A, gets a very short pulse about every second. Perhaps more if wifi is being used rather than merely being active.