如何在无额外库的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
相关产品推荐
相关产品推荐

