我是lua的新手,我试图从端口ttyACM0接收数据,我可以通过以下方式写入端口:
wserial = io.open("/dev/ttyACM0","w")
wserial:write("hellloooo")
wserial:flush()
我想,因为我可以用与写入文件相同的方式写入它,我可以像读取文件一样读取它。但是当我尝试阅读它时(使用下面的代码),我最终会陷入无限循环。
rserial=io.open("/dev/ttyACM0","r")
while chaine==nil do
chaine=rserial:read()
rserial:flush()
end
print(chaine)
所以我的问题是我做错了什么,如何从端口读取ttyACM0?
答案 0 :(得分:2)
这里有两种线路缓冲:一种在C库中,你可以避免使用:read(1)
,如评论中提到的@Advert,以及终端驱动程序本身的另一种。您可以使用stty
命令行实用程序(stty -F /dev/ttyACM0 -icanon
)或终端驱动程序在终端驱动程序中禁用输入行缓冲。使用luaposix(未经测试的代码):
local p = require( "posix" )
local rserial = assert( io.open( "/dev/ttyACM0", "r" ) )
local fd = assert( p.fileno( rserial ) )
local function table_copy( t )
local copy = {}
for k,v in pairs( t ) do
if type( v ) == "table" then
copy[ k ] = table_copy( v )
else
copy[ k ] = v
end
end
return copy
end
-- get current settings
local saved_tcattr = assert( p.tcgetattr( fd ) )
local raw_tcattr = table_copy( saved_tcattr )
-- clear ICANON bits from local flags using Lua 5.2 bit32 module
raw_tcattr.lflag = bit32.band( raw_tcattr.lflag, bit32.bnot( p.ICANON ) )
-- apply modified settings
assert( p.tcsetattr( fd, p.TCSANOW, raw_tcattr ) )
local c = rserial:read( 1 )
print( c )
-- restore default settings afterwards
p.tcsetattr( fd, p.TCSANOW, saved_tcattr )
rserial:close()
还有一个specialized C module用于处理Lua中的串行端口,最新未发布的LuaSocket版本具有处理串行端口的代码(但在默认构建中禁用它)。 / p>
答案 1 :(得分:-1)
我不会回答您做错了什么,而是基于一个1的答案here,我在Windows环境中做到了:
-- You can generate PowerShell script at run-time
local script = [[
$port= new-Object System.IO.Ports.SerialPort COM78,115200,None,8,one
$port.open()
$port.WriteLine('serialRequest')
$port.ReadLine() > 'c:\\temp\\serialResponse.txt'
$port.Close()
]]
-- Now create powershell process and feed your script to its stdin
local pipe = io.popen("powershell -command -", "w")
pipe:write(script)
pipe:close()
不太好,因为必须从文件中获取响应,但是可以。