如何在lua中从串口读取数据

我是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中读取数据?

点赞
用户3677376
用户3677376

这里涉及到两种行缓冲:一种在C库中,你可以像评论中@Advert提到的那样避免使用 :read(1);另一种在终端驱动程序本身中。你可以使用 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()

还有一个Lua串口处理的专门C模块,最新未发布版本的LuaSocket也有处理串口的代码(但默认构建中被禁用)。

2014-08-08 23:23:05
用户8785406
用户8785406

我不会回答你做错了什么,但根据 这里 的一个答案,我为 Windows 环境做了这个:

-- 您可以在运行时生成 PowerShell 脚本
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()
]]
-- 现在创建 power shell 进程并将脚本传递给它的 stdin
local pipe = io.popen("powershell -command -", "w")
pipe:write(script)
pipe:close()

不是很好的做法,因为必须从文件中获取响应,但它可行。

2020-10-16 11:20:32