• Python_Modbus_RTU_通讯Demo


    之前利用Python进行Modbus_TCP进行数据接收,本次需要利用串口进行数据传输,学习Modbus_RTU的简单实现

    首先要在创建两个虚拟串口,利用VSPD工具即可。在一台电脑上实现数据的发送和接收

     进入Python IDE进行slave端的编写

    import serial
    import modbus_tk
    import modbus_tk.defines as cst
    from modbus_tk import modbus_rtu
    import time
    def ModbusRTU_Slave():
        try:
            # 设定串口为从站
            # 外置参数包括端口 port = "COM3" 波特率:9600
            server= modbus_rtu.RtuServer(serial.Serial(port="com3",baudrate=9600, bytesize=8, parity='N', stopbits=1))
            server.start()
            print("runing...")
            SLAVE1 = server.add_slave(1)
            SLAVE1.add_block('A', cst.HOLDING_REGISTERS, 0, 4)  # 地址0,长度4
            increase_num = 17000
            for i in range(300):
                SLAVE1.set_values('A', 0, [17000, i + 1, i + 2])  # 改变在地址0处的寄存器的值
                time.sleep(0.1)
            for i in range(1500):
                increase_num = increase_num - 1
                SLAVE1.set_values('A', 0, [increase_num, i + 1, i + 2])  # 改变在地址0处的寄存器的值
                time.sleep(0.1)
            for i in range(800):
                SLAVE1.set_values('A', 0, [10000, i + 1, i + 2])  # 改变在地址0处的寄存器的值
                time.sleep(0.1)
            for i in range(800):
                SLAVE1.set_values('A', 0, [17000, i + 1, i + 2])  # 改变在地址0处的寄存器的值
                time.sleep(0.1)
        except Exception as exc:
            print(str(exc))

    再进行master端的编写

    # 数据接收端
    def ModbusRTU_Master():
        try:
            # 设定串口为从站
            # 外置参数包括端口 port = "COM3" 波特率:9600
            master = modbus_rtu.RtuMaster(serial.Serial(port="com4",baudrate=9600, bytesize=8, parity='N', stopbits=1))
            master.set_timeout(1.0)
            master.set_verbose(True)
            # 读保持寄存器
            read = master.execute(1, cst.HOLDING_REGISTERS, 0, 4)  # 这里可以修改需要读取的功能码
            print(red)
        except Exception as exc:
            print(str(exc))

    补充功能码

    功能代码cst
        1~255中1~21是常用的,以下是读写专用的功能码
        READ_COILS = 01 读线圈,位操作
        READ_DISCRETE_INPUTS = 02 读离散输入状态,位操作
        READ_HOLDING_REGISTERS = 03 读保持寄存器,字操作
        READ_INPUT_REGISTERS = 04 读输入寄存器,字操作
        WRITE_SINGLE_COIL = 05 写单线圈,位操作
        WRITE_SINGLE_REGISTER = 06 写单一寄存器,字操作
        WRITE_MULTIPLE_COILS = 15 写多个线圈【强制多点线圈】,位操作
        WRITE_MULTIPLE_REGISTERS = 16 写多寄存器【写乘法寄存器】,字操作

    演示Demo 创建一个项目 1. 通过Modbus_RTU读取 数据 在通过Modbus_RTU将数据发出

    首先创建四个虚拟串口 

     利用Modbus 工具 模拟数据发送 和 接收  【注意】:modbus poll 设置中的数据长度一定要和程序中推送的长度一致 ,在这个问题上浪费了好长时间 哎 

     

     Python程序,其中包含了tcp 和 rtu的内容  可以通过JSON配置文件实现协议切换

    import time
    from datetime import datetime
    import modbus_tk
    import modbus_tk.defines as cst
    import modbus_tk.modbus_tcp as modbus_tcp
    from modbus_tk import modbus_rtu
    import serial
    import json
    
    # JSON 文件初始化
    def InitJSON():
        global filejson
        try:
            with open('20191219_1443.json', 'r') as f:
                filejson = json.load(f)
        except FileNotFoundError:
            print('无法打开指定的文件!')
        except LookupError:
            print('指定了未知的编码!')
        except UnicodeDecodeError:
            print('读取文件时解码错误!')
    
    
    # modbus 相关参数初始化
    def ModbusInit():
        # 首先判断数据传输协议 Modbus_TCP  还是 RTU
        if filejson['ModbusInit']['Modbus_Mode'] == "Modbus_TCP":
            print("Modbus_Mode = Modbus_TCP")
            Modbus_master_IP = filejson['ModbusInit']['Modbus_master_IP']
            Modbus_master_port = filejson['ModbusInit']['Modbus_master_port']
            MASTER = modbus_tcp.TcpMaster(host=Modbus_master_IP, port=Modbus_master_port)
            MASTER.set_timeout(5.0)
            Modbus_slave_IP = filejson['ModbusInit']['Modbus_slave_IP']
            Modbus_slave_port = filejson['ModbusInit']['Modbus_slave_port']
            SLAVE = modbus_tcp.TcpServer(address=Modbus_slave_IP, port=Modbus_slave_port)
            # SLAVE.set_timeout(5.0)
        else:
            print("Modbus_Mode = Modbus_RTU")
            Modbus_master_PORT = filejson['ModbusInit']['Modbus_master_PORT']
            Modbus_master_baudrate = filejson['ModbusInit']['Modbus_master_baudrate']
            print(Modbus_master_PORT)
            MASTER = modbus_rtu.RtuMaster(serial.Serial(port=Modbus_master_PORT, baudrate=Modbus_master_baudrate))
            MASTER.set_timeout(5.0)
            Modbus_slave_PORT = filejson['ModbusInit']['Modbus_slave_PORT']
            print(Modbus_slave_PORT)
            Modbus_slave_baudrate = filejson['ModbusInit']['Modbus_slave_baudrate']
            SLAVE = modbus_rtu.RtuServer(serial.Serial(port=Modbus_slave_PORT, baudrate=Modbus_slave_baudrate, bytesize=8, parity='N', stopbits=1))
            # SLAVE.set_timeout(5.0)
        SLAVE.start()
        print("runing...")
        SLAVE1 = SLAVE.add_slave(1)
        SLAVE1.add_block('warning', cst.HOLDING_REGISTERS, 0, 4)  # 地址0,长度1
        return MASTER,SLAVE1
    
    def main():
        # 初始化JSON 文件
        InitJSON()
        # modbus 初始化
        MASTER, SLAVE1 = ModbusInit()
    
        a = filejson['DistanceParam']['EquationParamA']
        b = filejson['DistanceParam']['EquationParamB']
        print("方程参数a = {},b= {}
    ".format(a, b))
        while(1):
            # 测试 用来获取数据
            num = MASTER.execute(1, cst.READ_HOLDING_REGISTERS, 0, 1)[0]
            # 获取数据
            # num = MASTER.execute(1, cst.READ_INPUT_REGISTERS, 0, 1)[0]
            print("GetV={}".format(num))
            SLAVE1.set_values('warning', 0, num)  # 改变在地址0处的寄存器的值
            time.sleep(filejson['WhileTime'])
    if __name__ == '__main__':
        main()
    View Code
  • 相关阅读:
    合并项目(Project)
    Table.Group分组…Group(Power Query 之 M 语言)
    日程表(Project)
    判断存在…Contains…(Power Query 之 M 语言)
    批量打印本文件夹内除本工作簿以外所有工作簿的第一个工作表
    断舍离与“优秀”推销员
    JS中的let变量
    JavaScript中typeof正确使用
    JavaScript基础学习(一)
    Write an ASP.NET MVC Web app to get Outlook mail, calendar, and contacts
  • 原文地址:https://www.cnblogs.com/wangxiaobei2019/p/12067219.html
Copyright © 2020-2023  润新知