modbus仿真器读取RS485数据

modbus仿真器读取RS485数据

  • 仿真器
    • vspd 安装
    • modbus poll安装
    • modbus slave安装
  • 使用
    • 数据解析
    • 修改寄存器的值

仿真器

  1. vspd 虚拟串口
  2. modbus poll: modbus主机仿真器
  3. modbus slave :modbus从设备仿真器

vspd 安装

在调试485设备时,没有具体硬件或者电脑没有串口时,可以用来虚拟串口。
链接:https://pan.baidu.com/s/1aphnKI4yGvn-Ksk990G3HQ
提取码:wrwf
参考连接 https://blog.csdn.net/qq_34202873/article/details/88391265
添加端口后,打开连个串口助手,在com1的串口助手中发送一串十六进制数值,在com2的串口助手中可以显示
modbus仿真器读取RS485数据_第1张图片
modbus仿真器读取RS485数据_第2张图片

modbus poll安装

Modbus主机仿真器,用于测试和调试Modbus从设备。该软件支持ModbusRTU、ASCII、TCP/IP。用来帮助开发人员测试Modbus从设备,或者其它Modbus协议的测试和仿真。它支持多文档接口,即,可以同时监视多个从设备/数据域。每个窗口简单地设定从设备ID,功能,地址,大小和轮询间隔。你可以从任意一个窗口读写寄存器和线圈。如果你想改变一个单独的寄存器,简单地双击这个值即可。或者你可以改变多个寄存器/线圈值。提供数据的多种格式方式,比如浮点、双精度、长整型(可以字节序列交换)。

链接:https://pan.baidu.com/s/193L39nftHEyDzZTMVLSSuQ
提取码:wrwf
没有激活,试用30天
modbus仿真器读取RS485数据_第3张图片

modbus slave安装

Modbus从设备仿真器,可以仿真32个从设备/地址域。每个接口都提供了对EXCEL报表的OLE自动化支持。主要用来模拟Modbus从站设备,接收主站的命令包,回送数据包。帮助Modbus通讯设备开发人员进行Modbus通讯协议的模拟和测试,用于模拟、测试、调试Modbus通讯设备。可以32个窗口中模拟多达32个Modbus子设备。与Modbus Poll的用户界面相同,支持功能01, 02, 03, 04, 05, 06, 15, 16, 22和23,监视串口数据。

使用

参考链接https://blog.csdn.net/u013184970/article/details/90763024
modbus仿真器读取RS485数据_第4张图片

数据解析

参考https://blog.csdn.net/byxdaz/article/details/77979114
https://blog.csdn.net/weixin_43883666/article/details/103887782
https://blog.csdn.net/lsh159357/article/details/84938546
https://www.freesion.com/article/8467748271/
安装库

首先注意一点Python版的modbus要获取modbus值必须先装【环境包】
pip install serial 
# serial为串口包,需要打开串口,也就是usb
pip install crcmod
# crcmod 用来crc校验的
pip install modbus_tk
# modbus_tk 就是满足modbus协议的Python包

断开modbus poll, 运行代码。其实modbus poll 和下面代码的作用是一样的,但是modbus poll 是写好的工具

import crcmod
from binascii import unhexlify
import modbus_tk
import time
import serial
from modbus_tk import modbus_rtu
from modbus_tk import defines as cst
import logging


def crc16Add(read):
    try:
        crc16 = crcmod.mkCrcFun(0x18005, rev=True, initCrc=0xFFFF, xorOut=0x0000)
        readcrcout = hex(crc16(unhexlify(read))).upper()
        str_list = list(readcrcout)
        if len(str_list) == 5:
            str_list.insert(2, '0')  # 位数不足补0,在列表中下标为2的加入元素0
        crc_data = "".join(str_list)
        read = read.strip() + crc_data[4:] + crc_data[2:4]
        return read
    except:
        # print("crc校验出错'")
        logging.warning('crc校验出错')

flag_value = True
def modbus_getdate(slave_id, start_addr, date_len):
    try:
        master = modbus_rtu.RtuMaster(serial.Serial(port=PORT,
                                                    baudrate=38400,
                                                    bytesize=8,
                                                    parity='N',
                                                    stopbits=1,
                                                    xonxoff=0))
        # # logger = modbus_tk.utils.create_logger(name="console", record_format="%(message)s")
        master.set_timeout(3)
        master.set_verbose(True)
        # holding_date = master.execute(slave_id, cst.READ_HOLDING_REGISTERS, start_addr, date_len)
        # 功能码03
        print("slave_id = ",slave_id)
        holding_date = master.execute(slave=slave_id,function_code=cst.READ_HOLDING_REGISTERS,quantity_of_x=date_len,starting_address=start_addr)
        holding_data125 = list()
        for i in range(len(holding_date)):
            holding_data125.append('%04x' % (holding_date)[i])  # append()在Tmp1列表末尾添加新的对象
        all_holding_data = '0103' + '%02x' % (date_len * 2) + ''.join(holding_data125)  #
        # return str(all_holding_data)
        return crc16Add(all_holding_data) #这里crc校验了,如果单纯的看数据可以不校验
    
    except modbus_tk.modbus_rtu.ModbusInvalidResponseError as err:
        # print(err)
        logging.warning(err)

def get_s16(val):
    '''
    作用为解析16进制有符号数,值得注意的是modbus poll是不支持有符号数的,一会先讲个modbus poll的用法
    '''
    if val > 65536:
        return val/100 
    
    elif val > 32768:
        #因为我传的数是需要有2位小数的,但是16进制中没有小数点的概念,所以数本身扩大100倍,然后做处理再除以100,就得到小数点后2位
        return (val - 65536)/100
    else:
        return val/100

def f_analysis(x):
    '''
    解析4位一个的16进制数
    '''
    les = len(x)
    print(les,'数据长度')
    for i in range(les):
        if i % 4  == 0:
            # print(i,j)
            datas = int(x[i:i+4],16)
            print(i,get_s16(datas),datas) # i代表循环位置,get_s16()为解析16进制有符号数,datas为16进制数



if __name__ == '__main__':
    PORT = 'COM1'
    flag = True
    for i in range(2):
        if flag:
            da = modbus_getdate(slave_id=2,start_addr=0,date_len=10)
            
            print(da) # modbus取出的值
            # master.execute(slave=1, function_code=cst.WRITE_MULTIPLE_REGISTERS, starting_address=0,
            #                data_format='0')
            f_analysis(da[6:-4])
            # 不需要前6个和后四个原因是,前6个值是我为了协议拼接的,后四个是crc校验生成的,所以它们不是数据,不需要。

modbus仿真器读取RS485数据_第5张图片

修改寄存器的值

参考
https://www.cnblogs.com/muyi23333/articles/13533395.html
http://blog.sina.com.cn/s/blog_45eaa01a0102ykbe.html
配合串口助手
分别调试modbus poll和modbus slave。
重点注意在Modbus Poll 和 Modbus Slave联合测试中,修改modbus slave中值时首先要将数据格式改为十六进制。
modbus仿真器读取RS485数据_第6张图片
modbus仿真器读取RS485数据_第7张图片

你可能感兴趣的:(RS485仿真,modbus,stm32,modbus)