There are two kinds of line buffering going on here: one in the C library, which you can avoid using :read(1)
like @Advert mentioned in the comments, and another one in the terminal driver itself. You can disable input line buffering in the terminal driver using the stty
command line utility (stty -F /dev/ttyACM0 -icanon
) or e.g. using luaposix (untested code):
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()
There is also a specialized C module for handling serial ports in Lua, and the latest unreleased version of LuaSocket has code for handling serial ports (but it's disabled in default builds).
io.read()
will read until it receives a newline character. Maybe you're not sending any to it? Take a look at this lua.org/pil/21.1.html (about halfway down, there's stuff aboutio.read
). I'd try:read("*all")
or, if you know how long the message will be,:read(10)
(for 10 characters). You can always do:read(1)
to get one byte, then decide if you want more or not. – Advertcat /dev/ttyACM0
– Advert