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

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

I'm having trouble reading data from a serial port using Win32::SerialPort.

I'm working on writing a control program for a couple of syringe pumps. I've been able to successfully use the manufacturer's program to talk to the pump (so I'm pretty sure the pump is working properly), and I've been able to use their raw command syntax with PuTTY and there I can see the messages sent back from the pump.

Unfortunately, the things I need to do are a little too sophisticated for the manufacturer's program (or at least it would take less work to write my own program than to try to get the manufacturer's program to do what I want).

I've been digging through the Win32::SerialPort documentation and searching the web, but I don't seem to be getting any closer unfortunately.

Here's what I've been using so far for my settings:

#!/usr/bin/perl use warnings; use strict; use Win32::SerialPort; my $serial_port = new Win32::SerialPort('COM3'); $serial_port->handshake('none'); $serial_port->baudrate(9600); $serial_port->parity('odd'); $serial_port->databits(7); $serial_port->stopbits(1); $serial_port->buffers(256, 256); $serial_port->read_interval(0); #RI $serial_port->read_const_time(20); #RC $serial_port->write_char_time(1); #WM $serial_port->write_const_time(100); #WC $serial_port->write_settings || undef $serial_port; $serial_port->save('pump.cfg') if $serial_port;

Aside from the handshake, parity, databits, etc., I figured out the rest of these settings by comparing the initialization of my script with the start up of the manufacturer's program using PortMon. The basic settings, (parity, stopbits, etc.) I got from the manufacturer's documentation on the protocol.

The problem is this: whenever I write to the serial port, the subsequent read just echos back the command.

For example, if I try to read right after the write:

#!/usr/bin/perl use strict; use warnings; use Win32::SerialPort; use Data::Dumper; my $serial_port = start Win32::SerialPort('pump.cfg'); $serial_port->write_settings; $serial_port->write("aU\n"); # Asks pump 'a' for its version informati +on my $response = $serial_port->input; print Dumper($response); # Expected response: CV02.00.A

This should yield "CV02.00.A", but instead I get nothing ($VAR1 = '';)

Introducing a small wait gets me something, but it's just the "aU" command echoed back:

#!/usr/bin/perl use strict; use warnings; use Win32::SerialPort; use Data::Dumper; my $serial_port = start Win32::SerialPort('pump.cfg'); $serial_port->write_settings; $serial_port->write("aU\n"); # Asks pump 'a' for its version informati +on sleep(1); my $response = $serial_port->input; print Dumper($response); # Expected response: CV02.00.A

The response I get back is $VAR1 = 'aU\n';. (The '\n' is actually printed as a new line, I just added it here so as to keep this post pretty.)

I've tried the tied version with no luck:

my $serial_port = tie (*FH, 'Win32::SerialPort', 'pump.cfg') || die "C +an't tie: $^E\n"; print FH "aU\n"; sleep(1); # Same result w/ and w/o the sleep here my @response = <FH>; print join "\n", @response;

Result: aU

The straight "read" method doesn't help either:

my $serial_port = start Win32::SerialPort('pump.cfg'); $serial_port->write_settings; $serial_port->write("aU\n"); sleep(1); # Same result w/ and w/o sleep here too while (1) { my ($rb, $byte) = $serial_port->read(1); if ($rb > 0) { print $byte; } else { last; } }

Result: aU

Anyone encountered this problem before? Any thoughts on what I might try? Thanks in advance for your help!

Replies are listed 'Best First'.
Re: Reading Data from a Serial Port using Win32::SerialPort
by zentara (Archbishop) on Nov 20, 2010 at 18:06 UTC

      My earlier post had more to do with the mysterious pack function. In that case, it turned out that I could get away with not reading from the serial port so I never bothered to. Unfortunately, this time, I do have to!

      Karma...

Re: Reading Data from a Serial Port using Win32::SerialPort
by Anonymous Monk on May 12, 2011 at 14:03 UTC

    I also faced the same problem. here you have to go for "\r" instead of "\n". ie,

    $serial_port->write("aU\r");