How to change status of MCP23017 in IRAM_ATTR with ESP32

Hey coders,

I am using ESP32 Development board along with MCP23017 pin Expander and I want to change the status of my relay when user Clicks on touch sensor, for that I am using IRAM_ATTR method, All working fine when I was working with ESP32 GPIO pins but When I code like this

#include <Adafruit_MCP23X17.h>
Adafruit_MCP23X17 mcp;

IRAM_ATTR void button2Touch()
{
  button2_status = !button2_status;
  mcp.digitalWrite(relay2, button2_status);
}

void setup()
{
    attachInterrupt(digitalPinToInterrupt(button2), button2Touch, RISING);
    if (!mcp.begin_I2C()) {
        Serial.println("Error.");
        while (1);
     } else {
        Serial.println("Started.");
     }
     mcp.pinMode(relay2, OUTPUT);
}

I get following error and my board resetting

Guru Meditation Error: Core  1 panic'ed (Interrupt wdt timeout on CPU1)
Core 1 register dump:
PC      : 0x40093dda  PS      : 0x00060234  A0      : 0x80092fcf  A1      : 0x3ffc0240
A2      : 0x3ffbc12c  A3      : 0x3ffcbf98  A4      : 0x00000001  A5      : 0x00000001  
A6      : 0x00060223  A7      : 0x00000000  A8      : 0x3ffcbf98  A9      : 0x3ffcbf98  
A10     : 0x00000019  A11     : 0x00000019  A12     : 0x00000001  A13     : 0x00000001
A14     : 0x00060221  A15     : 0x00000000  SAR     : 0x0000000a  EXCCAUSE: 0x00000006
EXCVADDR: 0x00000000  LBEG    : 0x4000c2e0  LEND    : 0x4000c2f6  LCOUNT  : 0x00000000  
Core 1 was running in ISR context:
EPC1    : 0x400e6eb4  EPC2    : 0x00000000  EPC3    : 0x00000000  EPC4    : 0x40093dda

ELF file SHA256: 0000000000000000

Backtrace: 0x40093dda:0x3ffc0240 0x40092fcc:0x3ffc0260 0x40091273:0x3ffc0280 0x400912e1:0x3ffc02c0 0x400e761f:0x3ffc02e0 0x400e7906:0x3ffc0310 0x400d3ee9:0x3ffc0330 0x400d3f9d:0x3ffc0360 0x400d400d:0x3ffc0390 0x401edba9:0x3ffc03b0 0x401edbf6:0x3ffc03d0 0x401edc27:0x3ffc03f0 0x401ed9e5:0x3ffc0410 0x401eda49:0x3ffc0440 0x401eda86:0x3ffc0460 0x400d41dd:0x3ffc0480 0x400810e1:0x3ffc04e0 0x400811a9:0x3ffc0500 0x4008e74d:0x3ffc0520 0x402089db:0x3ffcbe80 0x401d1beb:0x3ffcbea0 0x40092c5d:0x3ffcbec0 0x4009149e:0x3ffcbee0

Core 0 register dump:
PC      : 0x400924bd  PS      : 0x00060034  A0      : 0x80092c95  A1      : 0x3ffbfea0
A2      : 0x3ffbf908  A3      : 0x0000cdcd  A4      : 0xb33fffff  A5      : 0x00000001  
A6      : 0x00060021  A7      : 0x0000abab  A8      : 0x0000abab  A9      : 0x3ffca740
A10     : 0x00000003  A11     : 0x00060023  A12     : 0x00060021  A13     : 0x3ffbd124  
A14     : 0x0000002a  A15     : 0x3ffd18a0  SAR     : 0x00000018  EXCCAUSE: 0x00000006
EXCVADDR: 0x00000000  LBEG    : 0x00000000  LEND    : 0x00000000  LCOUNT  : 0x00000000  

ELF file SHA256: 0000000000000000

Backtrace: 0x400924bd:0x3ffbfea0 0x40092c92:0x3ffbfed0 0x4009158b:0x3ffbfef0 0x40093c5d:0x3ffbff10 0x4008e756:0x3ffbff20 0x402089db:0x3ffbd7a0 0x401d1beb:0x3ffbd7c0 0x40092c5d:0x3ffbd7e0 0x4009149e:0x3ffbd800

Rebooting...

Actually I want an instant reflection on relay status as soon as user clicks on button, and in my code my loop taking some time that's why If I write my digitalwrite code in loop its take some time, so does any one know how to solve this?? Please help me.

Don't.
Firstly, you're switching a relay. There's absolutely no necessity whatsoever to do that from an ISR given the relatively low speed at which relays switch to begin with.
Secondly, you're doing I2C communications from inside an ISR which should never, ever be done, in particular not on an ESP platform - as you have found out. I2C is waaaay too slow to be run from an ISR; handling a full I2C transaction easily takes several milliseconds; an ISR should be kept as short as a couple of dozen microseconds at most.

Just poll the button from your loop() and then set your relay.
If you must absolutely use an interrupt (which you don't, but OK), then only use the ISR to set a flag/boolean and then use that in your loop() to set the relay.

try

void IRAM_ATTR button2Touch()

An interrupt is not needed in this case but learning new things cool.

the minimum is to post your complete sketch. Already from the few things you have described I can conclude that you have some mis-conceptions and gaps in your knowledge that just asking for some details will not lead to the solution.

Be the change you want to see in the world
best regards Stefan

Thank you for your reply, As you said I2C is too slow to run from ISR and that's why It's throwing error, but as I said earlier My loop is slow actually I am checking continuously for Internet by ping that's why My loop takes some delay about 1-2 second and that is what I am trying to avoid, so there is any way to do this or I have no any option except looping??

Then which is a best way to do?? My loop has 1-2 sec delay that's why It's took 1-2 sec for response

So make it faster.

Maybe don't? How often do you really need to ping a web server for updates? What is the acceptable delay between new data appearing on the server and your ESP responding?

It might help if you posted your full sketch so we can pinpoint where unnecessary delays etc. are.

Thanks for your reply, but I know how to create a post and you know what sometimes it doesn't matter, sorry I am being rude but It's fact, rather than pointing on others knowledge try helping them, I would be happy if you could solve my problem.

I haven't posted my entire code just because I have multiple packages included and there are so many lines in it, So rather than posting entire code I just point outed the main code where I am getting error, so normal coder can easily understand and advice me for what's I am doing wrong.

Actually I am using a Firebase library for web server and there I have created a listener which is continuously listening database values, but I found that when board goes offline and if user performs a query then It's acting weird and end up with an error that's why I am pinging and checking for there is internet or not and that's procedure consuming time.

less information more wild guessings:
Ping your ISP instead of google
send an UDP-heartbeat from the other side to check if internet is online
use the second core for this checking
use another ESP32 for checking

Ok, so you had a problem, you patched it up and created a new problem in the process and now that bites you. So perhaps go back to the first problem and try to tackle that.

my one core is busy on listener and I am using this address for ping httpbin.org

Yes but I can't do anything with library that's why I tried this way

if(Ping.ping("www.google.com", 1)) {

          if(updateData()) {

            isFromBoard = false;

            offline = false;

          }

        }

I am doing something like this in my code and that's why It's taking time

Like I said, I think there's probably another and better way to keep your program working even under difficult connection conditions, but it's impossible to recommend a solution for an invisible situation. So somehow posting your sketch is really necessary.

Okay then I'll do some changes and then after Share the github link with you.

You have working code? Post#1 you did not have working code.

Then in post#7 you are stating your code runs slow. If you have working code that runs slow, post it. Otherwise I thought we were still working to fix your ESP32 Exception.

Sorry for late reply, I was busy in my examination,

Here is my entire code: GitHub - jaydip-pawar/Smartify-Board

I found following bugs:

  1. After Pressing the touch sensor, It turns the relay in/off in 1-2 sec, sometimes It takes 5-6 sec also
  2. Sometime After pressing touch sensor, nothing happen!

If I found a solution for setting interrupt on MCP23017 pins then It might solve all this issues cuz then I can use digitalWrite method in I2C.

@Idahowalker @StefanL38 @anon35827816