1

Short story: How do I pass parameters to callback functions in Lua?

Long story:

I'm working on an ESP8266 with the NodeMCU firmware. Essentially I intend to build a dash button, just with multiple buttons per node. I'm doing this with the interrupt possibility of the GPIO pins.

However how to pass parameters to the callback function doesn't seem to be well documented. In my case I want to know for which pin the interrupt came. This is what I came up with. It is working except for the value of the pin, that seems to reset to the initialization value of 1 when triggered.

  -- Have an area to hold all pins to query (in testing only one)

  buttonPins = { 5 }
  direction="up"

  armAllButtons()

  function armAllButtons()
    for i,v in ipairs(buttonPins)
    do
        armButton(v)
    end
  end


  function armButton(buttonPin)
    print("Arming pin "..buttonPin.." for button presses.")

    gpio.mode(buttonPin,gpio.INT,gpio.FLOAT)
    gpio.trig(buttonPin, direction, function (buttonPin) notifyButtonPressed(buttonPin) end)

    print("Waiting for button press on "..buttonPin.."...")
  end

  function notifyButtonPressed(buttonPin)
    print("Button at pin "..buttonPin.." pressed.")

    --rearm the pins for interrupts
    armButton(buttonPin)
  end

However from within the notifyButtonPressed() function, the value of buttonPin is always 1 when pressed, not 5 as I would expect it to be. I'd assume that's probably the initialization value of number variables.

5
  • How is buttonPinPressed set to 1? Commented Jan 6, 2017 at 11:28
  • Sorry, that was a mistake in posting only. I changed the code. The var is buttonPin, not buttonPinPressed. Problem still persists though. And sorry for the formatting, was changing it in parallel when you were. Commented Jan 6, 2017 at 11:34
  • 1
    Change function (buttonPin) notifyButtonPressed(buttonPin) end to function () notifyButtonPressed(buttonPin) end Commented Jan 6, 2017 at 11:38
  • Damn, you're right, that did it: dofile("button.lua") Arming pin 5 for button presses. Waiting for button press on 5... > Button at pin 5 pressed. Arming pin 5 for button presses. Waiting for button press on 5... Button at pin 5 pressed. Arming pin 5 for button presses. Waiting for button press on 5... How can I mark your comment as an answer? Commented Jan 6, 2017 at 12:16
  • "How can I mark your comment as an answer?" - you can't, you can only flag it as useful. Commented Jan 7, 2017 at 13:26

1 Answer 1

1

First of all, your code does not run at all... As is, it will throw an

input:6: attempt to call a nil value (global 'armAllButtons')

After I rearranged your snippet as this:

  buttonPins = { 5 }
  direction="up"

  function armButton(buttonPin)
    print("Arming pin "..buttonPin.." for button presses.")

    gpio.mode(buttonPin,gpio.INT,gpio.FLOAT)
    gpio.trig(buttonPin, direction, function (buttonPin) --notifyButtonPressed(buttonPin) end)

    print("Waiting for button press on "..buttonPin.."...")
  end

  function notifyButtonPressed(buttonPin)
    print("Button at pin "..buttonPin.." pressed.")

    --rearm the pins for interrupts
    armButton(buttonPin)
  end

  function armAllButtons()
    for i,v in ipairs(buttonPins)
    do
        armButton(v)
    end
  end

armAllButtons()

it outputs:

Arming pin 5 for button presses.
Waiting for button press on 5...

For your callback work perfectly, you must pass a different function for each button, and not attempt to pass arguments to the functions... try this:

  buttonPins = { 5 }
  direction="up"

  function armButton(buttonPin)
    print("Arming pin "..buttonPin.." for button presses.")

    gpio.mode(buttonPin,gpio.INT,gpio.FLOAT)
    gpio.trig(
      buttonPin, 
      direction, 
      function ()
        notifyButtonPressed(buttonPin) 
      end
    ) -- this should create a function for each button, and each function shall pass a different argument to notifyButtonPressed

    print("Waiting for button press on "..buttonPin.."...")
  end

  function notifyButtonPressed(buttonPin)
    print("Button at pin "..buttonPin.." pressed.")

    --rearm the pins for interrupts
    armButton(buttonPin)
  end

  function armAllButtons()
    for i,v in ipairs(buttonPins)
    do
        armButton(v)
    end
  end

armAllButtons()
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.