Первое работоспособное решение, которое у меня есть, - это использование сценария powershell.Он принимает параметры от Lua, включая COM-порт, скорость передачи и строку для записи.
Во-первых, вот сценарий Lua.
writeThenReadCOMinLua.lua
local comPort = "COM2"
local baud = "9600"
local dataToWrite = "Hello. Is Anyone There?"
--run the powershell script with supplied params. Spaces are important.
local file = io.popen("powershell.exe -file ./liblocal/psLibs/writeAndReadCOM.ps1
"..comPort.. " " .. baud .. " " .. dataToWrite)
--Wait for a reply (indefinitely)
local rslt = file:read("*a")
print("Response: " .. rslt)
И сценарий powershell, который нужно написать, ждет ответа.
writeAndReadCOM.ps1
$nargs = $args.Count #args is the list of input arguments
$comPortName=$args[0] #This is the com port. It has zero spaces
$baud = $args[1] #this is the numberical baud rate
#the remainder of the arguments are processed below
#Combine argument 2,3,...,n with a space because of command prompt shortfalls to pass arguments with spaces
$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
#open port if it's not yet open
IF ($port.IsOpen) {
#already open
} ELSE {
#open port
$port.Open()
}
#write the data
$port.WriteLine($dataToWrite)
#wait for a response (must end in newline). This removes the need to have a hard coded delay
$line = $port.ReadLine()
Write-Host $line #send read data out
#if the response was multiple lines, then read the rest of the buffer. If the port was just opened.
while ($port.BytesToRead -ne 0) {
$dataReturned = 1
$line = $port.ReadLine()
Write-Host $line #send read data out for the remainder of the buffer
}
$port.Close()
#IF ($dataReturned -eq 0) {'PS_NO_BYTES_TO_READ'}
Здесь происходит несколько вещей.Во-первых, последовательные данные, отправленные lua, могут содержать пробелы.К сожалению, все они разделяются терминалом на несколько аргументов, поэтому powershell отправляет их и объединяет в одну строку.Во-вторых, порт должен быть открыт для чтения или записи данных.Если какие-либо последовательные данные отправляются до того, как они открыты, эти данные теряются.
Оставшаяся проблема: Я не могу оставить порт открытым, тогда делайте что-то в Lua и периодически проверяйте портдля новых данных.Это прискорбно, потому что аппаратное обеспечение, которое я использую, иногда отправляет данные без запроса или занимает много времени, чтобы ответить всеми данными (в случае итеративной калибровки уровня).Кроме того, каждый раз, когда я открываю порт, аппаратное обеспечение перезагружается.На данный момент у меня нет хорошего решения.
Вот моя попытка исправить: создать три отдельных скрипта powershell # 1) открыть порт # 2) прочитать порт и вернуть nil в течение 500 мс, если данных не существуетв противном случае ответьте со всеми данными и # 3) закройте его.К сожалению, # 2 выдает ошибку о закрытии порта даже после запуска # 1.Я хотел бы услышать некоторые мысли, и с удовольствием обновлю этот ответ с любыми решениями.
Большое спасибо Егору за всю помощь.