基于Pymodbus异步服务器如何将线圈状态直接绑定树莓派GPIO引脚
实现方案
完全可以实现线圈状态和GPIO引脚的直接绑定,不需要额外客户端轮询查询线圈值,有两种实现思路,推荐优先用回调触发的方案,延迟更低、资源占用更小。
方案1:写线圈事件回调触发(推荐)
Pymodbus异步服务器支持注册写操作的回调函数,只要有客户端修改线圈值,回调会立即触发,你可以在回调中直接更新GPIO状态,步骤如下:
- 先初始化GPIO引脚,以
gpiozero库为例:
from gpiozero import OutputDevice pin_21 = OutputDevice(21) # 初始化21号引脚为输出模式
- 定义写线圈回调函数:
async def write_coil_callback(address, value): # 注意线圈地址映射:如果客户端访问的线圈1对应内部地址0,按实际映射调整 if address == 0: pin_21.value = value
- 初始化异步服务器时注册回调:
server = ModbusTcpServer( context, address=("0.0.0.0", 502), on_write_coil=write_coil_callback )
方案2:定期同步状态(可选补充)
如果需要避免异常情况导致线圈值和引脚状态不一致,可以加一个异步定时任务定期同步:
import asyncio async def sync_gpio_task(context, interval=0.5): # 每500ms同步一次 while True: # 从服务器上下文读线圈1的值,地址0,数量1 coil_value = context.getValues(1, 0, 1)[0] pin_21.value = coil_value await asyncio.sleep(interval)
- 启动服务器时同时启动同步任务:
async def main(): # 原有服务器初始化逻辑 asyncio.create_task(sync_gpio_task(context)) await server.serve_forever()
注意事项
- 树莓派操作GPIO需要root权限,运行脚本时需要加
sudo前缀 - 确认线圈地址的映射关系,Pymodbus内部存储默认从0开始索引,客户端请求的1号线圈对应内部地址0,可根据实际业务调整映射逻辑
- 异步逻辑中不要加入阻塞操作,GPIO操作本身为非阻塞,不会影响服务器运行
内容的提问来源于stack exchange,提问作者Michael H.
相关产品推荐
相关产品推荐

