将pigpio库Python代码转换为gpiod库的技术求助
问题
需要将基于pigpio库的Python代码转换为gpiod库实现,已理解pigpio代码逻辑,但gpiod库缺乏可用文档导致转换受阻,已完成部分gpiod代码,需完整转换方案及gpiod文档指引。
原有pigpio代码
import pigpio relay_1 = 5 pi = pigpio.pi() def setupGPIO(): if not pi.connected: # Check connected print("Not connected to PIGPIO Daemon") setupGPIO() else: print("Connected to PIGPIO Daemon") pi.set_pull_up_down(relay_1, pigpio.PUD_DOWN) cb1 = pi.callback(relay_1, pigpio.EITHER_EDGE, pinChange) def pinChange(pin, state, t): if (state == 0): print('LOW', pin, str(t)) else: print('HIGH', pin, str(t)) lastPin = t # used somewhere else # 原代码中interCom变量未定义,保留逻辑结构 if (pin == interCom): some_func(state) else: check_lights() def check_lights(): r1 = pi.read(relay_1) totals = r1 # 原代码中pinTotals变量未定义,保留原输出结构 print(f'totals != pinTotals {totals} {pinTotals}') if __name__ == "__main__": setupGPIO()
已完成的gpiod代码片段
import gpiod relay_1 = 5 def setupGPIO(): print('setup gpio initiated') try: config = { relay_1: gpiod.LineSettings( direction=gpiod.line.Direction.INPUT, bias=gpiod.line.Bias.PULL_DOWN ) } with gpiod.request_lines( "/dev/gpiochip4", consumer='gpio-setup', config=config ) as request: print('Connected to GPIO') except Exception as e: print(f'Failed to setup GPIO: {e}') setupGPIO() print('setup gpio executed') if __name__ == "__main__": setupGPIO()
完整gpiod转换方案
以下代码完全对应原有pigpio的功能,包括下拉电阻配置、双边沿触发回调、引脚状态读取:
import gpiod import time relay_1 = 5 # 原代码中interCom、pinTotals、some_func需自行定义,这里保留逻辑结构 interCom = None # 替换为实际引脚号 pinTotals = 0 lastPin = 0 def pinChange(pin, state): # 生成微秒级时间戳,匹配pigpio的t参数格式 t = int(time.time() * 1000000) if state == 0: print('LOW', pin, str(t)) else: print('HIGH', pin, str(t)) global lastPin lastPin = t if pin == interCom: some_func(state) else: check_lights() def some_func(state): # 实现原函数逻辑 pass def check_lights(): global request r1 = request.get_value(relay_1) totals = r1 print(f'totals != pinTotals {totals} {pinTotals}') def setupGPIO(): print('setup gpio initiated') global request try: # 配置引脚:输入、下拉电阻、双边沿触发 line_settings = gpiod.LineSettings( direction=gpiod.line.Direction.INPUT, bias=gpiod.line.Bias.PULL_DOWN, edge_detection=gpiod.line.EdgeDetection.BOTH_EDGES ) config = gpiod.RequestConfig( consumer='gpio-listener', line_settings={relay_1: line_settings} ) # 注意:GPIO芯片编号需根据硬件调整,树莓派通常为gpiochip0 request = gpiod.request_lines("/dev/gpiochip0", config=config) print('Connected to GPIO') # 循环监听边缘事件,替代pigpio的回调机制 while True: # 等待事件,超时1秒可按需调整 events = request.wait_edge_events(1) if events: event = request.read_edge_event() pin = event.line_offset # 转换事件类型为0/1状态 state = 1 if event.type == gpiod.line.EventType.RISING_EDGE else 0 pinChange(pin, state) except Exception as e: print(f'Failed to setup GPIO: {e}') # 添加延迟避免无限递归 time.sleep(1) setupGPIO() if __name__ == "__main__": setupGPIO()
gpiod库核心使用指引
GPIO芯片编号确认
- 执行
ls /dev/gpiochip*查看系统中的GPIO芯片,树莓派主GPIO控制器通常是gpiochip0,需根据硬件实际情况调整。
- 执行
关键API说明
gpiod.LineSettings:配置引脚方向、偏置电阻(上拉/下拉)、边缘检测类型(上升沿/下降沿/双边沿)。gpiod.RequestConfig:定义请求的消费者名称(用于标识进程),关联引脚配置。gpiod.request_lines:向GPIO芯片请求引脚资源,返回Request对象。request.wait_edge_events(timeout):等待边缘事件,超时返回None,有事件返回事件数量。request.read_edge_event():读取边缘事件,包含引脚偏移、事件类型、时间戳。request.get_value(pin):读取指定引脚的当前状态(0/1)。
注意事项
- gpiod的资源请求在手动调用
request.release()或对象销毁后会释放,需在请求保持期间持续监听事件(如示例中的while循环)。 - 边缘事件的原生时间戳为纳秒级,可通过
event.timestamp获取并按需转换格式。 - 权限问题:运行代码需拥有GPIO设备的读写权限,可通过
sudo usermod -aG gpio $USER将用户加入gpio组解决。
- gpiod的资源请求在手动调用
内容的提问来源于stack exchange,提问作者farhan jatt
相关产品推荐
相关产品推荐

