Hello monks,

That is my first question and I hope to do everything properly.

I want to write an NMEA modul that reads the heading strings from a serial device. It is working properly but I'm using a tied filehandle for the strings and can't figure out how to autoflush the buffer. I have to destroy the object each time before I read. When I'm getting a value with readline I don't get the most recent value that I can see with minicom at the serial device.

On top I don't know if I created a proper filehandle in the module with gensym() and also don't know how to bless a global filehandle properly. I can't use the star notation (*)

Here's the module. I cut the part where I do checksum things etc. with the line. I'm also using the log4perl module but I replaced it with warn/die.

#!/usr/bin/perl # ### this module package GPS::NMEAserial; use strict; use warnings; # serial port communication use Device::SerialPort qw( :PARAM :STAT 0.07 ); # flush output of filehandle use IO::Handle; # create filehandles use Symbol qw( gensym ); sub new_nmea_port { my $class = shift; # open the serial port attached to control unit # $quiet parameter just for compatability my ( $port, $config_file, $quiet ) = @_; # this tests for an existing config file, # and creates one if necessary... if ( !-e $config_file ) { my $PortObj = new Device::SerialPort( $port, $quiet ) or die("Can't open $port: $!"); $PortObj->baudrate(4800); $PortObj->parity('none'); $PortObj->databits(8); $PortObj->handshake('none'); # when nmea data is available every second $PortObj->read_const_time(1100); $PortObj->read_char_time(700); $PortObj->stopbits(1); $PortObj->write_settings or undef $PortObj; $PortObj->save($config_file) or die("Can't save $config_file: $!"); # close serial port $PortObj->close or warn("Close $PortObj at $port failed: $!"); # destroy serial object # frees memory back to perl undef $PortObj; } else { print("$config_file already exists!"); } # tie filehandle to read/write from serial port (nmea device) my $fh = gensym(); tie( *$fh, 'Device::SerialPort', $config_file ) or die("Can't tie $port: $!"); my $self = bless { PortName => $port, FileHandle => $fh, ConfigurationFileName => $config_file }, $class; $self->{'FileHandle'}->autoflush(1); return $self; } # this shouldn't be necessary sub destroy_create_fh { my $self = shift; my $fh_self = $self->{'FileHandle'}; tie( *$fh_self, 'Device::SerialPort', $self->{'ConfigurationFileName'} ) or die("Can't tie $self->{'PortName'}: $!"); $self->{'FileHandle'} = $fh_self; } sub get_heading { my $self = shift; if ( !-e $self->{'PortName'} ) { warn("Device $self->{'PortName'} doesn't exist"); } $self->destroy_create_fh(); while ( my $line = readline( $self->{'FileHandle'} ) ) { print "Do something with $line"; return $line; } } 1;

Here's the script that calls the module. The device /dev/nmea is a symlink to /dev/ttyUSBX and created with an udev rule. The strings that appear look like: http://www.hemispheregps.com/gpsreference/GPHDT.htm

use strict; use warnings; use lib '/usr/local/lib'; use GPS::NMEAserial; my $nmea_unit = GPS::NMEAserial->new_nmea_port( '/dev/nmea', "/var/run/.nmea_unit.conf" ); my $heading_string = $nmea_unit->get_heading(); print "$heading_string\n"; sleep(10); my $heading_string2 = $nmea_unit->get_heading(); print "$heading_string2 is not most recent value\n";

I tried to leave it as small as possible. Mainly following part is bugging me.

# tie filehandle to read/write from serial port (nmea device) my $fh = gensym(); tie( *$fh, 'Device::SerialPort', $config_file ) or die("Can't tie $port: $!"); my $self = bless { PortName => $port, FileHandle => $fh, ConfigurationFileName => $config_file }, $class; $self->{'FileHandle'}->autoflush(1); return $self;

How can I create a filehandle for this module that it will always return me the last line from the serial port output? Or should I use a different approach for serial ports when using it in a module?


In reply to serial port tied filehandle autoflush by kkaiser

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.