本文转载自 Dreamcolor Said。
RPIO.py 相对于 RPi.GPIO 在各个方面都有所扩展,并且默认使用 BCM GPIO 编号方式。
GPIO 和 TCP 中断
RPIO 可以对两种中断进行监听:GPIO 和 TCP。某特定 GPIO 的输入状态改变时将产生 GPIO 中断。某 TCP socket 客户端发送信息时将产生 TCP 中断。
RPIO.wait_for_interrupts(threaded=False, epoll_timeout=1)
- 这是阻隔功能的主循环,当启用后,将会对中断进行监听,并且启用您自定义的回调操作。在您脚本的某个地方,您需要使用它来接收中断回调。这种阻隔方式非常适合于“让您的脚本一直循环运行”。
- 使用 threaded=True 参数,使它在您的脚本运行于主线程时,使其在后台操作(RPIO 在您的脚本退出时,会自动关闭该线程):
RPIO.wait_for_interrupts(threaded=True)
GPIO 中断
中断被用于接收当 GPIO 状态发生改变时来自于内核的通知。其优点是消耗 CPU 资源非常少,通知时间非常短,并且可在特定临界值转换(rising、falling、both)时被触发的能力。您还可以设置软件上拉或下拉电阻。
RPIO.add_interrupt_callback(gpio_id, callback, edge=’both’, pull_up_down=RPIO.PUD_OFF, threaded_callback=False, debounce_timeout_ms=None)
- 添加一个回调用于接收当 GPIO 状态从 0 到 1(反之亦然)时的通知。
- 可能用到的临界值为 rising、falling、both(默认)。
- 可能用到的 pull_up_down 值为:RPIO.PUD_UP、RPIO.PUD_DOWN、RPIO.PUD_OFF(默认)。
- 如果 threaded_callback 为 True,回调将开始与线程内。否则直到其结束后,回调才会从中断等待状态下阻断 RPIO(在这期间,不会有其它回调操作)。
- 如果设置了 debounce_timeout_ms,那么从上次中断结束后,需要等到您指定的毫秒数后才会再次执行中断回调操作。可以根据您的需求进行设置(通常为 10ms 到 100ms 之间)。
- 回调功能有两个参数,分别为:GPIO 编号和值。(值为整数,0(Low)或 1(High))。回调操作通常写法为:
def gpio_callback(gpio_id, value): RPIO.del_interrupt_callback(gpio_id)
- 移除特定 GPIO 上的回调操作。
TCP Socket 中断
仅使用这一种方法就可以方便的为入站 TCP 连接打开端口:
RPIO.add_tcp_callback(port, callback, threaded_callback=False)
- 添加 socket 服务器回调,它会在某个已连接的 socket 客户端发送数据时开始执行。这被用于 RPIO 在特定端口创建 TCP 服务器 socket。当 RPIO.wait_for_interrupts() 运行时,将接受入站连接。回调必须指定两个参数:socket 和 message(例如:def callback(socket, msg))。
- 回调可以使用 socket 参数将值发回到客户端(例如:socket.send(“hi there\n”))。如果要关闭某客户端的连接,可使用 RPIO.close_tcp_client(..)。客户端可以使用相同的方式关闭连接,或者发送到服务器一个空信息也会同样断开连接。
- 您可以使用 socket.getpeername() 来获得客户端的 IP 地址。详情可参见 Socket 对象文档。
您可以输入命令 $ telnet 对 TCP socket 中断进行测试(例如:$ telnet localhost 8080)。空字符串将通知服务器断开与客户端的连接(比如,您在 telnet 中按下回车键,您得连接将被断开)。
RPIO.close_tcp_client(self, fileno)
- 关闭客户端 socket 连接并从 epoll 中移除。您可以使用回调中的 RPIO.close_tcp_client(socket.fileno()) 来实现。
示例
以下示例将示范如何监听某些 GPIO 和 TCP 中断:
import RPIO def gpio_callback(gpio_id, val): print("gpio %s: %s" % (gpio_id, val)) def socket_callback(socket, val): print("socket %s: '%s'" % (socket.fileno(), val)) socket.send("echo: %s\n" % val) # GPIO 中断回调 RPIO.add_interrupt_callback(7, gpio_callback) RPIO.add_interrupt_callback(9, gpio_callback, pull_up_down=RPIO.PUD_UP) # 回调服务器端口 8080 TCP socket RPIO.add_tcp_callback(8080, socket_callback) # 阻断主 epoll 循环 RPIO.wait_for_interrupts()
在进程内接收回调(并且不对 RPIO 返回到等待中断状态进行阻隔),需要在添加时将 threaded_callback 设置为 True:
# 用于 GPIO 中断 RPIO.add_interrupt_callback(7, do_something, threaded_callback=True) # 用户 socket 中断 RPIO.add_tcp_callback(8080, socket_callback, threaded_callback=True)
去除 GPIO 中断抖动,您可以添加 debounce_timeout_ms 参数到 add_interrupt_callback(..) 中。例如:
RPIO.add_interrupt_callback(7, do_something, debounce_timeout_ms=100)
wait_for_interrupts() 对中断和调度进行监听。您可以添加 threaded=True 参数,使其运行于一个线程中,使您的脚本继续运行。从版本 v0.10.0 开始,当您的脚本退出后,RPIO 已经可以很好的关闭所有操作了。
RPIO.wait_for_interrupts(threaded=True)
停止 wait_for_interrupts(..) 可以通过调用 RPIO.stop_waiting_for_interrupts() 来实现。
GPIO 输入和输出
RPIO 对 RPi.GPIO 进行了扩展,所有输入和输出的工作方式都是相同的:
import RPIO # 设置无上拉电阻输入通道 RPIO.setup(7, RPIO.IN) # 设置有上拉电阻输入通道。可以为: # PUD_UP、PUD_DOWN、PUD_OFF(默认) RPIO.setup(7, RPIO.IN, pull_up_down=RPIO.PUD_UP) # 读取 GPIO 7 的输入值 input_value = RPIO.input(7) # 设置 GPIO 输出通道 RPIO.setup(8, RPIO.OUT) # 设置 GPIO 8 的值为 High RPIO.output(8, True) # 设置输出通道及初始值 RPIO.setup(8, RPIO.OUT, initial=RPIO.LOW) # 更改为 BOARD 编号方式 RPIO.setmode(RPIO.BOARD) # 在通道 17 上设置软件上拉电阻 RPIO.set_pullupdn(17, RPIO.PUD_UP) # RPIO 新增功能 # 获得通道 8 的函数 RPIO.gpio_function(8) # 复位所有由该程序设置过的通道, # 并清除 GPIO 中断接口 RPIO.cleanup()
您可以在现有代码中使用 RPIO 直接替换 RPi.GPIO:
import RPIO as GPIO # (如果您之前使用的是“import RPi.GPIO as GPIO”)
如果想获得更多使用方法及常量的讲解,可以运行 $ sudo pydoc RPIO,或者在 Python 中使用帮助功能:
import RPIO help(RPIO)
日志输出
开启 RPIO 日志输出,需在引入 RPIO 之前先引入 logging 函数并设置日志级别为 DEBUG:
import logging log_format = '%(levelname)s | %(asctime)-15s | %(message)s' logging.basicConfig(format=log_format, level=logging.DEBUG) import RPIO
对 RPi.GPIO 的扩展
更多可用常量
- RPIO.RPI_REVISION – 当前主板的修订版本(1 或者 2)
- RPIO.RPI_REVISION_HEX – CPU 的 16 进制修订码(0002 到 000f)
更多可用功能
- RPIO.gpio_function(gpio_id) – 返回 GPIO 当前的设置(IN、OUT、ALT0)
- RPIO.set_pullupdn(gpio_id, pud) – 在 GPIO 上设置上拉或下拉电阻
- RPIO.forceinput(gpio_id) – 无需调用 setup() 直接读取任何 GPIO 上的值
- RPIO.forceoutput(gpio_id, value) – 无需调用 setup() 直接为 GPIO 写入值
(警告:该功能可能会损坏您的 Raspberry Pi) - RPIO.sysinfo() – 返回 Raspberry Pi 系统信息(hex_rev, model、revision、mb-ram、maker)
- RPIO.version() – 返回 RPIO 信息(version_rpio、version_cgpio)
中断处理
- RPIO.add_interrupt_callback(gpio_id, callback, edge=’both’, pull_up_down=RPIO.PUD_OFF, threaded_callback=False, debounce_timeout_ms=None)
- RPIO.add_tcp_callback(port, callback, threaded_callback=False)
- RPIO.del_interrupt_callback(gpio_id)
- RPIO.close_tcp_client(fileno)
- RPIO.wait_for_interrupts(threaded=False, epoll_timeout=1)
- RPIO.stop_waiting_for_interrupts()
- 操控 epoll
原文地址:RPIO, the Python module
项目地址:RPIO’s documentation!
发表评论