Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"

stupid serial port issue

by mlibhart (Initiate)
on Oct 03, 2011 at 15:57 UTC ( #929374=perlquestion: print w/replies, xml ) Need Help??
mlibhart has asked for the wisdom of the Perl Monks concerning the following question:

I've got a weird problem I just can't lick, but I'm sure it's something dumb I'm just not thinking of. I have a device hooked to my USB which is emulating a serial port, so I've got /dev/ttyUSB0. I need to send that device a couple characters, and then the device replies with a line. If I open the /dev/ttyUSB0 for update, write my characters, then do a


where DEVICE is my file handle, I get no response from the device. I have made the file handle nonbuffered with select. This read blocks, which is fine, that's what it should do. If, from another session, I then simply echo my characters to >/dev/ttyUSB0, my blocked read gets the response line. If I split the write/read into two different perl scripts and call the read script, then call the write, that works as well. So basically what seems to be happening is that unless I'm reading the port at the time of the write, I miss the response and it's tossed out. Can anyone offer any advice? I've tried Device::SerialPort and really don't like it. It seems to foobar my port to the point where I have to unplug/replug the device (it's not a modem anyway). Thanks Monks.

Replies are listed 'Best First'.
Re: stupid serial port issue
by zentara (Archbishop) on Oct 03, 2011 at 17:26 UTC
    This is just a wild a*s guess, but it sounds familiar to the problem of making a bidirectional socket client. The idea is to fork ( or thread ) off the input from the output. The code below is for sockets, but you should be able to figure out how to open your DEVICE handle and read/write to it instead. Also, you might need to open DEVICE read/write, i.e. '+<'
    #!/usr/bin/perl -w use strict; # remove the socket code, and insert your # DEVICE open ############################# use IO::Socket; my ( $host, $port, $kidpid, $handle, $line ); ( $host, $port ) = ('localhost',1200); my $name = shift || ''; if($name eq ''){print "What's your name?\n"} chomp ($name = <>); # create a tcp connection to the specified host and port $handle = IO::Socket::INET->new( Proto => "tcp", PeerAddr => $host, PeerPort => $port ) or die "can't connect to port $port on $host: $!"; $handle->autoflush(1); # so output gets there right away print STDERR "[Connected to $host:$port]\n"; ############################ # here is the essence of what I'm proposing to try # split the program into two processes, identical twins die "can't fork: $!" unless defined( $kidpid = fork() ); # the if{} block runs only in the parent process if ($kidpid) { # copy the socket to standard output while ( defined( $line = <$handle> ) ) { print STDOUT $line; } kill( "TERM", $kidpid ); # send SIGTERM to child } # the else{} block runs only in the child process else { # copy standard input to the socket while ( defined( $line = <STDIN> ) ) { print $handle "$name->$line"; } }

    I'm not really a human, but I play one on earth.
    Old Perl Programmer Haiku ................... flash japh

      Thank you very much for the reply zentara, I think you're exactly right.

      Unfortunately my reader/writer need to know what each other are doing :) because I write a value and the device hanging off the port is then expected to send me data. Currently my reading portion only expects data when it "knows" that the writing has happened. After your advice I tackled the problem from the outside. I made a named pipe, and then just ran a simple background process

      cat /dev/mydevice > /dir/my_named_pipe

      My writing portion opens /dev/mydevice and writes there, but the reader portion then reads from /dir/my_named_pipe. Seems to work pretty well as the pipe hangs onto the data until someone actually comes along to read it. I tried opening /dev/mydevice with pipes in the open call, but it just didn't work, this does though.

      Thanks again for the help.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://929374]
Approved by Corion
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others browsing the Monastery: (3)
As of 2018-03-25 04:12 GMT
Find Nodes?
    Voting Booth?
    When I think of a mole I think of:

    Results (300 votes). Check out past polls.