0.前言
modbus是一种古老但是高效的应用层协议。在嵌入式和PC机领域有多种方法实现modbus协议栈,modbus又分为从机和主机,从机和主机在协议栈的实现上存在不同。在不能运行linux的嵌入式系统中,freemodbus是一个完善的从机协议栈,在能够运行linux的嵌入式系统中存在多种选择,而modbus tk是使用python语言实现的modbus协议栈,该函数库即支持主机也支持从机,即支持RTU也支持TCP。
有了modbus TK,那么在树莓派中加入一个modbus TCP实现从机功能,也就是分分钟的事情。
【有用的博客】
1.modbus tk安装
【1】请确保安装python 2.5以上,并安装pyserial(使用python 控制串口)
【2】下载modbus tk安装包并解压。例如安装包解压至E:\modbus-tk-0.4.2
【3】打开控制台,进入E:\modbus-tk-0.4.2,输入:
python setup.py install
setup.py为文件名,install为运行该文件的参数。安装过程非常快。
【4】验证安装是否完成。import modbus_tk,若输入该命令python没有提示错误的话,那么表示modbus_tk安装成功。
图1 验证modbus tk安装成功
2.示例代码
请参考freemodbus modbus TCP 学习笔记博文,建立一个modbus TCP从机。
从机IP地址 192.168.1.15
侦听端口 502
准备一些默认寄存器,共调试使用。
【输入寄存器】共16个,依次为1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16
【保持寄存器】共16个,依次为16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1
【线圈寄存器】共16个,依次为0xFF,0x00
【离散输入寄存器】共16个,一次为0x00,0xFF
【 代码】
# -*- coding: utf_8 -*- import sys import logging import modbus_tk import modbus_tk.defines as cst import modbus_tk.modbus_tcp as modbus_tcp logger = modbus_tk.utils.create_logger("console") if __name__ == "__main__": try: # 连接MODBUS TCP从机 master = modbus_tcp.TcpMaster(host="192.168.1.15") master.set_timeout(5.0) logger.info("connected") # 读保持寄存器 logger.info(master.execute(1, cst.READ_HOLDING_REGISTERS, 0, 16)) # 读输入寄存器 logger.info(master.execute(1, cst.READ_INPUT_REGISTERS, 0, 16)) # 读线圈寄存器 logger.info(master.execute(1, cst.READ_COILS, 0, 16)) # 读离散输入寄存器 logger.info(master.execute(1, cst.READ_DISCRETE_INPUTS, 0, 16)) # 单个读写寄存器操作 # 写寄存器地址为0的保持寄存器 logger.info(master.execute(1, cst.WRITE_SINGLE_REGISTER, 0, output_value=21)) logger.info(master.execute(1, cst.READ_HOLDING_REGISTERS, 0, 1)) # 写寄存器地址为0的线圈寄存器,写入内容为0(位操作) logger.info(master.execute(1, cst.WRITE_SINGLE_COIL, 0, output_value=0)) logger.info(master.execute(1, cst.READ_COILS, 0, 1)) # 多个寄存器读写操作 # 写寄存器起始地址为0的保持寄存器,操作寄存器个数为4 logger.info(master.execute(1, cst.WRITE_MULTIPLE_REGISTERS, 0, output_value=[20,21,22,23])) logger.info(master.execute(1, cst.READ_HOLDING_REGISTERS, 0, 4)) # 写寄存器起始地址为0的线圈寄存器 logger.info(master.execute(1, cst.WRITE_MULTIPLE_COILS, 0, output_value=[0,0,0,0])) logger.info(master.execute(1, cst.READ_COILS, 0, 4)) except modbus_tk.modbus.ModbusError, e: logger.error("%s- Code=%d" % (e, e.get_exception_code()))
【运行结果】
图2 运行结果
【简要说明】
【1】master = modbus_tcp.TcpMaster(host="192.168.1.15")
构造一个modbus主机对象,此处为TcpMaster对象,构造参数为IP地址192.168.1.15,若IP地址为空则为localhost。
若需要构造一个modbus RTU主机,可使用以下代码:
master = modbus_rtu.RtuMaster(serial.Serial(“COM1”, baudrate=9600))
构造参数和modbus TCP稍有差异。
【2】master.execute(1, cst.READ_HOLDING_REGISTERS, 0, 16)
读保持寄存器操作,execute为执行函数,共有4个参数,原型如下:
@threadsafe_function
def execute(self, slave, function_code, starting_address,
quantity_of_x=0, output_value=0, data_format="", expected_length=-1):
slaver
|
从机地址
|
modbus TCP时可以忽略该参数
|
function_code
|
功能码 |
modbus_tk.modbus_tcp中定义
|
starting_address
|
寄存器起始地址
|
可设定
|
quantity_of_x
|
寄存器数量
|
可设定
|
output_value
|
输出内容
|
读操作是无效,写操作是输入为List类型
|
3.总结
modbus tk的代码看了几天,对python或许有了更深的理解。前些年就知道python也有modbus库,但是由于不会python一直搁浅。去年尝试了树莓派,在使用树莓派的过程中真的开了眼界,慢慢接触了python和restful,真的感觉学了东西提高了自己。还是那句话,工程师没有过去只有去创造。继续努力吧。