JamesBarwell / rpi-gpio.js

Control Raspberry Pi GPIO pins with node.js
MIT License
657 stars 116 forks source link

Add retry to fix permission error in call to listen() #112

Open smagoun opened 3 years ago

smagoun commented 3 years ago

Fixes #111

autr commented 3 years ago

Hello, I'm also experiencing this bug quite badly on the Pi Zero v1.3 (not W) where I think it is the same problem with a race condition / slower threading. At the moment various pins never fully bind to EPoll / trigger a state change. My temporary solution was to just write unexport, export and direction a second time to /sys/class/gpio after the initial binding, which makes sure the pins report back their state:

    for (let i = 0; i < PINS.length; i++){
        let PIN = PINS[i]
        console.log(`[o-dsk] refreshing pin ${PIN}`)
        let cmds = {
            unexport: `echo ${PIN} > /sys/class/gpio/unexport`,
            export: `echo ${PIN} > /sys/class/gpio/export`,
            direction: `echo in > /sys/class/gpio/gpio${PIN}/direction`
        }
        try { await execSync( cmds.unexport ) } catch(err) { console.error('[o-dsk]', err.message) }
        try { await execSync( cmds.export ) } catch(err) { console.error('[o-dsk]', err.message) }
        try { await execSync( cmds.direction ) } catch(err) { console.error('[o-dsk]', err.message) }
    }

I'm thinking it could benefit to rewrite this lib as asynchronous and also add in optional setup args for delays between calls, something like this:

const wait = async ms => ( new Promise(resolve => setTimeout(resolve, ms) ) )

const someSetupFunc = args => {
    await bindSomething( args )
    await wait( 100 )
    await bindSomethingElse()
}

What do you think?