jperkin / node-rpio

Raspberry Pi GPIO library for node.js
858 stars 124 forks source link

Cannot open pin in PWM mode #62

Open amclin opened 6 years ago

amclin commented 6 years ago

On a Raspberry Pi 3 I cannot open pin 35 in PWM mode.

I even tried changing the permissions on /dev/gpiomem so that pi is the owner, not just group membership, but to no avail.

Every time I try to open:

rpio.open(35, rpio.PWM)

I get a permission denied error:

bcm2835_init: Unable to open /dev/mem: Permission denied
/home/pi/laundry/node_modules/rpio/lib/rpio.js:104
    return bindfunc(optarg);
           ^

Error: Could not initialize bcm2835 GPIO library
    at bindcall (/home/pi/laundry/node_modules/rpio/lib/rpio.js:104:9)
    at EventEmitter.rpio.init (/home/pi/laundry/node_modules/rpio/lib/rpio.js:460:2)
    at rpio.open (/home/pi/laundry/node_modules/rpio/lib/rpio.js:470:18)
    at initIndicator (/home/pi/laundry/index.js:139:8)
jperkin commented 6 years ago

Access to PWM requires root access via /dev/mem as the error message says. This is documented, but is there a way I can improve the docs here?

amclin commented 6 years ago

Ok, now that you said that... something finally clicked and I get it.

When I was reading the info about PWM: https://github.com/jperkin/node-rpio#pwm

I didn't make the connection that I had already done an open() previously with default values, and so I didn't make the mental connection with this area of the doc that describes the two different devices: https://github.com/jperkin/node-rpio#gpiomem

Perhaps some troubleshooting tips in the PWM (and presumably i2c) sections that link back to that?

Also common error messages would be really helpful for diagnosing since google searches for "Could not initialize bcm2835 GPIO library" don't provide much help here.

msi-matthew commented 5 years ago

I'm a bit confused by the documentation.

Would a chown in /dev/mem resolve this issue?

I am trying to

// init PWM
const pwmPin = 12
const range = 64
const clockdiv = 64
const dutyCycle = 0.99
const duty = dutyCycle * range
const off = 0

rpio.init({gpiomem: false})
rpio.open(pwmPin, rpio.PWM)
rpio.pwmSetClockDivider(clockdiv)
rpio.pwmSetRange(pwmPin, range)

// do some things then enable PWM
rpio.pwmSetData(pwmPin, duty)
rpio.open(1, rpio.OUTPUT, rpio.LOW)

// do more things then disable PWM
rpio.open(1, rpio.OUTPUT, rpio.HIGH)
rpio.pwmSetData(pwmPin, off)
jperkin commented 5 years ago

It might, but it would be incredibly dangerous, as you would be giving that user full access to the entire host. I wouldn't be surprised if there were additional checks to stop you doing this, nor that by doing so you might cause other problems on the host. Basically if you want to do hardware PWM, you need to be root.

msi-matthew commented 5 years ago

Will you please take a look at this?

Based on what you're saying it seems like running a service as root would resolve this issue.

msi-matthew commented 5 years ago

Update: after a fresh install of Raspbian, the service boots up fine as root.

After creating the service, run systemctl enable nameofservice.