Modbus RTU/TCP

描述

Modbus,父对象为ui,无子对象。本控件支持modbus master(主站)和modbus slave(从站),支持RTU和TCP两种通讯方式。作为主站时对modbus从站的读和写我们提供了两种类型的方法,第一种是read(code, addr, nb), write(code, addr, values), writeread(code, write_addr, write_values, read_addr, read-nb), 第二种是sendRaw(data), 一般我们建议使用第一种形式,因为第二种需要了解modbus协议的完整细节。
【注意】modbus-rtu可以通过Windows模拟器来模拟 (在工程配置对话框中模拟器类型选择Windows)。一个串口控件(如device.io.com1)只能绑定一个modbus控件。


事件

  • receive: Modbus返回数据,事件函数定义:onReceive(data, flags, addr), 做为主机时:data为从机回复的结果数组(如果请求是通过sendRaw(data)发起的,返回的结果是包含CRC的原始字节数组);做为从机时:data为主机发送的包含CRC的原始字节数组,flags为标识(包含isRaw, slaveId, functionCode标识), addr为寄存器地址
  • send:Modbus主站发送数据,事件函数定义:onSend(data, flags, addr),data为从站回复的结果数组(如果请求是通过sendRaw(data)发起的,返回的结果是原始的字节数组),flags为标识(包含isRaw, slaveId, functionCode标识), addr为寄存器地址(注意:如果功能码是0x17, 先写后读寄存器,addr的低16位是写寄存器的地址,addr的高16位是读寄存的地址)
  • error:通讯出错,事件函数定义:onError(errno, reason, flags), errno为错误号,reason为错误原因字符串,flags为标识(包含isRaw, slaveId, functionCode标识)

    • 错误号与错误原因对照表: 0x01-"Illegal function"; 0x02-"Illegal data address"; 0x03-"Illegal data value"; 0x04-"Slave device or server failure"; 0x05-"Acknowledge"; 0x06-"Slave device or server is busy"; 0x07-"Negative acknowledge"; 0x08-"Memory parity error"; 0x09-"Not defined"; 0x0A-"Gateway path unavailable"; 0x0B-"Target device failed to respond"; 0x0C-"Invalid CRC"; 0x0D-"Invalid data"; 0x0E-"Invalid exception code"; 0x10-"Too many data"; 0x11-"Response not from requested slave"


属性

名称 功能说明 脚本例子
enabled 使能,默认值为true ui.form-name.modbus-name.enabled = false; // 禁用modbus
type 类型:0-RTU,1-TCP 无。不支持脚本修改
role 角色:0-Master,1-Slave 无。不支持脚本修改
serial 串口:必须先将串口控件device.io.com{x}的通讯协议设置为PassThrough(透传),否则device.io.com{x}控件和ui.form-name.modbus-name控件可能都不能正常工作。串口的参数如波特率在相应的串口控件属性设置 无。不支持脚本修改
slaveId RTU协议时,从站的ID ui.form-name.modbus-name.slaveId=10; // 设置从站ID为10
ip TCP协议时,从站的IP地址 ui.form-name.modbus-name.ip='192.168.3.5'; // 设置从站IP
port TCP协议时,从站的端口号(一般默认为502) ui.form-name.modbus-name.port=502; // 设置端口号
byteTimeout 字节超时,默认为500毫秒 ui.form-name.modbus-name.byteTimeout=500; // 设置字节超时
responseTimeout 从站响应超时,默认为500毫秒 ui.form-name.modbus-name.responseTimeout=500; // 设置响应超时
sendingInterval 控件内部有请求队列,同时发送多条请求时,发送间隔, 默认为100毫秒 ui.form-name.modbus-name.sendingInterval=200; //设置发送间隔为200ms
autoResend 自动重发,当前请求帧发送失败后自动尝试重发 ui.form-name.modbus-name.autoResend=true;//使能自动重发
retryCount 重试次数,使能autoResend属性后才生效 ui.form-name.modbus-name.retryCount=3;//设置重试次数为3
debug 调试模式:布尔类型,true:在调试器打印发送和接收的数据帧。默认为false ui.form-name.modbus-name.debug=true;//打开调试模式

方法

名称 功能说明 脚本例子
connect() TCP连接从站,返回值为布尔变量 ui.form-name.modbus-name.connect(); // tcp连接从站
connect(ip, port) TCP连接从站,返回值为布尔变量 ui.form-name.modbus-name.connect('192.168.3.5', 502); // tcp 连接从站
disconnect() 断开与从站的TCP连接,无返回值 ui.form-name.modbus-name.disconnect();//断开连接
read(code, addr, nb) 读线圈或者保持寄存器:code-功能码,addr-寄存器地址,nb-读取个数 ui.form-name.modbus-name.read(0x01, 0x130, 2); //功能码0x01读取寄存器0x130地址开始的2个线圈状态,读取结果在onReceive(data,flags)方法中接收,例如data数组的内容形式为[0x01,0x01], 表示两个寄存器的状态都为1
write(code, addr, values) 写线圈或者保持寄存器:code-功能码,addr-寄存器地址,values-设置值数组 ui.form-name.modbus-name.write(0x0F, 0x130, [1,1]); //功能码0x0F写起始地址为0x130的2个线圈状态
writeread(code, write_addr, write_values, read_addr, read-nb) 写和读:code-功能码,write_addr-写寄存器地址,write_values-写操作数组,read_addr-读寄存器地址,read-nb读取的个数 ui.form-name.modbus-name.writeread(0x17, 0x160, [0x1122, 0x3344], 0x160, 2); //先写后读
sendRaw(data) 发送原始数据帧,data为字节数组,首字节以功能码开头,中间是寄存器地址以及个数和数据,帧尾不需要添加CRC校验,如果是RTU协议控件内部会自动追加CRC(TCP协议不需要CRC) ui.form-name.modbus-name.sendRaw([0x01, 0x01, 0x30, 0x00, 0x02]);//功能码0x01读取寄存器0x130地址开始的2个线圈状态,读取结果在onReceive(data,flags)方法接收,例如data数组的内容为[0x01, 0x01, 0x03], 第1个字节为功能码,第2个字节为数据长度,第3个字节为线圈状态值(0x03表示两个线圈的状态都为1)
isRaw(flags) 返回是否本次从站回复是通过 sendRaw方法发送。需要在事件方法onReceive(data, flags)中使用 var isRaw = ui.form-name.modbus-name.isRaw(flags); // 查询回复是否为raw回复
getSlaveId(flags) 返回从站 ID 。需要在事件方法onReceive(data, flags)中使用 var slaveId = ui.form-name.modbus-name.getSlaveId(flags); //查询当前回复的从站ID
getFunctionCode(flags) 返回功能码。需要在事件方法onReceive(data, flags)中使用 var fc = ui.form-name.modbus-name.getFunctionCode(flags); //查询当前回复的功能码
setMapping(bitsAddress, bitsNb, inputBitsAddress, inputBitsNb,registerAddress, registerNb, inputRegisterAddress, inputRegisterNb) [从站]设置地址映射表,bitsAddress: 线圈寄存器地址, bitsNb: 线圈寄存器个数; inputBitsAddress:离散输入寄存器地址, inputBitsNb: 离散输入寄存器个数; registerAddress: 保持寄存器地址,registerNb:保持寄存器个数; inputRegisterAddress:输入寄存器地址, inputRegisterNb:输入寄存器个数 ui.main.modbus.setMapping(0x130, 0x16, 0x1c4, 0x16, 0x160, 0x20, 0x108, 0x20);
setBits(bytes) [从站]设置线圈状态,bytes为字节数组 ui.form-name.modbus-name.setBits([0xCD, 0x6B, 0xB2, 0x0E, 0x1B]);
setBits(index, bytes) [从站]设置线圈状态,index为寄存器的索引,bytes为字节数组 ui.form-name.modbus-name.setBits(3, [0x0E, 0x1B]);
setInputBits(bytes) [从站]设置离散输入状态,bytes为字节数组 ui.form-name.modbus-name.setInputBits([0xAC, 0xDB, 0x35]);
setInputBits(index, bytes) [从站]设置离散输入状态,index为寄存器的索引,bytes为字节数组 ui.form-name.modbus-name.setInputBits(2, [0x35]);
setRegisters(data) [从站]设置保持寄存器,data为16位数组 ui.form-name.modbus-name.setRegisters([0x022B, 0x0001, 0x0064]);
setRegisters(index, data) [从站]设置保持寄存器,index为寄存器的索引,data为16位数组 ui.form-name.modbus-name.setRegisters(2, [0x0064]);
setInputRegisters(data) [从站]设置输入寄存器,data为16位数组 ui.form-name.modbus-name.setInputRegisters([0x02AA, 0x010B, 0x55CC]);
setInputRegisters(index, data) [从站]设置输入寄存器,index为寄存器的索引,data为16位数组 ui.form-name.modbus-name.setInputRegisters(2, [0x55CC]);
getBits(address, int nb) [从站]获取线圈状态,返回值为比特位数组 ui.form-name.modbus-name.getBits(0x130, 4);
getInputBits(address, int nb) 获取离散输入状态,返回值为比特位数组 ui.form-name.modbus-name.getBits(0x1c4, 8);
getRegisters(address, int nb) [从站]获取保持寄存器,返回值为16位数组 ui.form-name.modbus-name.getRegisters(0x160, 2);
getInputRegisters(address, int nb) [从站]获取输入寄存器,返回值为16位数组 ui.form-name.modbus-name.getInputRegisters(0x108, 2);

results matching ""

    No results matching ""