After your e-mail haunted my inbox for a while, I decided to give serial ports a try in POE. It turns out that Device::SerialPort works with one easily worked-around hitch! I'll be documenting the problem with a testcase and sending a bug report to Device::SerialPort's author.

Here's a program to interact with a line-based device over a serial port. Replacing the console bits with a TCP server is left as an exercise, but most of your answers are in POE's cookbook.

#!/usr/bin/perl use warnings; use strict; use POE; use POE::Wheel::ReadWrite; use POE::Wheel::ReadLine; use Symbol qw(gensym); use Device::SerialPort; 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]; # Open a serial port, and tie it to a file handle for POE. my $handle = gensym(); my $port = tie(*$handle, "Device::SerialPort", "/dev/cu.modem"); die "can't open port: $!" unless $port; $port->datatype('raw'); $port->baudrate(4800); $port->databits(8); $port->parity("none"); $port->stopbits(1); $port->handshake("rts"); $port->write_settings(); # Start interacting with the GPS. $heap->{port} = $port; $heap->{port_wheel} = POE::Wheel::ReadWrite->new( Handle => $handle, Filter => POE::Filter::Line->new( InputLiteral => "\x0D\x0A", # Received line endings. OutputLiteral => "\x0D", # Sent line endings. ), InputEvent => "got_port", ErrorEvent => "got_error", ); # Start a wheel to interact with the console, and prompt the user. $heap->{console} = POE::Wheel::ReadLine->new( InputEvent => "got_console", ); $heap->{console}->put("Press ^D to stop."); $heap->{console}->get("Ready: "); } # Port data (lines, separated by CRLF) are displayed on the console. sub display_port_data { my ($heap, $data) = @_[HEAP, ARG0]; $heap->{console}->put($data); } # Console input is sent to the device. sub transmit_console_data { my ($heap, $input) = @_[HEAP, ARG0]; if (defined $input) { $heap->{console}->addhistory($input); $heap->{port_wheel}->put($input); $heap->{console}->get("Ready: "); # Clearing $! after $serial_port_wheel->put() seems to work around # an issue in Device::SerialPort 1.000_002. $! = 0; return; } $heap->{console}->put("Bye!"); delete $heap->{port_wheel}; delete $heap->{console}; } # Error on the serial port. Shut down. sub handle_errors { my $heap = $_[HEAP]; $heap->{console}->put("$_[ARG0] error $_[ARG1]: $_[ARG2]"); $heap->{console}->put("bye!"); delete $heap->{console}; delete $heap->{port_wheel}; }

In reply to Re: POE & Serial Ports by rcaputo
in thread POE & Serial Ports by thekestrel

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.