You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在无额外库的Lua中实现串口十六进制读写(等效Matlab代码)

无额外库的Lua串口十六进制读写实现(等效Matlab代码)

问题场景

需要为使用十六进制指令的设备编写程序,此前用Python/Matlab实现,现在需改用嵌入在专有软件中的Lua脚本。已有可正常运行的Matlab代码,自行尝试的Lua代码无法工作,寻求无需额外库的等效实现。

参考Matlab代码

clear all
close all
s = serial('COM9','BaudRate',115200, 'DataBits',8);

fopen(s);
% %%Specify hex codes to be transmitted
txdata = ['FF';'22';'08';'00';'19';'64';'14';'28';'3C';'50';'64';'78';'8C';'AA';'19';'19';'19';'19';'32';'32';'32';'32';'01';'02';'01';'01';'01';'01';'01';'01';'61';'1E';'00';'01';'36'];
%Convert to decimal format
txdata_dec = hex2dec(txdata);
%Write using the UINT8 data format
fwrite(s,txdata_dec,'uint8');
%Read back data in decimal format
rxdata_dec = fread(s);
% Convert data back to hexadecimal format
rxdata = dec2hex(rxdata_dec)
fclose(s)
delete(s)
clear s

尝试的Lua代码(无法正常运行)

os.execute[[mode COM9: baud=115200 parity=N data=8 stop=1]]

s = io.open("COM9","w") 
io.output(s) 
io.write(0xFF, 0x22, 0x08, 0x00, 0x19, 0x64, 0x14, 0x28, 0x3C, 0x50, 0x64, 0x78, 0x8C, 0xAA, 0x19, 0x19, 0x19, 0x19, 0x32, 0x32, 0x32, 0x32, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x61, 0x1E, 0x00, 0x01, 0x36)

io.read("all") 
io.close(s)

解决方案代码

-- 配置串口参数:波特率115200、无校验、8位数据位、1位停止位
os.execute[[mode COM9: baud=115200 parity=N data=8 stop=1]]

-- 以可读可写模式打开串口("r+"),避免仅写模式无法读取返回数据
local serial_port = io.open("COM9", "r+")
if not serial_port then
    error("无法打开串口COM9,请检查端口是否被占用或存在")
end

-- 将十六进制指令转换为二进制字节流
-- string.char()会把每个数值转为对应的UINT8字节,与Matlab的uint8格式一致
local tx_bytes = string.char(
    0xFF, 0x22, 0x08, 0x00, 0x19, 0x64, 0x14, 0x28,
    0x3C, 0x50, 0x64, 0x78, 0x8C, 0xAA, 0x19, 0x19,
    0x19, 0x19, 0x32, 0x32, 0x32, 0x32, 0x01, 0x02,
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x61, 0x1E,
    0x00, 0x01, 0x36
)

-- 发送字节流并强制刷新缓冲区,确保数据立即发送
serial_port:write(tx_bytes)
serial_port:flush()

-- 读取串口返回的所有数据("*a"表示读取全部,会阻塞直到无数据返回)
local rx_raw = serial_port:read("*a")

-- 将读取到的二进制数据转换为十六进制字符串,与Matlab的dec2hex效果一致
local rx_hex_str = ""
for i = 1, #rx_raw do
    local byte_val = string.byte(rx_raw, i)
    -- %02X 确保每个字节转为两位大写十六进制,不足补0
    rx_hex_str = rx_hex_str .. string.format("%02X ", byte_val)
end

-- 打印转换后的十六进制结果
print("串口返回的十六进制数据:")
print(rx_hex_str)

-- 关闭串口释放资源
serial_port:close()

关键注意事项

  • 串口打开模式:必须使用"r+"(可读可写)而非仅写模式"w",否则无法读取设备返回的数据;若遇到换行符转换问题,可改用二进制模式"rb+"/"wb+"。
  • 数据发送方式:Lua的io.write直接传数字会转为字符串(如0xFF变成"255"),必须用string.char()将数值转为对应字节,才能正确发送UINT8格式的二进制数据。
  • 缓冲区刷新:发送数据后调用flush(),避免数据滞留在输出缓冲区,确保设备能立即收到指令。
  • 数据转换:用string.byte()提取二进制数据的每个字节,再通过string.format("%02X", ...)转为标准两位十六进制字符串,与Matlab的dec2hex输出格式匹配。

内容的提问来源于stack exchange,提问作者BenSijo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 15:23:10