The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

GPS::Lowrance - Connect to Lowrance and Eagle GPS devices

REQUIREMENTS

The following modules are required to use this module:

  Carp::Assert
  GPS::Lowrance::LSI 0.23
  Parse::Binary::FixedFormat
  Win32::SerialPort or Device::SerialPort

If you will be using the "get_plot_trails", "set_plot_trails", "set_waypoints" or "get_waypoints" methods, then you will need the following modules:

  GPS::Lowrance::Trail 0.41
  Geo::Coordinates::DecimalDegrees
  Geo::Coordinates::UTM
  XML::Generator

If you want to use the screen capture or icon download functions in GPS::Lowrance::Screen, you also need the following module:

  GD

This module should work with Perl 5.6.x. It has been tested on Perl 5.8.2.

SYNOPSIS

  use GPS::Lowrance;
  use GPS::Lowrance::Trail;

  $gps = GPS::Lowrance->connect(
            Device     => 'com1',
            BaudRate   => 57600,
          );

  $trail = $gps->get_plot_trail( plot_trail_number => 0 );

  $gps->disconnect;

DESCRIPTION

This module provides a variety of low- and high-level methods for communicating with Lowrance and Eagle GPS receivers which support the LSI 100 protocol. It also provides some utility functions for converting data.

This module is a work in progress.

Methods

connect
  $gps = GPS::Lowrance->connect(
            device     => $device_name,
            baudrate   => $baud_rate,
            parity     => $parity,
            databits   => $data_bits,
            stopbits   => $stop_bits,
            debug      => $debug_flag,
            timeout    => $timeout,
            retrycount => $retry_count,
  );

This method initiates the connection to the GPS and requests product information from the unit.

query
  $data_out = $gps->query( $cmd, $data_in );

This is a wrapper for the GPS::Lowrance::LSI/lsi_query method in GPS::Lowrance::LSI.

get_product_info
  $hashref = $gps->get_product_info

This method is called when there is a successful connection. All data is cached for subsequent calls.

get_protocol_version
  $ver = $gps->get_protocol_version;

Returns the protocol version. Known values are:

  0 = Version 1.0
  1 = Version 2.0

The value is based on the original call to "get_product_information".

get_product_id
  $prod_id = $gps->get_product_id;

Returns the product identifier. Known values are as follows:

   1 = GlobalMap        8 = Expedition II
   2 = AirMap           9 = GlobalNav 212
   3 = AccuMap         10 = GlobalMap 12
   4 = GlobalNav 310
   5 = Eagle View      12 = AccuMap 12
   6 = Eagle Explorer
   7 = GlobalNav 200   14 = GlobalMap 100

The value is based on the original call to "get_product_information".

get_screen_type
  $scn_type = $gps->get_screen_type;

The meaning of the return values:

   0 = Black Pane only
   1 = Black and Grey Pane
   2 = Packed Pixel

The value is based on the original call to "get_product_information".

get_screen_width
  $width = 1 + $gps->get_screen_width;

Returns the width of the screen (minus 1).

The value is based on the original call to "get_product_information".

get_screen_height
  $height = 1 + $gps->get_screen_height;

Returns the height of the screen (minus 1).

The value is based on the original call to "get_product_information".

get_num_of_waypoints
  $num = $gps->get_num_of_waypoints;

Returns the maximum number of waypoints that the unit can store.

The value is based on the original call to "get_product_information".

get_num_of_icons
  $num = $gps->get_num_of_icons;

Returns the maximum number of icons that the unit can store.

The value is based on the original call to "get_product_information".

get_num_of_routes
  $num = $gps->get_num_of_routes;

Returns the maximum number of routes that the unit can store.

The value is based on the original call to "get_product_information".

get_num_of_waypoints_per_route
  $num = $gps->get_num_of_waypoints_per_route;

Returns the maximum number of waypoints that a route can contain.

The value is based on the original call to "get_product_information".

get_num_of_plot_trails
  $num = $gps->get_num_of_plottrails;

Returns the maximum number of plot trails (e.g. breadcrumb trails) that a unit can store.

The value is based on the original call to "get_product_information".

get_num_of_icon_symbols
  $num = $gps->get_num_of_icon_symbols;

Get the maximum number of icon symbols that the device can support.

The value is based on the original call to "get_product_information".

get_screen_rotate_angle
  $angle = $gps->get_screen_rotate_angle;

Returns the screen rotation angle (0, 90, 180, or 270). This can be used to determine the orientation of screens captures and icons.

The value is based on the original call to "get_product_information".

get_run_time
  $time = $gps->get_run_time;

Returns the run time of the unit (in seconds).

The value is based on the original call to "get_product_information".

get_product_description
  $name = $gps->get_product_description

Returns a short description of the product.

The value of this is cached for subsequent calls.

This is not an officially documented function, and it may not be supported in all units (see "Unsupported Functions" below).

read_memory_location
  $data = $gps->read_memory_location(
     address          => $addr,
     count            => $size,
     cartridge_select => $cart );

Reads $size bytes from the memory location in cartridge $cart. A maximum of 256 bytes can be read. If you need to read larger blocks, use "read_memory" instead.

$cart is either 0, 1 or 2.

read_memory
  $data = $gps->read_memory_location(
     address          => $addr,
     count            => $size,
     cartridge_select => $cart,
     callback         => $coderef,     # optional
  );

Reads $size bytes from the memory location in cartridge $cart.

$cart is either 1 or 2.

The $coderef refers to a subroutine that is called for each block of memory read. It can be used to display the status (which is passed to it in the form of a string "total_bytes_read/total_requested"). For example,

  $data = $gps->read_memory_location(
     address          => 123456,
     count            => 2800,
     cartridge_select => 1,
     callback         =>
       sub {
        my $status = shift || "0/0";
        print STDERR $status, "\r";
       },
  );
login_to_serial_port
  $hash_ref = $gps->login_to_serial_port;
request_screen_pointer
  $hash_ref = $gps->request_screen_pointer;

Freezes the GPS display for downloading and returns pointers. The GPS will be locked until there is a call to "unfreeze_current_unit_screen".

The GPS::Lowrance::Screen module provides a wrapper routine to extract the current screen as a GD image.

unfreeze_current_unit_screen
  $gps->unfreeze_current_unit_screen;

Called to unlock the GPS display.

get_plot_trail_origin
  $hashref = $fps->get_plot_trail_origin(
    plot_trail_numer => $num,
  );

Note that returned values are in mercator meters and must be converted. (See Geo::Coordinates::MercatorMeters for conversion routines.)

This only works for devices that understand protocol version 2 ("get_protocol_version" == 1).

See "get_plot_trail", which is a wrapper routine for downloading plot trails.

get_plot_trail_deltas

The protocol specifies that no more than 40 deltas may be requested at a time.

Note that returned values are in mercator meters and must be converted. (See Geo::Coordinates::MercatorMeters for conversion routines.)

This only works for devices that understand protocol version 2 ("get_protocol_version" == 1).

See "get_plot_trail", which is a wrapper routine for downloading plot trails.

get_plot_trail_mercator_meters
  $array_ref = $gps->get_plot_trail_mercator_meters(
     plot_trail_number => $num,
     callback          => $code_ref,
  );

Retrieves the trail specified by $num (which is zero-based) as an array reference of coordinates in mercator meters:

  $array_ref = [ [ $lat_m_1, $lon_m_1 ], [ $lat_m_2, $lon_m_2 ], ... ];

It uses "get_plot_trail_origin" and "get_plot_trail_deltas" to retrieve plot trails, and convert the data to Latitude and Logitude. Thus it only works for devices that understand protocol version 2 ("get_protocol_version" == 1).

get_plot_trail
  $trail = $gps->get_plot_trail(
     plot_trail_number => $num,
     callback          => $code_ref,
  );

Retrieves the trail specified by $num (which is zero-based) as a GPS::Lowrance::Trail object.

Note the following:

  $trail->trail_num == $num+1

Coordinates are converted to decimal degrees from the native mercator meter format. Note that there may be rounding errors.

It uses "get_plot_trail_mercator_meters".

set_plot_trail_origin
  $gps->set_plot_trail_origin(
    plot_trail_number => $num,
    origin_x          => $origin_x,
    origin_y          => $origin_y,
    number_of_deltas  => $num_deltas,
  );

Sets the origin of the plot trail specified by $num. The plot origin is specified in mercator meters.

This only works for devices that understand protocol version 2 ("get_protocol_version" == 1).

See "set_plot_trail", which is a wrapper function to handle uploading trails.

set_plot_trail_deltas
  $gps->set_plot_trail_deltas(
    plot_trail_number => $trail_number,
    number_of_deltas  => $num_deltas,
    delta_x_1         => $delta_x_1,
    delta_y_1         => $delta_y_1,
    ...
    delta_x_40        => $delta_x_40,
    delta_y_40        => $delta_y_40,
  );

The protocol specifies that no more than 40 deltas may be uploaded at a time.

Note that accepted values are in mercator meters and must be converted. (See Geo::Coordinates::MercatorMeters for conversion routines.)

This only works for devices that understand protocol version 2 ("get_protocol_version" == 1).

See "set_plot_trail", which is a wrapper function to handle uploading trails.

set_plot_trail_mercator_meters
  $gps->set_plot_trail_mercator_meters(
    plot_trail_number => $num,
    plot_trail => $array_ref,
    callback   => $coderef,
  );

Sets plot trail $num to the one specified by $trail. $trail is the same format returned by "get_plot_trail_mercator_meters".

It uses "set_plot_trail_origin" and "set_plot_trail_deltas" to upload plot trails, and convert the data from Latitude and Logitude. Thus it only works for devices that understand protocol version 2 ("get_protocol_version" == 1).

set_plot_trail
  $trail = new GPS::Lowrance::Trail;

  ...

  $gps->set_plot_trail(
    plot_trail => $trail,
    callback   => $coderef,
  );

Sets a plot trail to the one specified by $trail.

It uses "set_plot_trail_mercator_meters".

get_a_waypoint
  $waypoint = $gps->get_a_waypoint( waypoint_number => $num );

Retrieves a waypoint specified by $num (which is zero-based) as a hash reference wih the following information:

  waypoint_number
  latitude (in Mercator Meters)
  longitude (in Mercator Meters)
  name (up to 13 characters long)
  status (0 = invalid, 1 = valid)
  date (number of seconds since Jan. 1, 1992)

The "mercator_meters_to_degrees" and "gps_to_unix_time" functions will convert latitude and lognitude and date fields.

For some GPS models, name may be no longer than 8 characters.

set_a_waypoint
  $gps->set_a_waypoint( %waypoint );

Sets a waypoint, using the same structure that is returned by "get_a_waypoint".

get_waypoints
  $wpts = $gps->get_waypoints(
    waypoints => [1..($gps->get_num_of_waypoints)],
    callback  => $coderef,
  );

Retrieves a set of waypoints. If no set is specified, it will retrieve all active waypoints with valid coordinates.

The returned value is a GPS::Lowrance::Waypoints object. It has the same methods as GPS::Lowrance::Trail.

Note that the waypoint number and symbol is lost in the output.

set_waypoints
  $wpts = new GPS::Lowrance::Waypoints;
  ...

  $gps->set_waypoints(
    waypoints => $wpt,
    callback  => $coderef,
    ignore_waypoint_numbers => $bool,
  );

Uploads waypoints in the unit.

get_number_of_graphical_symbols
  $num = $gps->get_number_of_graphical_symbols;

Returns the number of graphical icon symbols in the device. This is not necessarily the maximum number of icon symbols that the device can support. (See "get_num_of_icon_symbols".)

get_graphical_sumbol
  $info = $gps->get_graphical_symbol(
    icon_symbol_index => $num,
  );

Returns information about the icon symbol:

  width                  = width-1 of the icon
  height                 = height of the icon
  structure_pointer      = memory address where the icon bitmap is
  bytes_per_symbol       = amount of data

See the get_graphical_symbol function in GPS::Lowrance::Screen.

get_current_screen
  $img = $gps->get_current_screen(
    black_rgb => [0x00, 0x00, 0x00],
    grey_rgb  => [0x80, 0x80, 0x80],
    callback  => $coderef
  );

Returns a GD::Image object of the current screen on the GPS.

The black_rgb and grey_rgb values are optional. They specify the screen colors used. Default values are shown in the example.

get_icon_graphic
  $img = $gps->get_icon_graphic(
    icon_symbol_index => $icon_num,
    black_rgb => [0x00, 0x00, 0x00],
    grey_rgb  => [0x80, 0x80, 0x80],
    callback  => $coderef
  );

Returns a GD::Image object of the icon specified by icon_symbol_index.

disconnect
  $gps->disconnect;

Disconnects the serial connection.

Functions

The following functions are exported by default:

gps_to_unix_time
  my $time = gps_to_unix_time( $waypoint->{date} );

Converts a GPS date (such as from a waypoint) to a Unix date.

unix_to_gps_time
  $waypoint->{date} = unix_to_gps_time( time )

Converts Unix date to a GPS date.

mercator_meters_to_degrees
  ($lat, $lon) = mercator_meters_to_degrees( $lat_m, $lon_m );

Convert mercator meters to decimal degrees. This function is imported from Geo::Coordinates::MercatorMeters.

degrees_to_mercator_meters
  ($lat_m, $lon_m) = degrees_to_mercator_meters( $lat, $lon );

Convert decimal degrees to mercator meters. This function is imported from Geo::Coordinates::MercatorMeters.

signed_long
  $lat = signed_long( $lat );

Convert an unsigned long to a signed long.

signed_int
  $delta = signed_int( $delta );

Convert an unsigned int to a signed int.

CAVEATS

This is a beta version of the module, so there are bound to be some bugs. In the current form it is also far from complete.

This module was tested with Win32::SerialPort, although it should use Device::SerialPort on non-Windows platforms. However, this has not yet been tested.

Known Issues

The LSI-100 protocol uses mercator meters for coordinates, whereas these functions (and most mapping software) use degrees. Because of this, there will be rounding errors in converting between the formats. This means that data (e.g. trails and waypoints) which are repeatedly downloaded and uploaded will become increasingly inaccurate.

The protocol uses little-endian values, and due to some quirks in the decoding functions, they may not be converted properly on big-endian machines.

Compatability

This module should work with all Lowrance and Eagle devices which support the LSI 100 protocol. It has been tested on the following model(s):

Lowrance GlobalMap 100 (same as Eagle MapGuide Pro?)

If you have tested it on other models, please notify me.

Unsupported Functions

Because devices vary, there is no way to ensure that every device will work with every function.

GPS units may not respond if they do not support or understand a specific command. In most cases the functions will time out and return undef after several retries.

SEE ALSO

The Lowrance Serial Interface (LSI) 100 Protocol is described in a document available on the Lowrance or Eagle web sites:

  http://www.lowrance.com/Software/CyberCom_LSI100/cybercom_lsi100.asp

  http://www.eaglegps.com/Downloads/Software/CyberCom/default.htm

A low-level implementation is available in

  GPS::Lowrance::LSI

This module does not support the NMEA protocol. For one that does, see

  GPS::NMEA

Other GPS Vendors

There are other Perl modules to communicate with different GPS brands:

  GPS::Garmin

  GPS::Magellan

AUTHOR

Robert Rothenberg <rrwo at cpan.org>

Suggestions and Bug Reporting

Feedback is always welcome. Please report any bugs using the CPAN Request Tracker at http://rt.cpan.org.

COPYRIGHT AND LICENSE

Copyright (C) 2004 by Robert Rothenberg <rrwo at cpan.org>.

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.8.2 or, at your option, any later version of Perl 5 you may have available.

1 POD Error

The following errors were encountered while parsing the POD:

Around line 867:

alternative text 'GPS::Lowrance::LSI/lsi_query' contains non-escaped | or /