I'm new to lua and I'm trying to receive data from the port, ttyACM0, I can write to the port by:
wserial = io.open("/dev/ttyACM0","w")
wserial:write("hellloooo")
wserial:flush()
I thought since I can write to it in the same way as I would write to a file that I could read it in the same way as I would read a file. But when I try to read it (using the code below) I just end up in an infinite loop.
rserial=io.open("/dev/ttyACM0","r")
while chaine==nil do
chaine=rserial:read()
rserial:flush()
end
print(chaine)
So my question is what am I doing wrong, how do I read from the port, ttyACM0?
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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With