Modbus 3.0.8
L Master 3.0 版本以后,机器人支持作为 Modbus 主站(客户端),以便和 PLC(可编程逻辑控制器)连接进行编程。支持基于网络连接的 TCP/Socket 底层协议和 RTU 串口协议。
注意
由于通信不稳定等原因,可能导致错误发生。大多数情况下,需要使用错误处理机制来捕获错误,防止异常退出。
兼容说明
在老版本的 L Master 2.x 中,预置了一个开源库来处理 Modbus 通讯:
require('libmodbus')
当串口或者网络通讯异常时,该库有可能会导致系统卡死、崩溃。该用法 3.0 版本已废弃。
连接 Modbus/TCP 从站
通过 Modbus/TCP IP 连接从站。
支持 IPv4、IPv6。
示例程序
local mb = modbus.new_tcp("192.168.1.2", 10001)
连接 Modbus/RTU 从站
通过 Modbus/RTU 连接从站。
示例程序
local com1 = serial.open("/dev/ttyS1")
com1:set_timeout(200)
com1:set_baud_rate(9600)
local mb = modbus.new_rtu(com1)
连接法兰从站
通过法兰的 Modbus/RTU 连接从站。
注意
- 由于底层需要协议转发,平均每5个字节需要消耗20毫秒,请注意超时时间。
- 仅支持使用 8 位数据位、1 位停止位、无检验位。
示例程序
local mb = modbus.new_flange()
设置法兰波特率
设置法兰 Modbus 通信波特率。
注意
机箱 Modbus/RTU 串口波特率需使用 serial 模块的 set_baud_rate。
- 函数名:lua模块的函数
set_flange_baud_rate - 参数:
- baud_rate: [int] 波特率
- 返回:[bool] 是否设置成功
示例程序
set_flange_baud_rate(9600)
设置从站 ID
设置 Modbus 从站 ID。
- 函数名:[Modbus]下的方法
set_slave - 参数:
- id: [int] 从站 ID
- 返回:无
示例程序
mb:set_slave(0x01)
断开连接
断开与从站的连接。
- 函数名:[Modbus]下的方法
disconnect - 参数:无
- 返回:无
示例程序
mb:disconnect()
设置超时时间
设置通信超时时间。
- 函数名:[Modbus]下的方法
set_timeout - 参数:
- timeout: [int] 超时时间,单位毫秒(ms)。默认600ms。特殊地,法兰仅支持100~600
- 返回:无
示例程序
mb:set_timeout(500)
设置超时重传次数
设置通信超时重传次数。
- 函数名:[Modbus]下的方法
set_retry - 参数:
- retry: [int] 超时重传次数。默认0次
- 返回:无
示例程序
mb:set_retry(2)
写入单个线圈
- 函数名:[Modbus]下的方法
write_single_coil - 参数:
- addr: [int] 寄存器地址
- val: [bool] 写入的值
- 返回:无,或抛出连接错误
示例程序
mb:write_single_coil(0x0000, true)
写入多个线圈
- 函数名:[Modbus]下的方法
write_multiple_coils - 参数:
- addr: [int] 起始寄存器地址
- vals: [list[bool]] 待写入的值数组
- 返回:无,或抛出连接错误
示例程序
mb:write_multiple_coils(0x0000, {true, true, true, true, true})
读取多个线圈
- 函数名:[Modbus]下的方法
read_coils - 参数:
- addr: [int] 起始寄存器地址
- num: [int] 读取数量
- 返回:[list[bool]] 布尔数组,或抛出连接错误
示例程序
ret = mb:read_coils(0x0000, 5)
print(ret)
读取多个离散输入
- 函数名:[Modbus]下的方法
read_discrete_inputs - 参数:
- addr: [int] 起始寄存器地址
- num: [int] 读取数量
- 返回:[list[bool]] 布尔数组,或抛出连接错误
示例程序
ret = mb:read_discrete_inputs(0x0000, 5)
print(ret)
写入单个保持寄存器
- 函数名:[Modbus]下的方法
write_single_register - 参数:
- addr: [int] 寄存器地址
- val: [int] 写入的值
- 返回:无,或抛出连接错误
示例程序
mb:write_single_register(0x0090, 0x0088)
写入多个保持寄存器
- 函数名:[Modbus]下的方法
write_multiple_registers - 参数:
- addr: [int] 起始寄存器地址
- vals: [list[int]] 待写入的值数组
- 返回:无,或抛出连接错误
示例程序
mb:write_multiple_registers(0x0090, {0x0088, 0x0088})
读取多个保持寄存器
- 函数名:[Modbus]下的方法
read_holding_registers - 参数:
- addr: [int] 起始寄存器地址
- num: [int] 读取数量
- 返回:[list[int]] u16 数组,或抛出连接错误
示例程序
ret = mb:read_holding_registers(0x0090, 2)
print(ret)
读取多个输入寄存器
- 函数名:[Modbus]下的方法
read_input_registers - 参数:
- addr: [int] 起始寄存器地址
- num: [int] 读取数量
- 返回:[list[int]] u16 数组,或抛出连接错误
示例程序
ret = mb:read_input_registers(0x0080, 2)
print(ret)
示例
-- 使用Modbus/RTU
local com1 = serial.open("/dev/ttyS1")
com1:set_timeout(200)
com1:set_baud_rate(9600)
local mb = modbus.new_rtu(com1)
-- 使用Modbus/TCP
local mb = modbus.new_tcp("192.168.1.2", 10001)
-- 使用末端法兰Modbus
local mb = modbus.new_flange()
-- 配置Modbus
mb:set_timeout(500)
mb:set_slave(0x01)
-- 设置1路DO,使用pcall捕获错误
success, result = pcall(function() mb:write_single_coil(0x0000, true) end)
if not success then
print("Error: ", result)
end
-- 设置并读取5路DO,使用pcall捕获错误
success, result = pcall(function()
-- 设置5路DO
mb:write_multiple_coils(0x0000, {true, true, true, true, true})
-- 读取5路DO
mb:read_coils(0x0000, 5)
end)
if not success then
print("Error: ", result)
end
-- 读取5路DI
mb:read_discrete_inputs(0x0000, 5)
-- 设置1路AO
mb:write_single_register(0x0090, 0x0088)
-- 设置2路AO
mb:write_multiple_registers(0x0090, {0x0088, 0x0088})
-- 读取2路AO
mb:read_holding_registers(0x0090, 2)
-- 读取2路AI
mb:read_input_registers(0x0080, 2)
