Thanks for your response,
the serial port is a heading compass. It will give you heading strings like:
$HEHDT,123.49,T*12
$HEHDT,123.43,T*18
$HEHDT,123.43,T*18
$HEHDT,123.49,T*12
$HEHDT,123.49,T*12
$HEHDT,123.42,T*19
According to the direction from true north (0°-359.9°). The last value is a checksum.
I never write to the port. I just want the most recent heading (yes that's what I meant with last, sorry about that). The problem is the serial interface is rather fast. The output comes 10 times a second or one time a second.
In my main routine I don't want the heading that fast. I just want it when I need it. When I call my method I don't get the most recent value I get a value from the buffer.
There is many different sorts of compasses also some that output much more then just the heading. (GPS and other NMEA strings). I liked the tied filehandle approach (SerialPort::Port Methods for tied filehandles). My code already does what I want but I always retie or recreate the object. That way the first string I get is incomplete and thus invalid all the time plus the time I have to recreate the object, which is still fast but I don't believe it's the proper way.
Here's my two different Log::Log4perl output:
What I get:
05.12.2014-08:46:19 TRACE AA0009E (GPS/NMEAserial.pm:get_heading:271)>
+ Receiving ¤EHDT,217.62,T*1F
on /dev/nmea
05.12.2014-08:46:19 DEBUG AA0009E (GPS/NMEAserial.pm:get_heading:276)>
+ Not receiving valid NMEA data or cut off string: ¤EHDT,217.62,T*1F
!
05.12.2014-08:46:19 TRACE AA0009E (GPS/NMEAserial.pm:get_heading:271)>
+ Receiving $HEHDT,217.62,T*1F
on /dev/nmea
05.12.2014-08:46:19 TRACE AA0009E (GPS/NMEAserial.pm:get_heading:292)>
+ $VAR1 = bless( {
'_CKS_' => '1F',
'TrueHeading' => '217.62',
'_STRING_' => '$HEHDT,217.62,T*1F',
'_calcCKS_' => '1F',
'_ELEMENT_' => 'HDT',
'HDTT' => 'T',
'_ERROR_' => undef,
'_DEVICE_' => 'HE'
}, 'NMEAdata' );
05.12.2014-08:46:19 DEBUG AA0009E (GPS/NMEAserial.pm:get_heading:295)>
+ Received true heading: 217.62
-----------------------------------------------------
05.12.2014-08:46:20 TRACE AA0009E (GPS/NMEAserial.pm:get_heading:271)>
+ Receiving ¦L“ÉS‰•)ÓTHø$HEHDT,217.62,T*1F
on /dev/nmea
05.12.2014-08:46:20 DEBUG AA0009E (GPS/NMEAserial.pm:get_heading:276)>
+ Not receiving valid NMEA data or cut off string: ¦L“ÉS‰&#
+149;)ÓTHø$HEHDT,217.62,T*1F
!
05.12.2014-08:46:20 TRACE AA0009E (GPS/NMEAserial.pm:get_heading:271)>
+ Receiving $HEHDT,217.62,T*1F
on /dev/nmea
05.12.2014-08:46:20 TRACE AA0009E (GPS/NMEAserial.pm:get_heading:292)>
+ $VAR1 = bless( {
'_CKS_' => '1F',
'TrueHeading' => '217.62',
'_STRING_' => '$HEHDT,217.62,T*1F',
'_calcCKS_' => '1F',
'_ELEMENT_' => 'HDT',
'HDTT' => 'T',
'_ERROR_' => undef,
'_DEVICE_' => 'HE'
}, 'NMEAdata' );
05.12.2014-08:46:20 DEBUG AA0009E (GPS/NMEAserial.pm:get_heading:295)>
+ Received true heading: 217.62
-----------------------------------------------------
Heading ACU: FE0080DA000000000000
Heading degrees: 217.62
What I expect:
05.12.2014-08:43:02 TRACE AA0009E (GPS/NMEAserial.pm:get_heading:271)>
+ Receiving $HEHDT,123.47,T*1C
on /dev/nmea
05.12.2014-08:43:02 TRACE AA0009E (GPS/NMEAserial.pm:get_heading:292)>
+ $VAR1 = bless( {
'_CKS_' => '1C',
'TrueHeading' => '123.47',
'_STRING_' => '$HEHDT,123.47,T*1C',
'_calcCKS_' => '1C',
'_ELEMENT_' => 'HDT',
'HDTT' => 'T',
'_ERROR_' => undef,
'_DEVICE_' => 'HE'
}, 'NMEAdata' );
05.12.2014-08:43:02 DEBUG AA0009E (GPS/NMEAserial.pm:get_heading:295)>
+ Received true heading: 123.47
-----------------------------------------------------
05.12.2014-08:43:04 TRACE AA0009E (GPS/NMEAserial.pm:get_heading:271)>
+ Receiving $HEHDT,123.48,T*13
on /dev/nmea
05.12.2014-08:43:04 TRACE AA0009E (GPS/NMEAserial.pm:get_heading:292)>
+ $VAR1 = bless( {
'_CKS_' => '13',
'TrueHeading' => '123.48',
'_STRING_' => '$HEHDT,123.48,T*13',
'_calcCKS_' => '13',
'_ELEMENT_' => 'HDT',
'HDTT' => 'T',
'_ERROR_' => undef,
'_DEVICE_' => 'HE'
}, 'NMEAdata' );
05.12.2014-08:43:04 DEBUG AA0009E (GPS/NMEAserial.pm:get_heading:295)>
+ Received true heading: 123.48
-----------------------------------------------------
Heading ACU: FE00807B000000000000
Heading degrees: 123.48
If there's more strings involved it just will take longer when there is only one dataset per second.
So I would expect that I don't have to retie the serial port and not to get the first "bad" line all the time.
If there's another way I could get rid of the filehandle I would be open for it. Important is just that I can use something similar to readline() to process all the strings I need. Like GPS and Heading for instance:
$GPRMC,183729,A,3907.356,N,12102.482,W,000.0,360.0,080301,015.5,E*6F
$GPRMB,A,,,,,,,,,,,,V*71
$GPGGA,183730,3907.356,N,12102.482,W,1,05,1.6,646.4,M,-24.1,M,,*75
$GPGSA,A,3,02,,,07,,09,24,26,,,,,1.6,1.6,1.0*3D
$GPGSV,2,1,08,02,43,088,38,04,42,145,00,05,11,291,00,07,60,043,35*71
$GPGSV,2,2,08,08,02,145,00,09,46,303,47,24,16,178,32,26,18,231,43*77
$PGRME,22.0,M,52.9,M,51.0,M*14
$GPGLL,3907.360,N,12102.481,W,183730,A*33
$GPHDM,093.8,M*2B
$PGRMZ,2062,f,3*2D
$PGRMM,WGS 84*06
$GPBOD,,T,,M,,*47
$GPRTE,1,1,c,0*07
$GPRMC,183731,A,3907.482,N,12102.436,W,000.0,360.0,080301,015.5,E*67
$GPRMB,A,,,,,,,,,,,,V*71
I need to go through all lines to find $GPRMC and $GPHDM which is what I want.
Thanks for your help. It's really appreciated. |