2、python mudbus通信

Modbus是一种串行通信协议,是Modicon公司(现在的施耐德电气Schneider Electric)于1979年为使用可编程逻辑控制器(PLC)通信而发表。Modbus已经成为工业领域通信协议的业界标准(De facto),并且现在是工业电子设备之间常用的连接方式。
在这里插入图片描述
其中:
(1)地址域(Addr):8位数据,表示有效的从机设备地址范围0-247;
(2)功能域(Func):当主机向从机发送查询信息时,功能码命令从机执行相应功能;当从机响应主机,功能码表示从机正常响应或者出现异常。
(3)数据域:主机查询从机时,数据域包含读取寄存器起始地址和读取寄存器数量,16位有效,高字节在前,低字节在后。从机响应主机时,数据域包含接收数据字节数量(8位有效)和接收的数据(16位有效,高字节在前,低字节在后)。
(4)错误校验域:使用CRC16校验,16位有效,高字节在前,低字节在后。
线圈寄存器:实际上就可以类比为开关量,每个bit都对应一个信号的开关状态。所以一个byte就可以同时控制8路的信号。比如控制外部8路io的高低。 线圈寄存器支持读也支持写,写在功能码里面又分为写单个线圈寄存器和写多个线圈寄存器。对应上面的功能码也就是:0x01 0x05 0x0f

离散输入寄存器:如果线圈寄存器理解了这个自然也明白了。离散输入寄存器就相当于线圈寄存器的只读模式,他也是每个bit表示一个开关量,而他的开关量只能读取输入的开关信号,是不能够写的。比如我读取外部按键的按下还是松开。所以功能码也简单就一个读的 0x02

保持寄存器:这个寄存器的单位不再是bit而是两个byte,也就是可以存放具体的数据量的,并且是可读写的。比如我我设置时间年月日,不但可以写也可以读出来现在的时间。写也分为单个写和多个写,所以功能码有对应的三个:0x03 0x06 0x10

输入寄存器:只剩下这最后一个了,这个和保持寄存器类似,但是也是只支持读而不能写。一个寄存器也是占据两个byte的空间。类比我我通过读取输入寄存器获取现在的AD采集值。对应的功能码也就一个 0x04

# -*- coding: utf_8 -*-


import serial
import modbus_tk
import modbus_tk.defines as cst
from modbus_tk import modbus_rtu


def mod(PORT="com3"):
    red = []
    alarm = ""
    try:
        # 设定串口为从站
        master = modbus_rtu.RtuMaster(serial.Serial(port=PORT,
                                                    baudrate=9600, bytesize=8, parity='N', stopbits=1))
        master.set_timeout(5.0)
        master.set_verbose(True)
        # 0x01: 读线圈寄存器
        # 0x02: 读离散输入寄存器
        # 0x03: 读保持寄存器
        # 0x04: 读输入寄存器
        # 0x05: 写单个线圈寄存器
        # 0x06: 写单个保持寄存器
        # 0x0f: 写多个线圈寄存器
        # 0x10: 写多个保持寄存器
        # 读保持寄存器
        red = master.execute(1, cst.READ_HOLDING_REGISTERS, 2, 4)  # 这里可以修改需要读取的功能码
        print(red)
        red = master.execute(1, cst.WRITE_SINGLE_REGISTER, 6, output_value=789)  # 这里可以修改需要读取的功能码
        # master.execute(1, cst.WRITE_MULTIPLE_REGISTERS, 2,data_format='I', output_value=[[0],[0],[0],[3]])  # 这里可以修改需要读取的功能码
        #  quantity_of_x 就是数量   output_value 为每个16位寄存器配值
        master.execute(1, cst.WRITE_MULTIPLE_REGISTERS, 2,quantity_of_x=2, output_value=[0,3])  # 这里可以修改需要读取的功能码
        alarm = "正常"
        return list(red), alarm

    except Exception as exc:
        print(str(exc))
        alarm = (str(exc))

    return red, alarm  ##如果异常就返回[],故障信息


if __name__ == "__main__":
    mod()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿Q学长

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值