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协议整理——汇总 
    【2】 freemodbus modbus TCP 学习笔记 
    【3】python 扩展库安装 使用第三方镜像源 

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()))

      【运行结果】
MODBUS学习笔记——modbus tk modbus TCP主机实现_第1张图片
图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,真的感觉学了东西提高了自己。还是那句话,工程师没有过去只有去创造。继续努力吧。

你可能感兴趣的