For Programmers: Free Programming Magazines  


Home > Archive > PERL POE > April 2008 > Win32::SerialPort and POE









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author Win32::SerialPort and POE
Mark Swayne

2008-04-10, 8:04 pm

Does anybody have some working code using Win32::SerialPort with POE?

I've tried to follow the example in the cookbook, but haven't been able
to get very far. I injected a FILENO method. Unfortunately, I never
seem to get any data from my comm port. Is this due to the broken
socket-only select on Windows?

My code (which is essentially the cookbook recipe minus the wheel for
terminal IO, and an injected FILENO method for Win32::SerialPort)
follows below:

#!/usr/bin/perl

use warnings;
use strict;

$| = 1;

use POE;
use POE::Wheel::ReadWrite;

use Symbol qw(gensym);
use Win32::SerialPort;
BEGIN {
package Win32::SerialPort;

sub FILENO {
my $self = shift;

# The _HANDLE value of the object contains the file descriptor that
# was returned by CreateFile() which the docs say is a file
descriptor.
my $handle = $self->{_HANDLE};
return $handle || -1;
}

}


use POE::Filter::Line;

POE::Session->create(
inline_states => {
_start => \&setup_device,
got_port => \&display_port_data,
got_console => \&transmit_console_data,
got_error => \&handle_errors,
},
);

POE::Kernel->run();
exit 0;

sub setup_device {
my ( $kernel, $heap ) = @_[ KERNEL, HEAP ];

warn "setup\n";

# Open a serial port, and tie it to a file handle for POE.
my $handle = gensym();

my $port = tie( *$handle, 'Win32::SerialPort', 'poeterm.conf' );
die "can't open port: $!" unless $port;

warn "setup has port\n";

$port->datatype('raw');
$port->baudrate(9600);
$port->databits(8);
$port->parity("none");
$port->stopbits(1);
$port->handshake('none');
$port->write_settings();

# Start interacting with the GPS.

$heap->{port} = $port;
$heap->{port_wheel} = POE::Wheel::ReadWrite->new(
Handle => $handle,
InputEvent => "got_port",
ErrorEvent => "got_error",
);

warn "setup almost done\n";
# Start a wheel to interact with the console, and prompt the user.

}

# Port data (lines, separated by CRLF) are displayed on the console.
sub display_port_data {
my ( $heap, $data ) = @_[ HEAP, ARG0 ];
print STDOUT $data;

}

# Console input is sent to the device.
sub transmit_console_data {
my ( $heap, $input ) = @_[ HEAP, ARG0 ];
# Not really.
}

# Error on the serial port. Shut down.
sub handle_errors {
my $heap = $_[HEAP];

delete $heap->{port_wheel};
}
Rocco Caputo

2008-04-28, 10:50 pm

On Apr 10, 2008, at 13:23, Mark Swayne wrote:
> Does anybody have some working code using Win32::SerialPort with POE?
>
> I've tried to follow the example in the cookbook, but haven't been
> able to get very far. I injected a FILENO method. Unfortunately, I
> never seem to get any data from my comm port. Is this due to the
> broken socket-only select on Windows?


I believe so, yes. Perl's select() is written using Windows' winsock
library, which only multiplexes sockets. Your serial port is probably
a device, so it's not eligible.

Cygwin-built Perl doesn't have this limitation, but I don't know
whether Win32::SerialPort works there.

--
Rocco Caputo - rcaputo@pobox.com
Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com