54

I've made a python script using the RPi.GPIO library. I need to run it without root but I get this error when running it with "python ./script.py":

No access to /dev/mem. Try running as root!

I've read in many places that you no longer need root with the latest version of the library but I still get the error after updating. The version I have is RPi.GPIO 0.6.0a3

Here is the code:

import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(18,GPIO.OUT)
print "LED on"
GPIO.output(18,GPIO.HIGH)
time.sleep(1)
print "LED off"
GPIO.output(18,GPIO.LOW)

And the full error:

pi@raspberrypi ~/Desktop/python $ python ./sensors.py
Traceback (most recent call last):
  File "./sensors.py", line 5, in <module>
    GPIO.setup(18,GPIO.OUT)
RuntimeError: No access to /dev/mem.  Try running as root!

When I run it as root it works.

JoeyCK
  • 718
  • 1
  • 5
  • 10
  • sudo adduser my_new_user gpio is correct but remember to log out and back in because updating group membership requires re-login to become active. – Blindfreddy Oct 08 '19 at 22:26

10 Answers10

65

You probably need to be running Raspbian to use RPi.GPIO as a non-root user, possibly it needs to be jessie as well.

Does /dev/gpiomem exist? If so RPi.GPIO should use this device to access the GPIO. If /dev/gpiomem does not exist try:

sudo rpi-update

to make sure you are using a recent kernel, and

sudo apt-get update
sudo apt-get upgrade

to make sure you are using a recent RPi.GPIO.

You will also need to make sure you are a member of the gpio group:

sudo adduser pi gpio

EDITED TO ADD

The Raspbian system appears to be in a state of flux. I'm not sure if it's a Raspbian or (more likely) a raspberrypi.org problem.

Check that /dev/gpiomem has the correct permissions.

$ ls -l /dev/gpiomem
crw-rw---- 1 root gpio 244, 0 Dec 28 22:51 /dev/gpiomem

If it doesn't then set the correct permissions as follows

sudo chown root.gpio /dev/gpiomem
sudo chmod g+rw /dev/gpiomem
joan
  • 71,024
  • 5
  • 73
  • 106
  • 6
    Still not working. Everything is updated, /dev/gpiomem exists and when I try to add the user to the gpio group it says it's already a member – JoeyCK Dec 28 '15 at 00:06
  • 6
    @JoeyCK: note that changing group membership doesn't affect processes that were already running. Run id to list your shell's current groups, and if gpio isn't listed, log in again, or reboot. – deltab Dec 28 '15 at 03:57
  • @JoeyCK What version is reported by RPi.GPIO? – joan Dec 28 '15 at 09:00
  • @joan version 0.5.11 – JoeyCK Dec 28 '15 at 14:22
  • @deltab gpio is listed when I run id and I have rebooted several times. – JoeyCK Dec 28 '15 at 14:35
  • @JoeyCK RPi.GPIO is part of the foundation Raspbian image and shows version '0.6.0a3' on my jessie system. You seem to be stuck at an old version. It may be something to do with the way you installed the module. Did you use pip? Try uninstalling with pip (I don't how how, I don't use pip) and then sudo apt-get install RPi.GPIO. – joan Dec 28 '15 at 14:47
  • @joan I didn't use pip. It came with Raspbian. I'm using the old wheezy. sudo apt-get install RPi.GPIO downloads the old version again (0.5.11). I suppose the easiest would be to upgrade to jessie right? – JoeyCK Dec 28 '15 at 15:09
  • @JoeyCK That does appear to be the problem. It looks like you do need to be using jessie. Make sure you have safe copies of any important changes before trying an upgrade on an existing SD card. Alternatively write the current Raspbian jessie image to a fresh SD card. – joan Dec 28 '15 at 15:17
  • @joan after 2 hours I have managed to update to jessie. However I still get the same error message even though I have version 0.6.0a3 and user pi is in the gpio group – JoeyCK Dec 29 '15 at 09:07
  • Could you post your script? If it's more than a couple of hundred lines consider cutting it down to a minimum version which demonstrates the problem. – joan Dec 29 '15 at 09:14
  • @joan The code is very long but I have added a simple example in the original post which also fails to run. – JoeyCK Dec 29 '15 at 12:59
  • Oh dear, you are quite right. Somewhere along the line the Raspbian permissions have been screwed up. The permissions for /dev/gpiomem are incorrect. Try again after entering the following commands. sudo chown root.gpio /dev/gpiomem and sudo chmod g+rw /dev/gpiomem. – joan Dec 29 '15 at 13:56
  • Thank you so much! this worked! Can you add it to your answer please? – JoeyCK Dec 29 '15 at 14:11
  • I shall do but it's only a patch at best. Hopefully it will be fixed in a software update. – joan Dec 29 '15 at 14:25
  • I've spotted that on my raspberry pi running ubuntu mate, after restarting the system it's reverted the permission changes. Should I expect to reset those configuration after each reboot? Or should I consider migrating to Raspbian? –  Mar 24 '16 at 10:16
  • 1
    @mjwittering Raspbian will invariably be better supported on the Pi. If you prefer Ubuntu you'll need to apply the changes each boot. You could do it automatically with a boot script or a reboot entry in a crontab. – joan Mar 24 '16 at 10:25
  • It seems that the only required action for default user 'pi' on Linux RaspberryPi 4.9.59-v7+ is sudo adduser pi gpio – ololobus Feb 09 '18 at 21:16
  • It worked like a charm in Ubuntu Core. Linux-4.15.0-1049-raspi2-aarch64-with-Ubuntu-18.04-bionic – Marcos Nov 12 '19 at 12:07
  • On my pi, /dev/gpiomem was in the group 'dialout'. I added myself to that group with "sudo usermod -G dialout myusername" and now it works. – user1883048 Jan 06 '23 at 13:12
13

I had this issue right away and solved just with this:

sudo adduser my_new_user gpio

With this, the user "my_new_user" is added to the gpio group, so, all the users in the gpio group can access the GPIO pins.

Aurora0001
  • 6,308
  • 3
  • 23
  • 38
6

None of the replies above include all steps. I needed to complete the following steps to get non-root access to the GPIO pins. I had to create a new group, add my user to this group then change permissions (as in the previous posts).

sudo groupadd gpio
sudo usermod -a -G gpio user_name
sudo grep gpio /etc/group
sudo chown root.gpio /dev/gpiomem
sudo chmod g+rw /dev/gpiomem
Mark Tyers
  • 161
  • 1
  • 1
5

I can answer this.

sudo chown root.gpio /dev/mem

This changes the owner and group of /dev/mem to root and gpio respectively.

sudo chmod g+rw /dev/mem

then gives the group read write access to this /dev/mem object.

The /dev/mem object is basically the entire memory space on the system. This means that now the group gpio, and everyone in it, can read and write to the memory space.

Now, in the memory space are many things, including CPU registers. When you toggle GPIO pins, you are changing a bit in one of these registers. The kicker is, you need to be sure you do it correctly or bad bad things can happen to your system.

To help protect the entire memory space, the powers that be mapped just the memory parts that we need to work with the GPIO bits to /dev/gpiomem. This in effect masks/shields the rest of the memory space from being access and only allows the GPIO bits to be accessed. This allows access to the GPIO memory addresses and disallows any other parts of the memory, such as memory currently being used by any other programs.

In effect, this blows a hole in both security and system stability protections to allow access to the GPIO stuff, as well as the rest of the memory, but only to the users in group GPIO, which Pi is a member of.

In the future, drivers such as the bcm2835 library and wiringPi will be updated more (some updates are already happening) and the apps that are built on top of those tools will get further updated and then in the future, hopefully all this GPIO hassle as root will disappear.

Until then you have two choices, open up the /dev/mem to group gpio as read/write, or run as root, which has full read write to all of /dev/mem.

Hope that makes sense.

There are currently still some many issues where you still need to run as root. For example, using the node-red-contrib-dht-sensor module, which depends on the node-dht-sensor, which depends on BCM2835. It seg-faults using /dev/gpiomem as it has some bugs still either in node-dht-sensor or in /dev/gpiomem or the way they are working together. I don't know which is the case, but it will get worked out eventually. When BCM2835 runs as 'non-root' and /dev/gpiomem exists, it tries to use /dev/gpiomem instead of /dev/mem, so opening the /dev/mem to group gpio doesn't help. Bummer.

Karl Easterly
  • 51
  • 1
  • 2
1

Just use the following command in the terminal:

sudo chown root.gpio /dev/mem && sudo chmod g+rw /dev/mem
harkirat1892
  • 119
  • 2
  • 2
    Could you provide an explanation as to what this command does, and why it differs from joan's answer? What is the difference between /dev/mem and /dev/gpiomem? – Greenonline Mar 20 '16 at 00:15
  • If you can it is better to use Joan's answer, however if you can't change /dev/mem to /dev/gpiomem this will get you the same permission to use /dev/mem that you have with /dev/gpiomem – Natim Aug 02 '18 at 14:28
  • It's unsafe to offer access to all of /dev/mem, when a more surgical approach answers the question. – Bryce Dec 18 '18 at 01:53
1

If you're building in geany just change the build commands.

The Java commands to compile should be

sudo pi4j --compile "%f"

and the execute command should be

sudo pi4j --run "%e" 
Brick
  • 1,377
  • 2
  • 13
  • 19
0

I don't know if this is too late, but in Free Pascal I changed

fd := fpopen('/dev/mem', O_RdWr or O_Sync);

to

fd := fpopen('/dev/gpiomem', O_RdWr or O_Sync);

and that solved the problem

I understand that debian allow to use /dev/gpiomem and narrows the access to GPIO memory only, wich is safer.

Now I can run my programs from Lazarus IDE.

Greenonline
  • 2,740
  • 4
  • 23
  • 36
0

When using ubuntu, create the different groups (gpio is the specific for this question):

sudo groupadd -g 123 spi
sudo groupadd -g 124 gpio
sudo groupadd -g 125 i2c

Assign them to your user:

sudo usermod -a -G spi $USER
sudo usermod -a -G gpio $USER
sudo usermod -a -G i2c $USER

And create the file /etc/udev/rules.d/99-com.rules with the content:

SUBSYSTEM=="spidev" , GROUP="spi" , MODE="0660"
KERNEL=="i2c-0"     , GROUP="i2c" , MODE="0660"
KERNEL=="i2c-[1-9]*", GROUP="i2c" , MODE="0660"
KERNEL=="gpiomem"   , GROUP="gpio", MODE="0660"

Test with:

sudo udevadm control --reload-rules && sudo udevadm trigger

And reboot to check that everything is working fine.

imjoseangel
  • 101
  • 1
  • On my machine, this result in: RuntimeError: Failed to add edge detection running my script as root end-up working properly, but this is not what I am looking for. – Tobbey Jan 22 '22 at 17:14
0

ubuntu 23 server on raspberry pi 3b+

Heyo All, this is what I did. Created a script to modify the permissions of /dev/gpiomem and then created a systemd startup script. Here are the contents of both files.

gpio-open.sh

#!/bin/bash

sudo chown root:gpio /dev/gpiomem && sudo chmod g+rw /dev/gpiomem

And the startup file at:

/etc/systemd/system/gpio-open-startup.service

[Unit] Description=gpio-open

After=network.target

After=systemd-user-sessions.service

After=network-online.target

[Service]

User=nickodimus

Type=simple

PIDFile=/run/gpio-open.pid

ExecStart=/home/nickodimus/gpio-open.sh start

ExecReload=/home/nickodimus/gpio-open.sh reload

ExecStop=/home/nickodimus/gpio-open.sh stop

TimeoutSec=30

Restart=on-failure

RestartSec=30

StartLimitInterval=350

StartLimitBurst=10

[Install] WantedBy=multi-user.target

Now, make the script executable:

chmod +x gpio-open.sh

And enable the systemd file:

sudo systemctl daemon-reload sudo systemctl enable --now gpio-open-startup.service

This persists the permissions across reboots and no more must be root to run issues. First post for me. The preview looks like its got formatting, sorry for that in advance if it does. No idea how to prettify it so if anyone has a link to posting formatting here please leave it in a comment and I'll clean up my post.

0

initialize all GPIO before importing any other libraries