Win32::SerialPort and POE
Mark Swayne <[email protected]>
| Newsgroups | gmane.comp.lang.perl.poe |
|---|---|
| Message-ID | <[email protected]> |
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};
}