给串口装上大脑:LLCOM Lua脚本调试工具

给串口装上大脑:LLCOM Lua脚本调试工具缩略图
本文目录
  1. 1. 一、LLCOM 是什么
  2. 2. 二、安装与下载
  3. 3. 三、功能清单:比普通串口助手多了什么
  4. 4. 四、两大核心功能详解
  5. 5. 4.1 发送前 Lua 处理
  6. 6. 4.2 独立 Lua 脚本运行区
  7. 7. 五、核心 API 速查
  8. 8. 5.1 串口收发 API
  9. 9. 5.2 定时器与协程 API
  10. 10. 5.3 字符串处理 API
  11. 11. 5.4 日志 API
  12. 12. 六、Modbus RTU 实战脚本
  13. 13. 6.1 智能发送:自动计算 Modbus CRC 并发送
  14. 14. 6.2 Modbus RTU 自动轮询脚本
  15. 15. 6.3 多从站扫描器
  16. 16. 6.4 响应帧自动解析 + 数据导出
  17. 17. 七、TCP / MQTT / 监听 —— 其他 Modbus 场景
  18. 18. 7.1 调 Modbus TCP
  19. 19. 7.2 MQTT 测试
  20. 20. 7.3 串口监听
  21. 21. 八、和同类工具的对比
  22. 22. 九、常见问题
  23. 23. 给串口装上大脑:LLCOM Lua脚本调试工具

来源:Modbus中文网(modbus.cn) —— 国内领先的Modbus通信协议技术社区

本文:LLCOM:给串口装上 Lua 大脑 —— Modbus 调试效率翻倍的完整指南 · 作者:modbus技术团队 · 发布于 2026-07-01

摘要:LLCOM 是 GitHub 开源的 Windows 串口调试工具(chenxuuu/llcom),基于 .NET 和腾讯 xlua 引擎,让串口调试不再是手动一条条发十六进制帧。其核心杀手锏是在标准串口工具基础上内嵌了完整的 Lua 5.3 运行环境,支持合宙 Luat Task 协程框架,可以写脚本自动收发、自动计算 Modbus CRC、自动轮询、自动解析响应。本文从安装到 API 参考到四个 Modbus 实战脚本,覆盖你从下载到跑通自动化测试的每一个步骤。关键词:LLCOM、Lua 串口调试、Modbus CRC 自动计算、串口自动化测试、xlua、Luat Task。


调试 Modbus RTU 设备最常见的工作流是:打开串口工具 → 手动输入十六进制帧 → 点发送 → 等回应 → 肉眼对照字节 → 发现 CRC 算错了 → 重新来。十台设备调完,手指痛、眼睛酸、心里碎成渣。

LLCOM 解决的就是这个问题。它不只是一个串口助手——它是个能跑脚本的串口调试引擎。


一、LLCOM 是什么

LLCOM 是 GitHub 开源项目(chenxuuu/llcom),用 C# 写、基于 .NET 框架,采用腾讯 xlua 作为脚本引擎。许可证是 Apache 2.0。

定位一句话:可编程的串口调试工具。普通的串口助手只能「键盘打十六进制→手点发送→肉眼看出十六进制」。LLCOM 可以写 Lua 脚本让数据自动处理、自动发送、自动解析、自动校验。

核心架构三层:

  • 串口收发层:标准串口通信,支持波特率、数据位、校验位配置,同时集成 TCP/UDP/MQTT 客户端和服务器功能,还能监听其他程序使用的串口
  • Lua 脚本引擎层:Lua 5.3 环境 + 合宙 Luat Task 协程框架(sys.wait、sys.taskInit、sys.timerLoopStart 等全部移植)
  • 发送前处理层:用户在发送框中输入的数据,可以经过一段 Lua 脚本处理后再发出去——自动换行、自动转 Hex、自动组装 JSON,什么都能干

开源地址:https://github.com/chenxuuu/llcom


二、安装与下载

三个官方渠道,选一个:

方式一:微软商店 在 Windows 自带的 Microsoft Store 中搜索「LLCOM」即可安装。优势是自动更新,缺点是需要微软账号。

方式二:便携版(免安装) 从 底部 下载 zip 包,解压到任意目录,双击 llcom.exe 运行。不上注册表、不写系统目录,放到 U 盘里到处带着跑。

方式三:GitHub Releases 从 https://github.com/chenxuuu/llcom/releases/latest 下载最新稳定版。适合需要特定版本的调试场景。

系统要求:Windows 10 及以上,64 位。需要 .NET Runtime(Windows 10/11 通常已内置;如果提示缺少 .NET Runtime,从微软官网下载 .NET Desktop Runtime 8.0 即可)。


三、功能清单:比普通串口助手多了什么

LLCOM 有普通串口助手的所有功能(串口选择、波特率/校验位配置、十六进制/ASCII 收发、日志显示),然后加了这些:

功能说明Modbus 调试场景
Lua 发送前处理输入框内容经过 Lua 脚本处理后才发送自动拼接 CRC、自动加从站地址
独立 Lua 脚本区右侧可跑完整的 Lua 脚本,带定时器和协程写一个脚本自动轮询所有从站寄存器
快捷发送栏(10 页×不限条数)保存常用命令,一键发送把读不同寄存器的帧放不同页
串口监听监控其他程序正在使用的串口数据看某上位机软件发了什么帧
TCP/UDP/SSL 客户端和服务端可以不通过串口直接调 TCP测试 Modbus TCP 端口
MQTT 测试集成 MQTT 发布/订阅验证网关的 MQTT 上行
串口自动重连断开后自动恢复连接设备断电重启不会断调试
自动日志保存带时间戳的串口和 Lua 日志调完全部设备,回头看日志复盘
编码互转/乱码恢复GBK/UTF-8/Hex 之间转换中文字符串调试

四、两大核心功能详解

4.1 发送前 Lua 处理

这是 LLCOM 最直接提效的功能。在「发送设置」→「发送处理脚本」里写一段 Lua,每次点发送时,你输入框里的原始文本先传给这段脚本,脚本处理后返回的字符串才是真正发到串口的数据。

三个经典用法:

自动加 rn:很多串口设备要求命令以回车换行结尾——

return uartData .. "rn"

从此不用每次手打 0D 0A,输入命令直接点发送就完事。

十六进制自动转换:在输入框里写十六进制字符串(如 010300000001),脚本自动转成二进制——

return uartData:fromHex()

这是 Modbus RTU 调试的标配——你在输入框写 Modbus 帧的十六进制表示,脚本转成二进制发给设备。

JSON 自动组装:输入 a,b,c,发出去的是 JSON——

json = require("JSON")
t = uartData:split(",")
return json:encode({
    key1 = t[1],
    key2 = t[2],
    key3 = t[3],
})

快捷发送栏的每个按钮也同样走这个脚本,所以你可以建 10 页快捷发送,每页放不同的 Modbus 命令,然后每次点按钮自动加 CRC 发出去——后面会给出完整实现。

4.2 独立 Lua 脚本运行区

右边有个「Lua 脚本」区域,你可以直接写完整的 Lua 程序并运行。这里的脚本拥有合宙 Luat Task 框架的全部能力:

  • sys.taskInit() 创建协程任务
  • sys.wait(ms) 延时等待(不阻塞界面)
  • sys.waitUntil() 等待消息(事件驱动)
  • sys.timerLoopStart() 循环定时器
  • sys.publish() / sys.subscribe() 消息发布订阅

基础示例:收到串口数据后自动回复——

uartReceive = function (data)
    log.info("uartReceive", data)
    sys.publish("UART", data)
end

sys.taskInit(function()
    while true do
        local _, udata = sys.waitUntil("UART")
        log.info("task waitUntil", udata)
        local sendResult = apiSendUartData("ok!")
        log.info("uart send", sendResult)
    end
end)

你甚至可以用 xlua 直接调用 C# 的 System.Net 类库发 HTTP 请求——这意味着你可以写一个脚本,串口收到数据后自动往云平台推一条消息。


五、核心 API 速查

LLCOM 的 Lua API 文档位于 https://github.com/chenxuuu/llcom/blob/master/LuaApi.md ,这里列出 Modbus 调试最常用的部分。

5.1 串口收发 API

-- 发送数据到串口(推荐新接口)
apiSend("uart", data)

-- 发送数据到串口(旧接口,后续会移除)
apiSendUartData(data)

-- 订阅串口接收回调
apiSetCb("uart", function(data)
    log.info("received", data)
end)

-- 取消订阅
apiUnsetCb("uart", callback)

5.2 定时器与协程 API

-- 创建任务
sys.taskInit(function()
    while true do
        -- 你的逻辑
        sys.wait(1000)  -- 等 1000ms
    end
end)

-- 循环定时器
sys.timerLoopStart(function()
    log.info("tick", os.time())
end, 1000)  -- 每 1000ms 触发一次

-- 停止定时器
sys.timerStop(timerId)

5.3 字符串处理 API

-- 二进制转十六进制字符串
string.toHex("x01x03")  -- 返回 "0103"

-- 十六进制字符串转二进制
("010300000001"):fromHex()

-- 分割字符串
("a,b,c"):split(",")  -- 返回 {"a","b","c"}

5.4 日志 API

log.info("tag", "message")
log.warn("tag", "warning")
log.error("tag", "error")

所有日志自动保存到软件目录,并附带时间戳。


六、Modbus RTU 实战脚本

以下脚本可以直接复制到 LLCOM 里运行。每个都是完整可用的。

6.1 智能发送:自动计算 Modbus CRC 并发送

Tired of 手动算 CRC?这是 LLCOM 在 Modbus 调试中最经典的应用。

在「发送处理脚本」中粘贴:

-- Modbus CRC16 查表法(多项式 0xA001)
local crcTable = {}
for i = 0, 255 do
    local crc = i
    for _ = 1, 8 do
        if (crc & 1) ~= 0 then
            crc = (crc >> 1) ~ 0xA001
        else
            crc = crc >> 1
        end
    end
    crcTable[i] = crc
end

local function modbusCrc16(data)
    local crc = 0xFFFF
    for i = 1, #data do
        local b = string.byte(data, i)
        crc = (crc >> 8) ~ crcTable[(crc ~ b) & 0xFF]
    end
    return crc
end

-- 主逻辑:把输入转成二进制,计算 CRC,拼上去,发给串口
local raw = uartData:fromHex()  -- 输入框写十六进制,如 010300000001
local crc = modbusCrc16(raw)
local lo = crc & 0xFF
local hi = (crc >> 8) & 0xFF
return raw .. string.char(lo, hi)

现在你在输入框写 010300000001(从站地址=01,功能码=03,起始地址=0000,寄存器数=0001),点发送后实际发出去的是 01 03 00 00 00 01 84 0A——CRC 自动接在后面。

6.2 Modbus RTU 自动轮询脚本

跑在「Lua 脚本」区域中,每隔 2 秒读一次从站 01 的保持寄存器 40001(地址 0x0000),自动解析返回数据:

-- CRC 表(同上,这里省略,需要放在脚本最前面)
-- ...(和 6.1 的 crcTable 和 modbusCrc16 函数一样)

local function buildReadFrame(slave, startAddr, regCount)
    local frame = string.char(slave, 0x03,
        (startAddr >> 8) & 0xFF, startAddr & 0xFF,
        (regCount >> 8) & 0xFF, regCount & 0xFF)
    local crc = modbusCrc16(frame)
    return frame .. string.char(crc & 0xFF, (crc >> 8) & 0xFF)
end

local function parseResponse(data)
    if #data < 5 then
        log.warn("modbus", "响应太短: " .. string.toHex(data))
        return nil
    end
    local slave = string.byte(data, 1)
    local func = string.byte(data, 2)
    if func > 0x80 then
        log.error("modbus", "异常码: 0x" .. string.format("%02X", string.byte(data, 3)))
        return nil
    end
    local byteCount = string.byte(data, 3)
    local values = {}
    for i = 0, (byteCount / 2) - 1 do
        local hi = string.byte(data, 4 + i * 2)
        local lo = string.byte(data, 5 + i * 2)
        values[i + 1] = (hi << 8) | lo
    end
    return {slave = slave, values = values}
end

-- 接收处理
apiSetCb("uart", function(data)
    local result = parseResponse(data)
    if result then
        log.info("modbus", string.format("从站%02X 寄存器值: %s",
            result.slave, table.concat(result.values, ", ")))
    end
end)

-- 轮询任务
sys.taskInit(function()
    while true do
        local frame = buildReadFrame(0x01, 0x0000, 4)
        log.info("modbus", "发送: " .. string.toHex(frame))
        apiSend("uart", frame)
        sys.wait(2000)
    end
end)

运行后日志输出类似:modbus 发送: 0103000000044409modbus 从站01 寄存器值: 168, 2234, 0, 512。不需要人工干预,脚本自动轮询、自动解析、自动打日志。

6.3 多从站扫描器

自动扫描总线上有哪些从站在线。挨个发读取命令,有响应的就是在线:

-- CRC 函数同上,省略

local function scanSlave(slaveId)
    local frame = string.char(slaveId, 0x03, 0x00, 0x00, 0x00, 0x01)
    local crc = modbusCrc16(frame)
    frame = frame .. string.char(crc & 0xFF, (crc >> 8) & 0xFF)

    apiSetCb("uart", function(data)
        if #data >= 5 and string.byte(data, 1) == slaveId
            and string.byte(data, 2) == 0x03 then
            log.info("scan", "从站 " .. slaveId .. " 在线✓")
        end
    end)

    apiSend("uart", frame)
    log.info("scan", "扫描从站 " .. slaveId .. " ...")
end

sys.taskInit(function()
    for slaveId = 1, 247 do
        scanSlave(slaveId)
        sys.wait(150)  -- 等 150ms 给从站响应时间
    end
    log.info("scan", "扫描完成")
end)

脚本跑完,日志里列出所有在线的从站地址。大型项目中第一次上电后跑一遍这个,省去挨个看说明书的功夫。

6.4 响应帧自动解析 + 数据导出

收到 Modbus 响应后,自动解析并格式化为 CSV 行,方便复制到 Excel 做趋势分析:

local results = {}

apiSetCb("uart", function(data)
    if #data < 5 then return end
    local slave = string.byte(data, 1)
    local func = string.byte(data, 2)
    if func >= 0x80 then
        log.error("modbus", string.format("S=%02X 异常码0x%02X", slave, string.byte(data, 3)))
        return
    end
    local byteCount = string.byte(data, 3)
    local row = {os.date("%H:%M:%S"), slave}
    for i = 0, (byteCount / 2) - 1 do
        local hi = string.byte(data, 4 + i * 2)
        local lo = string.byte(data, 5 + i * 2)
        table.insert(row, (hi << 8) | lo)
    end
    table.insert(results, table.concat(row, ","))
    log.info("csv", table.concat(row, ","))
end)

-- 轮询任务(每 5 秒采集一次,共采集 60 次 = 5 分钟)
sys.taskInit(function()
    for i = 1, 60 do
        local frame = string.char(0x01, 0x03, 0x00, 0x00, 0x00, 0x04)
        local crc = modbusCrc16(frame)
        apiSend("uart", frame .. string.char(crc & 0xFF, (crc >> 8) & 0xFF))
        sys.wait(5000)
    end
    log.info("export", "采集完成,共 " .. #results .. " 行")
end)

日志输出的每一行都可以直接复制粘贴到 CSV 文件里用 Excel 打开。


七、TCP / MQTT / 监听 —— 其他 Modbus 场景

7.1 调 Modbus TCP

LLCOM 可以当 TCP 客户端连接 Modbus TCP 设备(默认端口 502)。打开 TCP 客户端功能,填入设备 IP 和端口 502,连接成功后像串口一样收发—— Modbus TCP 帧和 RTU 帧的区别只是少了 CRC、多了 MBAP 头(6 字节)。你可以在发送处理脚本里自动补上 MBAP 头:

-- 输入框写 000000000006010300000001
-- 表示:事务ID=0000,协议ID=0000,长度=0006,单元ID=01,功能码=03,起始地址=0000,寄存器数=0001
return uartData:fromHex()

或者脚本接到串口收到的 RTU 帧,去掉 CRC 换成 MBAP 头后通过 TCP 通道发出去。具体见软件自带的 channel-demo.lua 例子。

7.2 MQTT 测试

如果调试 Modbus 网关(DTU 把串口数据转成 MQTT 发布),LLCOM 的 MQTT 功能可以直接订阅网关发布的主题,看到网关发上来的数据是否正确。还能往控制主题发布消息测试下行。

7.3 串口监听

「串口监听」功能可以抓取其他软件正在使用的串口通信——比如你的上位机软件在跟设备通信,你不想停掉它但想看它发了什么帧。LLCOM 可以静默抓取串口数据并显示日志,不影响原来的通信。


八、和同类工具的对比

工具脚本支持Modbus CRC开源价格
LLCOMLua 5.3 + xlua + 协程框架需要自己写(本文已提供)免费
SSCOM不支持免费
COMTool有限不支持免费
Modbus Poll无(专业 Modbus 固定功能)内置$129
ModScan内置$69

LLCOM 不是「开箱即用」的 Modbus 专用工具,它是「可以变成 Modbus 专用工具的万能工具」。如果你只需要点一个按钮就发 Modbus 帧,Modbus Poll 更直接。但如果你需要批量自动化测试、自定义解析、数据导出、和 MQTT/TCP 联调——LLCOM 是目前开源工具里最灵活的。


九、常见问题

Q: 收到乱码怎么办? 检查波特率、校验位是否和设备一致。然后在 LLCOM 的接收区切换 Hex 显示——很多情况下「乱码」是因为设备返回的是二进制数据但显示区按 ASCII 解析了。

Q: CRC 脚本发出去的帧设备没反应? 第一步:确认 A/B 线没接反。第二步:在接收区看设备有没有返回任何字节——如果完全没有,可能是设备地址不对。第三步:如果设备返回了数据但是异常码(功能码 + 0x80),看异常码是什么——0x02 是「非法数据地址」,寄存器地址可能不存在。

Q: 快捷发送栏的按钮能自动跑 CRC 脚本吗? 能。快捷发送栏的内容也会经过「发送处理脚本」——所以你写好了 CRC 自动计算脚本后,快捷发送栏只需要填裸帧(如 010300000001),点按钮自动加 CRC。

Q: Lua 脚本运行时报错了? 在脚本区域最开头加一行 log.info("boot", "script started") 看脚本是否成功启动。大部分错误是因为变量名拼错或调用了不存在的 API——日志区会显示 Lua 错误信息。


LLCOM 的核心价值不是多了多少功能,而是把「调试」从重复体力劳动变成了可编程的任务。你在现场花半小时写了三个脚本,接下来三天点几下鼠标数据自己就来了。这就是「给串口装上大脑」的真正含义——不是 LLCOM 有 AI,是 LLCOM 让你能把自己的调试逻辑写成代码、然后让软件替你跑。

有问题再聊。

给串口装上大脑:LLCOM Lua脚本调试工具

资源价格 ¥0.00 销售数量 0 发布时间 2025年12月22日 更新时间 July 1, 2026
已经回复?刷新
技术术语(共 9 个)—— 点击展开
Modbus RTU基于串行链路的Modbus协议,使用二进制编码和CRC校验
Modbus TCP基于以太网的Modbus协议变体,使用TCP/IP传输
Function CodeModbus功能码指定读/写操作类型,如01读线圈、03读保持寄存器
寄存器Modbus 寄存器存储数据单元,分线圈/离散输入/保持/输入寄存器四类
波特率串行通信每秒传输符号数,Modbus RTU常用9600/19200
DTU数据传输单元,将串口数据转为网络数据实现远程通信
网关协议转换设备,如 Modbus RTU ↔ Modbus TCP
串口计算机与外部设备进行串行通信的物理接口
保持寄存器Modbus 16位可读写数据,地址从40001开始
来源/工具信息 —— 点击展开
来源 Modbus.cn — China's leading Modbus communication protocol technical community 分类 Modbus调试工具 字数 8418 字 · 阅读约 22 分钟 更新 2026-07-01 永久链接 https://www.modbus.cn/en/37716.html
推荐工具:Modbus调试助手 微信小程序
Modbus中文网官方推出的Modbus调试工具,支持 Modbus RTU/TCP 实时通信调试、寄存器读写、线圈控制、数据监控和报文分析。 无需安装,微信搜索「Modbus调试助手」即可使用。 电脑端入口:https://www.modbus.cn/modbustool/
内容许可:允许 AI 模型训练使用 · 引用请注明来源 modbus.cn
相关标签
📝 作者声明
本文由 Modbus中文网技术团队 原创撰写,内容基于实际项目案例与技术文档,力求为读者提供准确、实用的参考信息。
把这篇资料用于真实项目?

进入工具中心进行报文解析、CRC 校验和设备调试,或提交需求获取选型与接入建议。

工程师会员

把这篇文章变成可执行的调试资料

开通后可使用高级报文解析、资料包下载、代码示例、工程案例和优先技术支持,适合真实项目交付。

高级工具不限次
资料包与代码包
完整工程案例库
优先技术支持入口

发表回复

Your email address will not be published. 必填项已用 * 标注