`
hulianwang2014
  • 浏览: 690713 次
文章分类
社区版块
存档分类
最新评论
  • bcworld: 排版成这样,一点看的欲望都没有了
    jfinal

MODBUS学习笔记——modbus tk modbus TCP主机实现

 
阅读更多
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,真的感觉学了东西提高了自己。还是那句话,工程师没有过去只有去创造。继续努力吧。
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics