moubus协议以及python实现

moubus协议

moubus协议以及python实现_第1张图片

寄存器协议地址指指通信时使用的寄存器地址,例如PLC地址40001对应寻址地址0x0000,40002对应寻址地址0x0001,寄存器寻址地址一般使用16进制描述。再如,PLC寄存器地址40003对应协议地址0002,PLC寄存器地址30003对应协议地址0002,虽然两个PLC寄存器寄存器通信时使用相同的地址,但是需要使用不同的命令访问,所以访问时不存在冲突。

moubus读取数据

参考资料:[](https://blog.csdn.net/xukai871105/article/details/16368615

moubus_tk实现

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

#找本机的端口号是多少
PORT = 'COM6'

def WriteFloat(value,reverse=False):
    #!:network (= big-endian),f:浮点数,此方法把浮点数转换为字节流
    y_bytes = struct.pack('!f',value)
    #字节流转化位16进制
    y_hex = y_bytes.hex()
    n,m = y_hex[:-4],y_hex[-4:]
    n,m = int(n,16),int(m,16)
    if reverse:
        v = [n,m]
    else:
        v = [m,n]
    return v

def ReadFloat(*args,reverse=False):
    #十进制转化为16进制,并化为字符串
    for n,m in args:
        n,m = '{:04x}'.format(n),'{:04x}'.format(m)
    if reverse:
        v = n + m
    else:
        v = m + n
    #16进制转化为字节流
    y_bytes = bytes.fromhex(v)
    #转化为浮点数,结果返回的是元组
    y = struct.unpack('!f',y_bytes)[0]
    #取1位小数点
    y = round(y,1)
    return y

def ReadDint(*args,reverse=False):
    for n,m in args:
        n,m = '{:04x}'.format(n),'{:04x}'.format(m)
    if reverse:
        v = n + m
    else:
        v = m + n
    y_bytes = bytes.fromhex(v)
    y = struct.unpack('!i',y_bytes)[0]
    return y

def WriteDint(value,reverse=False):
    y_bytes = struct.pack('!i',value)
    y_hex = y_bytes.hex()
    n,m = y_hex[:-4],y_hex[-4:]
    n,m = int(n,16),int(m,16)
    if reverse:
        v = [n,m]
    else:
        v = [m,n]
    return v

def Readint(*args):
    n = '{:04x}'.format(args[0][0])
    y_bytes = bytes.fromhex(n)
    y = struct.unpack('!h',y_bytes)[0]
    return y

def Writeint(value):
    y_bytes = struct.pack('!h',value)
    y_hex = y_bytes.hex()
    n= int(y_hex,16)
    return n

if __name__ == "__main__":
    logger = modbus_tk.utils.create_logger("console")
    master = modbus_rtu.RtuMaster(
        serial.Serial(port=PORT, baudrate=9600, bytesize=8, parity='N', stopbits=1)
    )
    master.set_timeout(5.0)
  
    logger.info("connected")

   logger.info(master.execute(1, cst.WRITE_SINGLE_REGISTER, 22,
                                output_value= WriteFloat(123.2)))
    tuple = master.execute(1, cst.READ_HOLDING_REGISTERS, 22, 2
     print(ReadFloat(tuple)

1、PLC与树莓派基于Modbus_tk库、serial库进行串口通信。通过serial.Serial连接,端口需查看当前连接的端口号,波特率9600,数据位为8位,奇偶校验设置为无,停止位设置为1位。
2、数据均为PLC从各类传感器中获取的数据,使用master.execute传输数据,获取的是十进制,从站为1,cst. WRITE_SINGLE_REGISTER为写入一个保持寄存器、cst. WRITE_MULTIPLE_REGISTERS为写入多个连续保持寄存器、cst. READ_HOLDING_REGISTERS为读取一个或者多个连续保持寄存器、cst. READ_COILS为读取线圈(开关)、cst. WRITE_SINGLE_COIL为写入一个线圈(开关),output_value为输入的十进制,starting_address为寄存器或者线圈的起始地址,quantity_of_x为获取的个数。
3、如果数据为4字节浮点数,需要转化数据,使用struct.pack、struct.unpack方法把转化为对应格式,其中!为网络字节顺序,h为有符号2字节整型,i为有符号4字节整型,f为4字节浮点型。使用round()方法保留位数。上面可实现存入2字节有符号整型、4字节有符号整型、4字节浮点型读取写入。

你可能感兴趣的:(moubus协议以及python实现)