0

I am trying to run a program using GPIO from a normal user. I checked that /dev/gpiomem has the correct permission (root:gpio 0660) and that my user is member of group gpio.

The following works correctly:

import RPi.GPIO as GPIO
from time import sleep

try:
    pin = 21
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(pin, GPIO.IN)

    while True:
        pin_value = GPIO.input(pin)
        print("Pin {} has value {}".format(pin, pin_value))
        sleep(1)
finally:
    GPIO.cleanup()

When I press a button attached to pin 21 it does indeed show 1, and 0 otherwise. I run this as a standard user, so I guess it uses /dev/gpiomem (and indeed it failed before I fixed its permissions).

However, if I try to set an event on such pin

import RPi.GPIO as GPIO
from time import sleep

try:
    pin = 21
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(pin, GPIO.IN)

    GPIO.add_event_detect(pin, GPIO.RISING)
    GPIO.add_event_callback(pin, lambda _: print("Pin {} was pressed".format(pin)))

    while True:
        pass
finally:
    GPIO.cleanup()

it raises the following exception:

Traceback (most recent call last):
  File "tst.py", line 9, in <module>
    GPIO.add_event_detect(pin, GPIO.RISING)
RuntimeError: Failed to add edge detection

Everything works fine using root, but I want to run this program as a standard user. Kernel is 4.14.37 and RPi.GPIO is 0.6.3. I am using a RPi 2.

It seems that adding an event on a pin still requires being root. Am I right? Am I doing anything wrong? How else could I detect a pin rising as a standard user?

2
  • 1
    Dunno but as a guess it could be using the /sys/gpio interface to poll rising/falling events...
    – goldilocks
    Commented Apr 28, 2018 at 13:24
  • Polling is not an option. I can check if an edge is detected only once every couple seconds, I would most certainly miss it if I used polling.
    – Claudio
    Commented Apr 29, 2018 at 9:18

3 Answers 3

2

I'm not sure what is going wrong. My Python knowledge is sketchy.

I'd dump the lambda and try the following (which works for me).

#!/usr/bin/env python

import RPi.GPIO as GPIO
import time

def callback(pin): 
   print("Pin {} was pressed".format(pin))

try:
    pin = 21
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(pin, GPIO.IN)

    GPIO.add_event_detect(pin, GPIO.RISING, callback)

    while True:
        time.sleep(60)
finally:
    GPIO.cleanup()
2
  • This is completely equivalent, and, besides, the exception is raised before I even define the lambda. Moreover, that code works as root.
    – Claudio
    Commented Apr 29, 2018 at 9:15
  • @Claudio The code I posted works as the pi user.
    – joan
    Commented Apr 29, 2018 at 9:44
1

I just changed the GPIO setup and it works for me (remote connection to rpi over ssh). This is my complete code. I added the pullup, changed the pin to 12 and because I was lazy used the setmode GPIO.BOARD because I just had the pin number. The shebang line does not influence, BUT I have to use python3 (3.7.3) to start the code since python (2.7.16) does return SyntaxError: invalid syntax with the line

GPIO.add_event_callback(pin, lambda _: print("Pin {} was pressed".format(pin)))

Here is my code that works. I start it with python3 main.py from the folder.

#!/usr/bin/python3
# -*- coding: utf-8 -*-

import RPi.GPIO as GPIO

try:
    pin = 12
    GPIO.setmode(GPIO.BOARD)
    GPIO.setup(pin, GPIO.IN, pull_up_down=GPIO.PUD_UP)

    GPIO.add_event_detect(pin, GPIO.RISING)
    GPIO.add_event_callback(pin, lambda _: print("Pin {} was pressed".format(pin)))

    while True:
        pass
finally:
    GPIO.cleanup()
0

Unfortunately, to interface with the GPIO pins, it is required that you use sudo. This is because it is a component that directly controls the Pi's electronics, and it is usually safer to only allow administrators to use those components, especially because they want to make it idiotproof in case it is used as a public computer.

So, the only way your program can work is like this: sudo python filename.py

Of course, you could use an extra component or a microcontroller to send the information wirelessly, but that would be annoying, so unless you want to do that, I would just use sudo.

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.