2.13 haas506开发教程-高级组件库-modbus

本文详细介绍了如何使用mbslave软件进行Modbus从机设置,并通过Python的modbus库进行数据读写操作。包括设置SlaveID、功能、地址和数据格式,以及读取保持寄存器、写入数据、读取多个输入寄存器的步骤。同时,提供了多个实际操作案例,展示了如何读写寄存器并分析日志输出。
摘要由CSDN通过智能技术生成

1.mbslave仿真软件的使用

需要先下载mbslave这个软件
链接: lmbslave官网.
(1)打开仿真软件

(2)点击setup进行slave definition

  在slave definition中设置Slave ID(modbus从机ID)、Function(功能)、Address(地址)、Quantity(寄存器个数)、数据显示的格式等。

(3)编辑寄存器的值
  双击当前值,跳出一个Edit Register编辑框,修改寄存器的值

  全部修改后如下图所示:
    当前数据显示是无符号整型格式,若想修改数据的显示格式,可以点击软件窗口栏中的”Display"选择一个合适的数据格式。

    例如选择“HEX"之后,数据显示如下图所示:

(4)Connection连接配置
  点击软件窗口栏中的Connection选项,进行连接配置。

  配置项:Connection选择”Serial Port“,Port需要选择设备的RS485的串口端口号,例如当前设备的RS485的端口号为COM26(从我的电脑-设备管理器获取),那么Port就选择Port26。波特率选择9600(Modbus采用串口通信时的串口波特率,默认为 9600)、数据位选择"8 Data bits"、奇偶校验选择”None Parity-不校验"、停止位选择"1 stop bit"。

  详细的配置项如下图所示:

  设置完毕

2.案例一

  对保持寄存器(holdRegister)进行数据读取和数据写入

烧录代码

  • main.py
import modbus
import utime as time
time.sleep(5)
#初始化modbus:RS485串口id为2,波特率为9600,奇偶校验为0,响应超时为1000ms
modbus.init(2,9600,0,1000)
#建立20个字节的数组
readBuf=bytearray(20)
#读保持寄存器:设备ID是1,寄存器起始地址为0,连续读入10个寄存器数据, 响应超时为1000ms
modbus.readHoldingRegisters(1,0,10,readBuf,1000)
print('read data from register:',readBuf)
#写保持寄存器:设备ID是1,寄存器地址为0,往地址为0的寄存器写入的数据为200, 响应超时1000ms
time.sleep(5)
modbus.writeHoldingRegister(1,0,200,1000)
modbus.readHoldingRegisters(1,0,10,readBuf,1000)
print("read register again:",readBuf)
#关闭modbus
modbus.deinit()
  • board.json
{
    "name": "haas506",
   "version": "1.0.0",
   "io": {            
      "serial1":{
        "type":"UART",
        "port":0,
        "dataWidth":8,
        "baudRate":115200,
        "stopBits":1,
        "flowControl":"disable",
        "parity":"none"
      },
      "serial2":{
        "type":"UART",
        "port":1,
        "dataWidth":8,
        "baudRate":115200,
        "stopBits":1,
        "flowControl":"disable",
        "parity":"none"
      },
      "serial3":{
        "type":"UART",
        "port":2,
        "dataWidth":8,
        "baudRate":115200,
        "stopBits":1,
        "flowControl":"disable",
        "parity":"none"
      }
   },
   "debugLevel": "ERROR",
   "repl":"enable",
   "replPort":0
  
  }
   
  • 日志输出
    打开串口助手,查看打印的日志信息
read data from register: bytearray(b'\x00\x00\xff\xff\x01\x00\xff\xff\x02\x00\xff\xff\x03\x00\xff\xff\x04\x00\xff\xff')
read register again: bytearray(b'\xc8\x00\xff\xff\x01\x00\xff\xff\x02\x00\xff\xff\x03\x00\xff\xff\x04\x00\xff\xff')

注意:每个寄存器包含高低2个字节,寄存器数据按照大端字节序排列,大端就是一个数据的低字节在高地址,高字节在低地址。例如地址为0的寄存器的数据是0x00C8,那么输出的时候,先输出C8然后输出00。

3.案例二

  修改多个寄存器的值

  • main.py
  import modbus
  import utime
  utime.sleep(5)
  #修改前五个寄存器值,每个寄存器包含高低2个字节  
  #注意:(寄存器数据按照大端字节序排列) 大端就是一个数据的低字节在高地址,高字节在低地址
  modbus.init(2,9600,0,1000)
  readBuf=bytearray(10)
  #读保持寄存器:设备ID是1,寄存器起始地址为0,连续读入5个寄存器数据, 响应超时为1000ms
  modbus.readHoldingRegisters(1,0,5,readBuf,1000)
  print('read data from register:',readBuf)
  print("write data into register...")
  writeBuf=bytearray([0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00])
  #写多个保持寄存器:设备ID是1,寄存器的起始地址为0,待写入寄存器的数据为200, 响应超时1000ms
  ret=modbus.writeMultipleHoldingRegisters(1, 0, 5, writeBuf, 1000)
  print("----ret=",ret)
  # ----ret= (0, 0, 5, 0)
  #读保持寄存器:设备ID是1,寄存器起始地址为0,连续读入5个寄存器数据, 响应超时为1000ms
  modbus.readHoldingRegisters(1,0,5,readBuf,1000)
  print("read register again:",readBuf)
  modbus.deinit()
  • board.json
{
    "name": "haas506",
   "version": "1.0.0",
   "io": {            
      "serial1":{
        "type":"UART",
        "port":0,
        "dataWidth":8,
        "baudRate":115200,
        "stopBits":1,
        "flowControl":"disable",
        "parity":"none"
      },
      "serial2":{
        "type":"UART",
        "port":1,
        "dataWidth":8,
        "baudRate":115200,
        "stopBits":1,
        "flowControl":"disable",
        "parity":"none"
      },
      "serial3":{
        "type":"UART",
        "port":2,
        "dataWidth":8,
        "baudRate":115200,
        "stopBits":1,
        "flowControl":"disable",
        "parity":"none"
      }
   },
   "debugLevel": "ERROR",
   "repl":"enable",
   "replPort":0
  
  }
   
  • 日志
read data from register: bytearray(b'\x00\x00\xff\xff\x01\x00\xff\xff\x02\x00')
write data into register...
read register again: bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
  • 原始数据表
  • 修改后的数据表

4.案例三

  读取多个输入寄存器(InputRegisters)的值

在仿真软件中如下设置:
(1)创建一张表

(2)在slave definition中,选择Function中的 input Registers,注意当前设备的id是1。

(3)适当修改几个寄存器的值

  • main.py
import modbus as mb
import utime as time
def modbus_test():
    #初始化串口2-->RS485,波特率9600,奇偶校验为0,超时1000ms 
    mb.init(2, 9600, 0, 1000)
    readBuf = bytearray(10)
    #params:设备Id,寄存器起始地址, 所要读取的寄存器个数, readBuf, 超时时间设置
    ret = mb.readInputRegisters(1, 0, 5, readBuf, 200)
    print(ret)
    print('readBuf:',readBuf)
    mb.deinit()
    
if __name__ == '__main__':
    while True:
        time.sleep(1)
        modbus_test()    
  • board.json
{
    "name": "haas506",
   "version": "1.0.0",
   "io": {            
      "serial1":{
        "type":"UART",
        "port":0,
        "dataWidth":8,
        "baudRate":115200,
        "stopBits":1,
        "flowControl":"disable",
        "parity":"none"
      },
      "serial2":{
        "type":"UART",
        "port":1,
        "dataWidth":8,
        "baudRate":115200,
        "stopBits":1,
        "flowControl":"disable",
        "parity":"none"
      },
      "serial3":{
        "type":"UART",
        "port":2,
        "dataWidth":8,
        "baudRate":115200,
        "stopBits":1,
        "flowControl":"disable",
        "parity":"none"
      }
   },
   "debugLevel": "ERROR",
   "repl":"enable",
   "replPort":0
  
  }
   
  • 日志
    代码执行过程中会输出两个值,分别是readInputRegisters()函数的状态返回值和前5个寄存器中的值
(0, 10)
readBuf: bytearray(b'\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00')
(0, 10)
readBuf: bytearray(b'\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00')
(0, 10)
......

5.class-modbus

  • modbus.init(uartId,Baud,Parity,timeout)
    • 作用:初始化modbus
    • 参数:id,Baud,Parity,timeout
    • 返回:0成功
参数说明
uartId串口id,TTL的id是0,RS232是1,RS485是2
Baud设置波特率数值
Parity设置奇偶校验,0代表不校验,1代表奇校验,2代表偶校验
timeout设置响应超时时间,单位ms
  • modbus.deinit()

    • 作用:关闭modbus
    • 参数:无
    • 返回:0成功
  • modbus.writeHoldingRegister(id,regAddr,data,timeout)

    • 作用:写保持寄存器,往指定设备的某个寄存器内写入数据
    • 参数:id,regAddr,data,timeout
    • 返回:成功返回一个元组数据->(0, regAddr, data, 0)
参数说明
id设备id
regAddr寄存器地址
data待写入寄存器的数据
timeout设置响应超时时间,单位ms
  • modbus.readHoldingRegisters(id,regStartAddr,num,readBuf,timeout)

    • 作用:读保持寄存器,从某个寄存器开始,连续读取指定个数寄存器的数据
    • 参数:id,regStartAddr,num,readBuf,timeout
    • 返回:成功返回一个元组数据
参数说明
id设备id
regStartAddr寄存器起始地址
num要读取的寄存器个数
readBuf所读取的寄存器数据
timeout设置响应超时时间,单位ms
  • modbus.writeMultipleHoldingRegisters(id,regStartAddr,num,writeBuf,timeout)
    • 作用:写多个保持寄存器,从某个寄存器开始,连续写入指定个数寄存器的数据
    • 参数:id,regStartAddr,num,writeBuf,timeout
    • 返回:成功返回一个元组数据
参数说明
id设备id
regStartAddr寄存器起始地址
num要写入的寄存器个数
writeBuf待写入的寄存器数据
timeout设置响应超时时间,单位ms
  • modbus.readInputRegisters(id,regStartAddr,num,readBuf,timeout)
    • 作用:向从机读取多个输入寄存器的值
    • 参数:id,regStartAddr,num,readBuf,timeout
    • 返回:成功返回一个元组数据(state,len(readbuf)),即modbus状态码和读取到的数据的字节数
参数说明
id设备id
regStartAddr寄存器起始地址
num待读寄存器的数量,表示操作多少个寄存器
readBuf读寄存器获得的数据
timeout设置响应超时时间,单位ms
  • modbus奇偶校验
常量说明
modbus.PARITY_NONE0串口不使用奇偶校验
modbus.PARITY_ODD1串口使用奇校验
modbus.PARITY_EVEN2串口使用偶校验
  • modbus的状态码
状态返回值说明
MB_SUCCESS0成功
MB_MUTEX_ERROR-1互斥失败
MB_INVALID_SLAVE_ADDR-2无效的地址
MB_INVALID_PARAM-3无效的参数
MB_RESPOND_EXCEPTION-4从机响应失败
MB_RESPOND_LENGTH_ERR-5从机响应长度错误
MB_RESPOND_FRAME_ERR-6从机响应帧太短或者CRC错误
MB_RESPOND_TIMEOUT-7从机响应超时
MB_CANNOT_GET_HANDLER-8分配Modbus句柄失败
MB_SLAVE_NO_RESPOND-9从机无响应
MB_FRAME_SEND_ERR-10帧发送送错误
MB_SERIAL_INIT_FAILED-11串口初始化失败
MB_SERIAL_UNINIT_FAILED-12串口反初始化失败
MB_FUNCTION_CODE_NOT_SUPPORT-13串口使用偶校验
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值