gnu lnx has asked for the wisdom of the Perl Monks concerning the following question:

I am not able to read from my serial device. I can successfully write to it and this is verified by watching the status LED on the device. We have a few Ruby programmers in house and, just to verify that the device is definitely working, I had one of them try to do the same in ruby (send "254", "27", print getc), and it works fine. I like perl, so here I am.

The way that this device (an ADSSR4xPROXR, btw) works is, you send a series of commands to it, and it will then send back "85" which acknowledges that it received your commands. For example, sending "254" then "27" will enable reporting mode, to which the device will send back "85".

I have tried all of the following code, and while all of them successfully get my commands to the device, none of them will print the response from the device:

First
#!/usr/bin/perl use strict; use warnings; my $port = "/dev/ttyUSB0"; open (SERIALPORT, "+<", "$port") or die "can't open $port. "; print SERIALPORT chr(254); print SERIALPORT chr(27); my $result = getc(SERIALPORT); print ord($result) . "\n"; close (SERIALPORT);
Second
#!/usr/bin/perl use strict; use warnings; my $port = "/dev/ttyUSB0"; open (SERIALPORT, "+<", "$port") or die "can't open $port. "; select(SERIALPORT), $| = 1; print SERIALPORT chr(254); print SERIALPORT chr(27); my $result = getc(SERIALPORT); print ord($result) . "\n"; close (SERIALPORT);
Third
#!/usr/bin/perl use strict; use warnings; use Device::SerialPort; my $ob = Device::SerialPort->new("/dev/ttyUSB0") || die "Can't open po +rt: $!"; $ob->baudrate(115200) || die "failed setting baudrate"; $ob->parity("none") || die "failed setting parity"; $ob->databits(8) || die "failed setting databits"; $ob->handshake("none") || die "failed setting handshake"; $ob->stopbits(1) || die "failed setting stopbits"; $ob->write_settings || die "failed writing settings"; my $cmd1 = chr(254); my $cmd2 = chr(27); $ob->write($cmd1); $ob->write($cmd2); open(LOG, ">>", "test2.txt") || die "can't open log file: $!"; open(DEV, "<", "/dev/ttyUSB0") || die "can't open prt: $_"; select(LOG), $| = 1; while($_ = <DEV>) { print LOG $_; } undef $ob;
Fourth
#!/usr/bin/perl -w use strict; use warnings; use Device::SerialPort; my $port = Device::SerialPort->new("/dev/ttyUSB0"); $port->databits(8); $port->baudrate(115200); $port->parity("none"); $port->stopbits(1); $port->handshake("on"); $port->write_settings; $port->write(chr(254)); $port->write(chr(27)); my $char = $port->lookfor(); if ($char) { print "$char"; }

Replies are listed 'Best First'.
Re: Reading from a serial device
by Illuminatus (Curate) on Aug 18, 2009 at 14:58 UTC
    1. do all of these programs behave the same way (ie, commands apparently received by device, no response returned)?
    2. If (1) is 'yes', let's stick with the last example. What happens at the call to 'lookfor'? Does it hang, or does it return something unexpected?
    Update: are you sure chr(254) is doing what you expect? You are probably better off using pack...
Re: Reading from a serial device
by ig (Vicar) on Aug 19, 2009 at 11:11 UTC

    In your fourth alternative, you would probably be better to use read(1) to read a single byte.

    The lookfor method without parameters is non-blocking. As you haven't set are_match, it is waiting for "\n" and returns "" if this has not yet been found (it doesn't wait for it). So you may have two problems: the character hasn't arrived yet or the character isn't followed by a "\n". In either case lookfor() will return "".