fivdi / epoll

A low-level Node.js binding for the Linux epoll API
MIT License
84 stars 13 forks source link

epoll interrupt handling any more robust now? #33

Closed dkebler closed 5 years ago

dkebler commented 5 years ago

A couple years ago I tried using epoll via this package for interrupt handling and I had a heck of time with none or excessive tripping. I tried all manner of debouncing to no avail. I gave up and started using pigpio which was way more stable and many times did not require any debouncing (for interrupt by physical switch). That code has now been battle tested for two years (I have 64 physical switches connected on 4 mcp23017 chips throwing interrupts via 8 pins on gpio bus).

That's all good but of course pigio library requires pi hardware and the pigioc library. That leaves out all my new groovy sbcs :-(.

Now two years later do you feel using your epoll package (via onoff) for interrupts is any more robust and stable on par with pigio? Were there interrupt issues that you specifically addressed in the last two years?

If so maybe I'll give onoff another shot.
I suppose I'll have to try implementing this anyway as I (and many others) are moving from pi hardware and thus the pigio library.


Do you know of any non epoll ways to monitor linux interrupts on say a rockchip64? I guess this is all a can of worms every sbc having different hardware architecture even if they share the same processor. Seems like a manufacturer should supply a devicetree module for their gpio bus interrupt with some standard software interface API.

fivdi commented 5 years ago

To be honest, I don't have any issues with buttons and debouncing when using onoff. It works well for me. Prior to v3.0.0 onoff had inadequate and undocumented support for debouncing GPIO inputs. onoff v3.0.0 (and higher) comes with a very effective debouncing implementation based on lodash.debounce. onoff v3.0.0 was released in March 2018.

What's important to know about GPIO inputs on the Raspberry Pi is that on some GPIOs the internal pulldown resistors are enabled by default and on other GPIOs the internal pullup resistors are enabled by default. If this isn't taken into account, issues like this one can occur.

Note that the constellation described above with the mcp23017, connected to the Pi via I2C I assume, is very different to connecting buttons directly to the Pi. There is no comparison.

Now two years later do you feel using your epoll package (via onoff) for interrupts is any more robust and stable on par with pigio?

epoll and pigpio were equally robust then and are equally robust now. I don't know how robust and stable your code was at the time.

Do you know of any non epoll ways to monitor linux interrupts on say a rockchip64?

If the goal is to interface with buttons the gpio-button package offers an alternative technique.

fivdi commented 5 years ago

@dkebler I'm going to go ahead and close this issue.

dkebler commented 5 years ago

In a nutshell the rpi gpio pin is set to pulldown, then the mcp interrput pin goes high when tripped by a pin change on mcp chip. Then I reset the mcp chip which brings the mcp interrupt low (connected to rpi gpio) and then I'm ready for another. Not sure where/how in there the rpio interrupt resets but it does at least using pigio. There is nothing in my code for that so I assume when I bring it back low it resets? Maybe that's the difference between pigio and on/off/epoll?

with pigpio I am setting the pullup state for sure on each. I had tried to use on/off but I wasn't able to solve multi firing so tried with epoll directly where I could apply some debouncing and had no luck.

That was all before V3 on/off so I will try that again and be sure to not depend on default pullup state but set it explicitly and use the new built in debouncing. Maybe need to look closer at how epoll interrupt get reset too?

Thx for your input.

fivdi commented 5 years ago

There is nothing in my code for that so I assume when I bring it back low it resets?

I'm afraid not.

In the epoll readme there is a watching buttons example with the following commented line of code:

  // Read GPIO value file. Reading also clears the interrupt.
  fs.readSync(fd, buffer, 0, 1, 0);

onoff will clear the interrupt automatically here if debouncing is used and here if debouncing is not used.

dkebler commented 5 years ago

Ok I gave on/off a try with this 18.04 distro (newer kernel) and a slightly different udev and a small debounce time and it's working (not like before) for my use case. The pins I was using as interrupts were supposed to be pulldowns by default but I set them in config.txt anyway (didn't need devicetree for rpi).

So guess I can say it's more robust!! Thx.

I do suggest maybe in on/off supporting (by passing through) all the options of lodash.debounce not just wait. https://lodash.com/docs/4.17.11#debounce. I just set up a dbopts hash prop and passed them that way.

In my pigipio version I used those to fine tune the debounce. Doesn't look like I will need them but if I did without on/off supporting them I'd have to wrap the callback of .watch in another debounce.