使用Lua在Windows上读写串口

我的总体程序目标是使用Lua创建一个更好的3D打印机校准GUI,我很幸运已经把GUI部分搞定了。我正在尝试在我Windows 10的计算机上读写与打印机Arduino板连接的COM端口。然而,我被串口通信绊住了。目前为止,我已经将两个FTDI电缆连接在一起,并使用RealTerm(一个终端程序)进行测试,可以彼此通信,因此我知道接线正确。我使用的是ZeroBrane Studio进行开发,但还不熟悉安装库。

到目前为止,我已经尝试了以下解决方案:

  1. 尝试:嵌入powershell脚本以打开串口

结果:没有数据从端口输出,但没有生成错误

  1. 尝试:使用srdgame/librs232库

结果:require "rs232"在代码中失败,因为它找不到文件。我将SRC的内容安装到我的Lua代码所在的同一目录中,但这可能不是正确的方法。

  1. 尝试:使用Lua的本机io函数

结果:我可以使用这种方法发送数据,这是个好消息。但是,我没有看到调整端口波特率的方法。进入设备管理器并搞乱设置没有效果。它默认为115200bps。

代码:

file = io.open("COM5","wb")
io.output(file)
io.write("Hello world!")

其他选项: 我已经安装了luarocks,但无法在命令提示符中安装任何库。“错误:无法找到预期的文件ffi.lib或ffi.dll或libffi.dll用于FFI -- 您可能需要在系统中安装FFI和/或设置FFI_DIR变量”

如果任何解决方案需要库,请指导我在哪里放置文件。

提前致谢!

PS:下面是我调查的一些参考资料。

  1. posix似乎只适用于Linux

  2. lua用户组串行通信wiki。我没有理解指令和他们的推荐库过时了。

点赞
用户11032285
用户11032285

我想到的第一个可行解决方案是使用 PowerShell 脚本。它从 Lua 中获取参数,包括 COM 端口,波特率和要写入的字符串。

首先是 Lua 脚本。

writeThenReadCOMinLua.lua

local comPort = "COM2"
local baud = "9600"
local dataToWrite = "Hello. Is Anyone There?"
--使用提供的参数运行 PowerShell 脚本。空格很重要。
local file = io.popen("powershell.exe -file ./liblocal/psLibs/writeAndReadCOM.ps1
"..comPort.. " " .. baud .. " " .. dataToWrite)

--等待响应(无限期)
local rslt = file:read("*a")
print("Response: " .. rslt)

然后是写入并等待响应的 PowerShell 脚本。

writeAndReadCOM.ps1

$nargs = $args.Count #args 为输入参数的列表
$comPortName=$args[0] #这是 com 端口。它没有空格。
$baud = $args[1] #这是数值波特率
#下面处理其它的参数

#将第 2,3,...,n 个参数与空格组合,因为命令提示符不支持传递带空格的参数
$dataToWrite = ""
For ($i=2; $i -le $nargs ; $i++) {
    $dataToWrite = "$($dataToWrite) $($args[$i])"
}

#$port= new-Object System.IO.Ports.SerialPort COM2,9600,None,8,one
$port= new-Object System.IO.Ports.SerialPort $comPortName,$baud,None,8,one

#如果端口尚未打开,则打开它
IF ($port.IsOpen) {
    #已经打开
} ELSE {
    #打开端口
    $port.Open()
}

#写入数据
$port.WriteLine($dataToWrite)

#等待响应(必须以换行符结尾)。这样可以避免硬编码的延迟
$line = $port.ReadLine()
Write-Host $line #发送读取数据

#如果响应包含多条消息,则读取缓冲区中的其它内容。如果刚刚打开端口,则执行此操作。
while ($port.BytesToRead -ne 0) {
    $dataReturned = 1
    $line = $port.ReadLine()
    Write-Host $line #发送读取数据的其它内容
}

$port.Close()

#IF ($dataReturned -eq 0) {'PS_NO_BYTES_TO_READ'}

这里有几个要点。 首先,Lua 发送的串行数据可能含有空格。不幸的是,这些空格会被终端分隔成多个参数,因此 PowerShell 需要重新组合成单个字符串。 其次,必须打开端口才能读取或写入数据。如果在打开端口之前发送任何串行数据,则这些数据将丢失。

仍需解决的问题:我无法保持端口打开并在 Lua 中处理其它事情,然后定期检查端口以获取新数据。这很不幸,因为我使用的硬件有时会在没有请求的情况下发送数据,或需要很长时间才能以迭代水平校准的形式回复全部数据。此外,每次打开端口时,硬件都将重新启动。此时,我没有好的解决方案。

以下是我的解决尝试:创建三个独立的 PowerShell 脚本 #1)打开端口 #2)读取端口并在 500 毫秒内返回 nil,如果没有数据则回复所有数据 #3)关闭端口。不幸的是,#2 抛出了有关端口关闭的错误,即使#1 已运行。我很乐意听听大家的想法,并将随时更新此答案以获得任何解决方案。

非常感谢 Egor 到目前为止提供的所有帮助。

2019-02-11 06:40:33