【问题标题】:How to read from a serial port in lua如何从lua中的串口读取
【发布时间】:2014-10-01 23:27:22
【问题描述】:

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

【问题讨论】:

  • 使用io.read() 将读取直到它收到一个换行符。也许你没有发送任何给它?看看这个lua.org/pil/21.1.html(大约一半,有关于io.read 的东西)。我会尝试:read("*all"),或者,如果您知道消息的长度,:read(10)(10 个字符)。您可以随时使用:read(1) 获取一个字节,然后决定是否需要更多。
  • 谢谢回复,我试过了,还是不行。您还有其他建议吗?
  • 嗯,检查一下你是否得到了任何东西怎么样? cat /dev/ttyACM0
  • 好的,所以我尝试了我能想到的一切,但是当我执行 cat /dev/ttyACM0 时你是对的我可以成功读取文件。所以我想知道我是否可以将 python 与 lua 集成?

标签: file-io lua serial-port


【解决方案1】:

这里有两种行缓冲:一种在 C 库中,您可以避免使用 :read(1),如 cmets 中提到的 @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()

在 Lua 中还有一个 specialized C module 用于处理串行端口,而最新未发布版本的 LuaSocket 具有用于处理串行端口的代码(但在默认构建中被禁用)。

【讨论】:

  • 它说 tcgetattr 得到一个 nil 值。
  • @lana:“获得零值”是什么意思?是fdnil(由于assert( p.fileno( rserial ) ),这不应该发生在代码中),p.tcgetattr( fd ) return nil (if so assert` 也应该给你tcgetattr 的具体原因失败),或者是p.tcgetattr nil(在这种情况下你的luaposix模块太旧了)?
  • 我得到的错误是:lua: trial.lua:18: attempt to call field 'tcgetattr' (a nil value) stack traceback: trial.lua:18: in main chunk [C]: ?
  • 第 18 行是local saved_tcattr = assert( p.tcgetattr( fd ) )
  • @lana:好的,这是案例 3(luaposix 模块太旧)。从今年 5 月开始,您需要版本 32。答案中已经有指向 github 存储库的链接。不过,我建议 LuaRocks 安装 Lua 模块。
【解决方案2】:

我不会回答你做错了什么,但基于一个 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()

不是很好,因为必须从文件中获取响应,但它可以工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-04-11
    • 1970-01-01
    • 2011-03-19
    • 2010-10-03
    • 1970-01-01
    • 1970-01-01
    • 2016-04-04
    • 1970-01-01
    相关资源
    最近更新 更多