http://www.perlmonks.org?node_id=18663

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

Has anyone experience of using the serial ports under Windows? I'm trying to send commands to the modem and read the response. I thought that I'd read all the relevant bits in the open tutorial and I have the following code
use warnings; use Fcntl; my $tty = "COM3"; my $text = shift || "ATH0"; sysopen(COM,$tty,O_RDWR) || die "Can't open $tty $^E"; transmit("$text"); receive(); sub transmit { my $data = shift; $data .= "\r"; @ascii = unpack("C*",$data); print "transmit: [@ascii]\n"; syswrite(COM,$data); } sub receive { sysread(COM,$buf,4); @ascii = unpack("C*",$buf); print "receive: [@ascii]\n"; return $buf; }
However when I run the script it hangs on the sysread instead of returning O.K. as expected. I think the port is opening correctly, because when something else is using the port the open fails with an "Access denied" message.

Replies are listed 'Best First'.
Re: Accessing serial ports under Windows
by chromatic (Archbishop) on Jun 17, 2000 at 23:43 UTC
    You probably ought to check the return values of sysread and syswrite. They both return undef on error:
    $result = syswrite(COM, $data); if (defined $result) { print "$result bytes written\n"; } else { die "Couldn't write to port.\n"; }
    Of ourse, there's always the CPAN module Win32::SerialPort.
      I supposedly searched CPAN this afternoon and found nothing! - in my defence my twin daughters were climbing on me at the time. But you are quite correct I should not assume that the syswrite and sysread are working.
(jcwren) RE: Accessing serial ports under Windows
by jcwren (Prior) on Jun 17, 2000 at 23:50 UTC
    As chromatic mentioned, there is Win32::SerialPort. I've used this rather extensively with some Perl modules I wrote to control several amateur radio transceivers, my weather station, and some equipment I designed to interface general purpose I/O to a serial port. It works quite well, and better yet, you can port it to Linux using Device::SerialPort.

    You get a lot of control over the port, and unless you don't get too bizarre, all you need is a BEGIN code snipped to select Win32::SerialPort or Device::SerialPort based on the OS reported by $^O.

    --Chris (who wonders why the first link isn't right, and second is)
Re: Accessing serial ports under Windows
by Anonymous Monk on Jun 16, 2008 at 21:08 UTC
    I took your code, replaced $^E with $!, and it ran fine... maybe some strange quirk on your modem? Maybe for some reason there aren't 4 bytes from the modem for the script to read, so the call to sysread is blocking?
      If only I could remember what I was trying to do - but it was eight years ago...
RE: Accessing serial ports under Windows
by Odud (Pilgrim) on Jun 18, 2000 at 00:02 UTC
    See previous excuse for not searching CPAN properly! I want to do very simple stuff so hopefully this will do the job. The end result is hopefully going to be a script that will put call waiting back on the phone line after I have finished using it.