kkaiser has asked for the wisdom of the Perl Monks concerning the following question:
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?
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: serial port tied filehandle autoflush
by Anonymous Monk on Dec 04, 2014 at 13:58 UTC | |
by kkaiser (Initiate) on Dec 05, 2014 at 07:56 UTC | |
by Anonymous Monk on Dec 05, 2014 at 13:51 UTC | |
|
Re: serial port tied filehandle autoflush
by Anonymous Monk on Dec 05, 2014 at 13:11 UTC | |
by kkaiser (Initiate) on Dec 05, 2014 at 14:51 UTC |