Dynamic lambdas pass to attachInterrupt

tanmanh0707
Posts: 18
Joined: Fri Jun 23, 2023 3:26 am

Dynamic lambdas pass to attachInterrupt

Postby tanmanh0707 » Sat Nov 30, 2024 2:40 am

Hello,

I would like to have a common function that receives any PIN number as argument, then create a common ISR using attachInterrupt on that pin.

I decided to use lambda for dynamic purpose. However, I got stucked at how to pass the pin number to callback function.

For more details, please see the code below, function LocalRegisterButton, I would like to simplize that function so that I can call attachInterrupt on any pin input.

Currently I cannot do that because attachInterrupt does not accept a captured-by-value lambda. In the code, you can see line 18 where lambda starts. I want to refactor that code to utilize pin variable.

Any tries, you can test your code on my Wokwi project for this code here:

https://wokwi.com/projects/415904203034773505

Thank you.

Code: Select all

static uint8_t _pin_pressed = 0;

void btnRisingIsrHandler(uint8_t btn_pin)
{
  _pin_pressed = btn_pin;
  /* Do other stuff for specific pin */
}

void LocalRegisterButton(uint8_t pin)
{
  /* I would like to simplize this function based on *pin* variable */
  pinMode(pin, INPUT_PULLUP);
  
  switch ( pin )
  {
    case 4:
      attachInterrupt(4,
        /* Lambda start */
        []() IRAM_ATTR {
          /* The problem is that I must hard-code the number 4 here */
          /* I want to use *pin* variable to remove "case 5:" below */
          btnRisingIsrHandler(4);
        }
        /* Lambda end */
        ,
        RISING);
    break;

    case 5:
      attachInterrupt(5, []() IRAM_ATTR {
          btnRisingIsrHandler(5);
        },
        RISING);
    break;

    /* Other cases for all possible PIN numbers */
  }

}

void setup() {
  Serial.begin(115200);
  Serial.println("Hello, ESP32-S3!");
  LocalRegisterButton( 4 );
  LocalRegisterButton( 5 );
}

void loop() {
  if (_pin_pressed > 0) {
    Serial.printf("Pin pressed: %d\n", _pin_pressed);
    _pin_pressed = 0;
  }

  delay(10); // this speeds up the simulation
}

lbernstone
Posts: 858
Joined: Mon Jul 22, 2019 3:20 pm

Re: Dynamic lambdas pass to attachInterrupt

Postby lbernstone » Sat Nov 30, 2024 4:55 pm

I'm not sure a lambda really lends itself to making an ISR. The interrupt has to be attached to each pin you would want a response from, so you will have to call attachInterrupt multiple times in any case, which would mean multiple copies of the function resident in memory. Maybe you just want to functionalize it? I think using a lambda would end up looking almost exactly like a std::bind, but requires you to think a lot more about which variable goes where in the here-now structures.

tanmanh0707
Posts: 18
Joined: Fri Jun 23, 2023 3:26 am

Re: Dynamic lambdas pass to attachInterrupt

Postby tanmanh0707 » Sun Dec 01, 2024 6:44 am

lbernstone wrote:
Sat Nov 30, 2024 4:55 pm
I'm not sure a lambda really lends itself to making an ISR. The interrupt has to be attached to each pin you would want a response from, so you will have to call attachInterrupt multiple times in any case, which would mean multiple copies of the function resident in memory. Maybe you just want to functionalize it? I think using a lambda would end up looking almost exactly like a std::bind, but requires you to think a lot more about which variable goes where in the here-now structures.

Code: Select all

attachInterruptArg
is exact what I am looking for for days. I have not known about this function before. Thank you very very much for your suggestion. Have a nice weekend!

lbernstone
Posts: 858
Joined: Mon Jul 22, 2019 3:20 pm

Re: Dynamic lambdas pass to attachInterrupt

Postby lbernstone » Sun Dec 01, 2024 7:19 pm

:+1:

Who is online

Users browsing this forum: No registered users and 29 guests