Trying to read the values from gpio chips in a Python script using the gpiod python module. When calling get_value() we are getting "Operation not permitted".
Have tried running the python script as both root
and pi
user.
My python test script
import logging
import gpiod
_log = logging.getLogger(__name__)
device = "/dev/gpiochip3"
chip = None
try:
chip = gpiod.chip(device, gpiod.chip.OPEN_BY_PATH)
except OSError:
_log.warning("Unable to open gpio chip {device}.")
if chip is None:
_log.error("GPIO chip {device} not available")
line = chip.get_line(12)
if line is not None:
print("Line name: ", line.name)
print(" Line direction: ", line.direction)
print(" Line consumer: ", line.consumer)
print(" Line active state: ", line.active_state)
print(" Line bias: ", line.bias)
print(" Line value: ", line.get_value())
else:
print("Line {line_name} was not found")
Running this I get the following output
root@rpi2:~# python3.9 gpio.py
Line name:
Line direction: 1
Line consumer:
Line active state: 2
Line bias: 1
Traceback (most recent call last):
File "/root/gpio.py", line 25, in <module>
print(" Line value: ", line.get_value())
File "/usr/local/lib/python3.9/dist-packages/gpiod/libgpiodcxx/__init__.py", line 611, in get_value
raise OSError(
PermissionError: [Errno 1] Operation not permitted: 'error reading GPIO line value'
We have tried using the gpoizero, which seem to work better. The problem with gpiozero is
- Support for GPIO expander access the chip directly via I2C-bus, and not via the OS.
- It does not support the GPIO expander we are using.
Running Debian Bullseye on a Raspberry Pi.
root@rpi2:~# uname -a
Linux rpi2 5.15.44-rt46-v8+ #1 SMP PREEMPT Mon Jun 13 10:36:58 CEST 2022 aarch64 GNU/Linux
I also tried creating a C++ application using the C++ bindings of the libgpiod. I am getting the same error there, Operation not permitted.
#include <chrono>
#include <cstdlib>
#include <gpiod.hpp>
#include <iostream>
#include <string>
int main(int argc, char **argv) {
std::string CHIP = "gpiochip1;
int LINE_OFFSET = 2;
gpiod::chip chip(CHIP);
gpiod::line line = chip.get_line(LINE_OFFSET);
std::cout << "Line name: " << line.name();
std::cout << " Line direction: " << line.direction();
std::cout << " Line consumer: " << line.consumer();
std::cout << " Line active state: " << line.active_state();
std::cout << " Line bias: " << line.bias();
std::cout << " Line value: " << line.get_value();
}
Using the command line tools gpioget
works fine. This tool is using the C-library of libgpiod. Could then the problem be the C++ and Python bindings?
root@rpi2:~# gpioget gpiochip3 12
1
root@rpi2:~# gpiodetect
gpiochip0 [pinctrl-bcm2711] (58 lines)
gpiochip1 [raspberrypi-exp-gpio] (8 lines)
gpiochip2 [ftdi-cbus] (4 lines)
gpiochip3 [1-0021] (16 lines)
gpiochip4 [1-0020] (16 lines)
The gpiochip3 and gpiochip 4 are both PCAL6416APW on the I2C-bus. They are configured in /boot/config as following
dtoverlay=pca953x,pcal6416,addr=0x20,irq_gpios=17,reset=16
dtoverlay=pca953x,pcal6416,addr=0x21,irq_gpios=2,reset=12
root@rpi2:~# ls -l /dev/gpiochip*
crw-rw---- 1 root gpio 254, 0 Sep 16 13:34 /dev/gpiochip0
crw-rw---- 1 root gpio 254, 1 Sep 16 13:34 /dev/gpiochip1
crw-rw---- 1 root gpio 254, 2 Sep 16 13:35 /dev/gpiochip2
crw-rw---- 1 root gpio 254, 3 Sep 16 13:35 /dev/gpiochip3
crw-rw---- 1 root gpio 254, 4 Sep 16 13:35 /dev/gpiochip4
ls -l /dev/gpiochip*
into your question.