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。

  • 函数名:lua模块下[modbus]模块的函数new_tcp
  • 参数:
    1. ip: [str] 从站 IP 地址
    2. port: [int] 端口号
  • 返回:[Modbus] 从站实例,或抛出错误

示例程序

local mb = modbus.new_tcp("192.168.1.2", 10001)

连接 Modbus/RTU 从站

通过 Modbus/RTU 连接从站。

  • 函数名:lua模块下[modbus]模块的函数new_rtu
  • 参数:
    1. com: [Serial] 串口实例
  • 返回:[Modbus] 从站实例,或抛出错误

示例程序

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 位停止位、无检验位。
  • 函数名:lua模块下[modbus]模块的函数new_flange
  • 参数:无
  • 返回:[Modbus] 从站实例,或抛出错误

示例程序

local mb = modbus.new_flange()

设置法兰波特率

设置法兰 Modbus 通信波特率。

注意

机箱 Modbus/RTU 串口波特率需使用 serial 模块的 set_baud_rate

  • 函数名:lua模块的函数set_flange_baud_rate
  • 参数:
    1. baud_rate: [int] 波特率
  • 返回:[bool] 是否设置成功

示例程序

set_flange_baud_rate(9600)

设置从站 ID

设置 Modbus 从站 ID。

  • 函数名:[Modbus]下的方法set_slave
  • 参数:
    1. id: [int] 从站 ID
  • 返回:无

示例程序

mb:set_slave(0x01)

断开连接

断开与从站的连接。

  • 函数名:[Modbus]下的方法disconnect
  • 参数:无
  • 返回:无

示例程序

mb:disconnect()

设置超时时间

设置通信超时时间。

  • 函数名:[Modbus]下的方法set_timeout
  • 参数:
    1. timeout: [int] 超时时间,单位毫秒(ms)。默认600ms。特殊地,法兰仅支持100~600
  • 返回:无

示例程序

mb:set_timeout(500)

设置超时重传次数

设置通信超时重传次数。

  • 函数名:[Modbus]下的方法set_retry
  • 参数:
    1. retry: [int] 超时重传次数。默认0次
  • 返回:无

示例程序

mb:set_retry(2)

写入单个线圈

  • 函数名:[Modbus]下的方法write_single_coil
  • 参数:
    1. addr: [int] 寄存器地址
    2. val: [bool] 写入的值
  • 返回:无,或抛出连接错误

示例程序

mb:write_single_coil(0x0000, true)

写入多个线圈

  • 函数名:[Modbus]下的方法write_multiple_coils
  • 参数:
    1. addr: [int] 起始寄存器地址
    2. vals: [list[bool]] 待写入的值数组
  • 返回:无,或抛出连接错误

示例程序

mb:write_multiple_coils(0x0000, {true, true, true, true, true})

读取多个线圈

  • 函数名:[Modbus]下的方法read_coils
  • 参数:
    1. addr: [int] 起始寄存器地址
    2. num: [int] 读取数量
  • 返回:[list[bool]] 布尔数组,或抛出连接错误

示例程序

ret = mb:read_coils(0x0000, 5)
print(ret)

读取多个离散输入

  • 函数名:[Modbus]下的方法read_discrete_inputs
  • 参数:
    1. addr: [int] 起始寄存器地址
    2. num: [int] 读取数量
  • 返回:[list[bool]] 布尔数组,或抛出连接错误

示例程序

ret = mb:read_discrete_inputs(0x0000, 5)
print(ret)

写入单个保持寄存器

  • 函数名:[Modbus]下的方法write_single_register
  • 参数:
    1. addr: [int] 寄存器地址
    2. val: [int] 写入的值
  • 返回:无,或抛出连接错误

示例程序

mb:write_single_register(0x0090, 0x0088)

写入多个保持寄存器

  • 函数名:[Modbus]下的方法write_multiple_registers
  • 参数:
    1. addr: [int] 起始寄存器地址
    2. vals: [list[int]] 待写入的值数组
  • 返回:无,或抛出连接错误

示例程序

mb:write_multiple_registers(0x0090, {0x0088, 0x0088})

读取多个保持寄存器

  • 函数名:[Modbus]下的方法read_holding_registers
  • 参数:
    1. addr: [int] 起始寄存器地址
    2. num: [int] 读取数量
  • 返回:[list[int]] u16 数组,或抛出连接错误

示例程序

ret = mb:read_holding_registers(0x0090, 2)
print(ret)

读取多个输入寄存器

  • 函数名:[Modbus]下的方法read_input_registers
  • 参数:
    1. addr: [int] 起始寄存器地址
    2. 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)