Lua, and accessing nodes in /dev/ (Lua in Linux)...

classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|

Lua, and accessing nodes in /dev/ (Lua in Linux)...

Matthew Percival
G'Day,

        I was trying to write a simple Lua script to check modem status; for a
test script, I simply wanted to send `AT' and check if I receive `OK' in
return. I have been doing it like this:

tty = io.open("/dev/ttyS0", "rw")
tty:write("AT\n")
if (tty:read("*line") ~= "OK") then
        print "Modem Failed!\n"
else
        print "Modem OK!\n"
end
tty:close()

        However, it just blocks at the read, never receiving anything back.  My
first thought is that it is missing the OK, but I was also wondering if
it were because io.open were not compatible with device nodes: when I
checked liolib.c, I saw that it uses fopen() (and thereby everything
uses FILE*), when I need it to use open().

        Does anyone know if it is possible to do this in Lua?  I would imagine
I would would need to write a different io library set for file
descriptors (in place of the FILE* library currently used), but even if
I did this I am not sure whether that would be enough or not.

        -- Matthew

Reply | Threaded
Open this post in threaded view
|

Re: Lua, and accessing nodes in /dev/ (Lua in Linux)...

D Burgess-4
 try

tty:setvbuf("no")

>         Does anyone know if it is possible to do this in Lua?  I would imagine
> I would would need to write a different io library set for file
> descriptors (in place of the FILE* library currently used), but even if
> I did this I am not sure whether that would be enough or not.

You might try luafs from the kepler project (except I found the
library inadequate
for my uses).

DB
Reply | Threaded
Open this post in threaded view
|

Re: Lua, and accessing nodes in /dev/ (Lua in Linux)...

Brendan Dowling
In reply to this post by Matthew Percival
First, you might need to send it a \r instead of a \n.  I forget how
modems work, it's been a while.
Also, there's probably something you need to do to set the TTY speed.
Also, if you don't actually have a modem hooked up, it will block
forever waiting to read something.
For something low-level like this, why not do it in C where you have all
the tcgetattr(), tcsetattr(), cfsetispeed(), cfsetospeed(), et cetera.



Brendan Dowling





Matthew Percival wrote:

>G'Day,
>
> I was trying to write a simple Lua script to check modem status; for a
>test script, I simply wanted to send `AT' and check if I receive `OK' in
>return. I have been doing it like this:
>
>tty = io.open("/dev/ttyS0", "rw")
>tty:write("AT\n")
>if (tty:read("*line") ~= "OK") then
> print "Modem Failed!\n"
>else
> print "Modem OK!\n"
>end
>tty:close()
>
> However, it just blocks at the read, never receiving anything back.  My
>first thought is that it is missing the OK, but I was also wondering if
>it were because io.open were not compatible with device nodes: when I
>checked liolib.c, I saw that it uses fopen() (and thereby everything
>uses FILE*), when I need it to use open().
>
> Does anyone know if it is possible to do this in Lua?  I would imagine
>I would would need to write a different io library set for file
>descriptors (in place of the FILE* library currently used), but even if
>I did this I am not sure whether that would be enough or not.
>
> -- Matthew
>
>  
>

Reply | Threaded
Open this post in threaded view
|

Re: Lua, and accessing nodes in /dev/ (Lua in Linux)...

David Given
In reply to this post by Matthew Percival
On Wednesday 08 February 2006 23:25, Matthew Percival wrote:
[...]
> tty = io.open("/dev/ttyS0", "rw")
> tty:write("AT\n")
> if (tty:read("*line") ~= "OK") then

Firstly, have you set up the serial port correctly --- baud rate an such like?
(You can use the stty command to do this from the command line.) Secondly,
you'll need to ensure that all output gets flushed before you start reading.
Does calling tty:flush() after that write help?

--
+- David Given --McQ-+
|  [hidden email]    | "Home is where, when you have to go there, they
| ([hidden email]) | have to take you in." --- Cordelia Naismith
+- www.cowlark.com --+


attachment0 (196 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Lua, and accessing nodes in /dev/ (Lua in Linux)...

Matthew Percival
G'Day,

        Thanks for the responses.

        1) I tried tty:setvbuf("no"), but that seems to be 5.1 (I am using 5.0
until 5.1 stable is released)
        2) luafs. I checked this out, but it does not seem like it would help
much for this.
        3) I tried with \r, but there was no change.  You could well be right
(I suspect you may be), but there seems to be another problem in the
way.
        4) I know this is easy in Python, so I do not think I should have to
fall back to C.  If it were anything more complicated, I probably would,
but I just want a quick "check this one thing" script.
        5) I checked with stty -F /dev/ttyS0 -a, and have made a couple of
adjustments now.
        6) tty:flush() does not seem to solve the problem.

        It is still not reading back an `OK' (though if I run minicom and type
`AT' I get back an `OK').  The script now looks like this:
                os.execute("stty -F /dev/ttyS0 115200 cols 80 rows 24")
                tty = io.open("/dev/ttyS0", "rw")
                --tty:setvbuf("no") Lua 5.1 only
                tty:write("AT\r")
                tty:flush()
                if (tty:read("*line") ~= "OK") then
                        print "Modem Failed!\n"
                else
                        print "Modem OK!\n"
                end
                tty:close()

        -- Matthew

Reply | Threaded
Open this post in threaded view
|

Re: Lua, and accessing nodes in /dev/ (Lua in Linux)...

Dolan, Ryanne Thomas (UMR-Student)
I use Lua with the UMR Robotics Team to interface with several different devices such as GPS receivers, microcontrollers, etc.  So long as you don't want it to be portable, it is easy in Linux with stty:

file = "/dev/ttyUSB0";
baud = "4800";
timeout = "3";

os.execute ("stty -F " .. file .. " " .. baud .. " cread min 0 time " .. timeout);

fdin = io.open (file, "r");


On Thu, 2006-02-09 at 12:12 +1100, Matthew Percival wrote:
G'Day,

	Thanks for the responses.

	1) I tried tty:setvbuf("no"), but that seems to be 5.1 (I am using 5.0
until 5.1 stable is released)
	2) luafs. I checked this out, but it does not seem like it would help
much for this.
	3) I tried with \r, but there was no change.  You could well be right
(I suspect you may be), but there seems to be another problem in the
way.
	4) I know this is easy in Python, so I do not think I should have to
fall back to C.  If it were anything more complicated, I probably would,
but I just want a quick "check this one thing" script.
	5) I checked with stty -F /dev/ttyS0 -a, and have made a couple of
adjustments now.
	6) tty:flush() does not seem to solve the problem.

	It is still not reading back an `OK' (though if I run minicom and type
`AT' I get back an `OK').  The script now looks like this:
		os.execute("stty -F /dev/ttyS0 115200 cols 80 rows 24")
		tty = io.open("/dev/ttyS0", "rw")
		--tty:setvbuf("no") Lua 5.1 only
		tty:write("AT\r")
		tty:flush()
		if (tty:read("*line") ~= "OK") then
			print "Modem Failed!\n"
		else
			print "Modem OK!\n"
		end
		tty:close()

	-- Matthew


Reply | Threaded
Open this post in threaded view
|

Re: Lua, and accessing nodes in /dev/ (Lua in Linux)...

Matthew Percival
G'Day,

        I think I have sort of worked out why I am not reading anything back:
it does not seem the script is sending anything in the first place.  If
I do `print (tty)', I get back `file (0x8051688)', so it seems OK at
that point, but if I wrap a print() around the write() call I get this:
                nil     Bad file descriptor     9

> I use Lua with the UMR Robotics Team to interface with several
> different devices such as GPS receivers, microcontrollers, etc.  So
> long as you don't want it to be portable, it is easy in Linux with
> stty:

        I am trying to check the status of a GPS Modem, and the script will
only ever be run from Linux, so it sounds like you are doing something
very similar to what I am trying to do (which also suggests it does
work).  I tried copying your code (with minor changes for my setup), and
added a write at the end, but it returned the same error.

        -- Matthew

Reply | Threaded
Open this post in threaded view
|

Re: Lua, and accessing nodes in /dev/ (Lua in Linux)...

Dolan, Ryanne Thomas (UMR-Student)
Is it possible that your script doesn't have read/write permission on this device node?  I've had this simple problem in the past, and it is easy to overlook.

If you wanna take a look at my GPS code, we have it hosted on our SVN server:

https://robotics.umr.edu:7651/svn/lua/gps.lua
https://robotics.umr.edu:7651/svn/lua/com.lua

I don't usually like to post work I haven't tested a million times, but maybe that will help you out a bit.  Sorry it isn't commented yet; I will have someone on the team comment it for me at some point...

On Thu, 2006-02-09 at 15:19 +1100, Matthew Percival wrote:
G'Day,

	I think I have sort of worked out why I am not reading anything back:
it does not seem the script is sending anything in the first place.  If
I do `print (tty)', I get back `file (0x8051688)', so it seems OK at
that point, but if I wrap a print() around the write() call I get this:
		nil     Bad file descriptor     9

> I use Lua with the UMR Robotics Team to interface with several
> different devices such as GPS receivers, microcontrollers, etc.  So
> long as you don't want it to be portable, it is easy in Linux with
> stty:

	I am trying to check the status of a GPS Modem, and the script will
only ever be run from Linux, so it sounds like you are doing something
very similar to what I am trying to do (which also suggests it does
work).  I tried copying your code (with minor changes for my setup), and
added a write at the end, but it returned the same error.

	-- Matthew


Reply | Threaded
Open this post in threaded view
|

Re: Lua, and accessing nodes in /dev/ (Lua in Linux)...

Matthew Percival
G'Day,

> https://robotics.umr.edu:7651/svn/lua/gps.lua
> https://robotics.umr.edu:7651/svn/lua/com.lua

        Thanks a lot for those examples!  They gave me some ideas to try out,
and eventually I got it to work.  I first noticed you had separate in
and out streams: I do not understand why, but when I did that too I was
suddenly able to write --- if someone could point me to something that
would help me to understand this, it would be most appreciated!  Now I
can write, I read back an '\r' (unfortunately); if I pass over this and
read again, I get a response from the modem!  My final code is as below:

        os.execute("stty -F /dev/ttyS0 115200 cread min 0 time 3")

        ttyin = assert(io.open("/dev/ttyS0", "r"))
        ttyout = assert(io.open("/dev/ttyS0", "w"))

        ttyout:write("AT\r")
        ttyout:flush()

        ttyin:flush()
        reply = ttyin:read("*line")

        while (reply == "\r") do
           ttyin:flush()
           reply = ttyin:read("*line")
        end

        if (reply ~= "OK\r") then
           print "Modem Failed!\n"
        else
           print "Modem OK!\n"
        end

        ttyin:close()
        ttyout:close()

        There is probably a better way to do some of this, but this works at
least.

        Thank you for taking the time to lend me a hand: it has helped me a
great deal!

        -- Matthew