更新日志: 2013 年 6 月 2 日更新:根据官方文档完成了初步翻译。 本文会在适当的时间里进行增删改等操作,如果您对该文感兴趣,可以仅收藏本页。
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 <your-ip> <your-port>
对 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!