How to control GPIO via C or Python 3

It works across every distro the same way.

Although it worked when I just read lines (direct voltage reads whether a gpio line was 1 or 0), it was doing something weird like not releasing the line correctly (system interrupts occur but then donā€™t go away):

def run(self) -> None:
        """Monitors the GPIO line for tap events and processes them.

        Continuously checks a specific GPIO line for voltage changes. If a change is detected,
        interprets it as a tap event and triggers the tap handling process.
        """
        # TODO: Create chip/pin mapping in gpio_config
        chip_path = '/dev/gpiochip1'
        line_offset = 26

        with gpiod.request_lines(
            path=chip_path,
            consumer='watch-touch-sensor-line',
            config={
                line_offset:
                    gpiod.LineSettings(
                        edge_detection=Edge.RISING,
                        bias=Bias.PULL_DOWN,
                        debounce_period=timedelta(seconds=0.5)
                )
            }
        ) as line:
            while True:
                # Block until rising edge event happens
                if line.read_edge_events():
                    self.handle_tap()

This will work the first run, but then as soon as it reads once, it then canā€™t read again. In fact, if I rerun the program, the gpiod.request_lines throws an error like resource is busy or something like that. Only once I reboot will the process run once again (but always only once). I figured the reboot removes the system interrupt that occurs when gpiod.request_lines or line.read_edge_events() is called. What can I do to fix this, or at least debug to gain more insight?

Have you updated the kernel to the latest?

I will attempt it again for the Dec. 3rd update, but assuming that wasnā€™t already fixed from the Dec. 2nd update, I have the following kernel/distro:

Linux raspbian-bookworm-aml-s905x-cc 6.1.64-11810-g69b1ffe8ef6c #1 SMP PREEMPT_DYNAMIC Sat Dec  2 01:00:10 EST 2023 aarch64 GNU/Linux

We fixed it in 6.1.66.

1 Like

yet another thing to get around.

Error I am getting is: ā€œgpioset: error setting the GPIO line values Permission Deniedā€

How do I work around this issue?

The user you are using to run the commands has no permissions to write to the /dev/gpiochipX character devices. Either run your program as root or run sudo or apply proper permissions/groups to your running user.

I dropped the Easy GPIO Python Library and just coded the pin commands as needed.

GPIO0_D3set = ā€œgpioset 0 27=1ā€
GPIO0_D3reset = ā€œgpioset 0 27=0ā€
ā€¦
system( f"{GPIO0_D3set}" )

1 Like

Hi, itā€™s been three weeks since I received your Alta AML-A311D-CC. I installed the 2023-10-10-raspbian-bookworm-arm64-full+arm64 OS on it. However, Iā€™m still struggling to understand how to simply turn on a led using the GPIO ports.
I want to accomplish this using Python, but I canā€™t find any documentation about the gpiod module. Additionally, Iā€™m unsure how to bind the ports and determine which one is which.
thankā€™s in advence

Did you do this thing, post 1, Libre Computer Wiring Tool?

Did it work?

If yes then:

from os import system

certs.FanOff = ā€œgpioset 0 0=0ā€ #J1 pin 32
certs.FanOn = ā€œgpioset 0 0=1ā€

                    if ( temperature >= certs.FanTriggerPoint ):
                        system( f"{certs.FanOn}" )
                        fan_enabled = True
                    else:
                        system( f"{certs.FanOff}" )
                        fan_enabled = False

else:
let us know it did not work and what issue you have.

1 Like

thankā€™s a lot I check that and y keep you informed for now it works

Hello, so I finally managed to control my robot, although not in an optimal manner. However, itā€™s sufficient for my project. Here is the code : (I still have a question to ask I put it below the code)

#!/usr/bin/env python3
import subprocess, time

'''
---------------------
--->display doc<---
---------------------
'''

x = subprocess.check_output('lgpio headers', shell=True, text=True)
y = subprocess.check_output('lgpio header 7J1', shell=True, text=True)

print(y)
print("from chip 7J1 but there is other chip detected : \n" + x)

'''
-------------------------------
--->Variable definition<---
-------------------------------
'''

leftFWD = "8" #outpup pin for the engine
rightFWD = "7"
leftRWD = "11"
rightRWD = "10"

'''
--------------------------------
--->fonctions definition<---
--------------------------------
'''

def FX_Mouvement(Movement):
	'''
	this function execute the desierd movement
	Stop = stop every engine
	FWD = go forwad
	RWD = go backward
	Left = turn left
	Right = turn right
	'''
	
	match Movement:
		case "Stop":
			subprocess.run("sudo lgpio set " + leftFWD + "=0", shell=True)
			subprocess.run("sudo lgpio set " + rightFWD + "=0", shell=True)
			subprocess.run("sudo lgpio set " + leftRWD + "=0", shell=True)
			subprocess.run("sudo lgpio set " + rightRWD + "=0", shell=True)
			
		case "FWD":
			subprocess.run("sudo lgpio set " + leftFWD + "=1", shell=True)
			subprocess.run("sudo lgpio set " + rightFWD + "=1", shell=True)
			subprocess.run("sudo lgpio set " + leftRWD + "=0", shell=True)
			subprocess.run("sudo lgpio set " + rightRWD + "=0", shell=True)
			
		case "RWD":
			subprocess.run("sudo lgpio set " + leftFWD + "=0", shell=True)
			subprocess.run("sudo lgpio set " + rightFWD + "=0", shell=True)
			subprocess.run("sudo lgpio set " + leftRWD + "=1", shell=True)
			subprocess.run("sudo lgpio set " + rightRWD + "=1", shell=True)
			
		case "Left":
			subprocess.run("sudo lgpio set " + leftFWD + "=1", shell=True)
			subprocess.run("sudo lgpio set " + rightFWD + "=0", shell=True)
			subprocess.run("sudo lgpio set " + leftRWD + "=1", shell=True)
			subprocess.run("sudo lgpio set " + rightRWD + "=0", shell=True)
			
		case "Right":
			subprocess.run("sudo lgpio set " + leftFWD + "=0", shell=True)
			subprocess.run("sudo lgpio set " + rightFWD + "=1", shell=True)
			subprocess.run("sudo lgpio set " + leftRWD + "=0", shell=True)
			subprocess.run("sudo lgpio set " + rightRWD + "=1", shell=True)
			
		
'''
-----------------
--->Quick test<---
-----------------
'''

for i in range(1):
	'''
	test
	'''
	print('|||---------------------fw ---------------------|||')
	FX_Mouvement("FWD")
	time.sleep(0.5)

	print('|||---------------------bw ---------------------|||')
	FX_Mouvement("RWD")
	time.sleep(0.5)

	print('|||---------------------L  ---------------------|||')
	FX_Mouvement("Left")
	time.sleep(0.5)

	print('|||---------------------R  ---------------------|||')
	FX_Mouvement("Right")
	time.sleep(0.5)

	
	print('|||---------------------stp---------------------|||')
	FX_Mouvement("Stop")
	time.sleep(0.3)

	
	print('endprocess')


Now, I would like to read some information that is outputted from the sensors into GPIO ports. For example, I would like to evaluate distance using an ultrasonic sensor connected to an ADC. However, Iā€™m unsure how to detect if there is current flowing into the GPIO ports using the libgpioreg libraryā€¦

Are you using a raw Ultrasonic sensor and pulsing it with +/-12V or are you using something like a SRO4 module?

Did you do a search using your IDE for a Python SRO4 library?

lgpio should not be called via a program. Itā€™s for command line testing of the GPIOs.

You should get the gpio chip and line from the lgpio tool and use pythonā€™s libgpiod bindings to directly control the GPIOs.

GPIOs are digital IOs that require 3.3V, not analog. Do not run anything that drives current to a GPIO and/or is not 3.3V.

1 Like

Iā€™m planning to use some SR04 and one SEN0032, and one SEN0101, yes I would like tu use them with python. Because I need the data of these sensor to give them to my AI.

So the 7J1 chip is not the one that is meant to contrƓl the GPIO pins?

For the libgpiod, I did not understand where to find a documentation that workā€™s with your OS.

I dont know if I understand correctly your last point. Did you mean that I can not read any info on the gpio or my ADC must send 3.3V?

If using an SR04 then why not use a Python library to do the Ultrasonic thing?

1 Like

SR04 is a 5V device so you cannot directly hook it to a 3.3V GPIO. You need to have a level shifter to safely use it. In terms of use, SR04 uses GPIO interrupts to measure pulse duration to determine distance. Itā€™s best to compile a kernel driver that will return distance via the IIO subsystem.

1 Like

thankā€™s a lot for helping me, I will use the python library if I succed to overide the externally managed environement that Iā€™m on. Itā€™s just that for now Iā€™m stuck at understanding how to read information but it looks like itā€™s because of the voltage as @librecomputer said

Thank you Iā€™m happy to hear that I can read some info on my GPIO ports !! I will start to try what you said. 3.3V I saw that i could use a resistor divider, I might do that but is there a tolerance with the GPIO ports if I with 3.333ā€¦V could it break the board with time?