Click here to Skip to main content
15,885,546 members
Articles / Programming Languages / Java

NMEA 0183 sentence parser/builder

Rate me:
Please Sign up or sign in to vote.
4.78/5 (25 votes)
10 Dec 2013CPOL6 min read 247.6K   15K   97  
Library for working with NMEA0183 devices
using System;
using System.Collections.Generic;
using System.Windows.Forms;


namespace GNSSView
{
    // Code by Aleksandr Dikarev, dikarev-aleksandr@yandex.ru

    public partial class MainForm : Form
    {
        #region Invokers

        private void InvokeInvalidate(Control control)
        {
            if (control.InvokeRequired)
                control.Invoke((MethodInvoker)delegate { control.Invalidate(); });
            else
                control.Invalidate();
        }

        private void InvokeAddPoint(GeoPlot geoPlot, GeoCoordinate2D newPoint)
        {
            if (geoPlot.InvokeRequired)
                geoPlot.Invoke((MethodInvoker)delegate { geoPlot.AddPoint(newPoint); });
            else
                geoPlot.AddPoint(newPoint);
        }

        private void InvokeSetText(Control control, string text)
        {
            if (control.InvokeRequired)
                control.Invoke((MethodInvoker)delegate { control.Text = text; });
            else
                control.Text = text;
        }

        private void InvokeAppendText(TextBox txb, string text)
        {
            if (txb.InvokeRequired)
                txb.Invoke((MethodInvoker)delegate { txb.AppendText(text); });
            else
                txb.AppendText(text);
        }

        private void InvokeSetLines(ListBox listBox, string[] lines)
        {
            if (listBox.InvokeRequired)
                listBox.Invoke((MethodInvoker)delegate 
                { 
                    listBox.Items.Clear(); 
                    listBox.Items.AddRange(lines); 
                });
            else
            {
                listBox.Items.Clear(); 
                listBox.Items.AddRange(lines);
            }
        }

        #endregion

        #region Properties

        GNSSReceiverWrapper gnssWrapper;
        SettingsProviderXML<SettingsContainer> settingsProvider;

        #endregion

        #region Constructor

        public MainForm()
        {
            InitializeComponent();

            #region settings loading

            settingsProvider = new SettingsProviderXML<SettingsContainer>();
            settingsProvider.isSwallowExceptions = false;

            var settingsFileName = StrUtils.GetExecutableFileNameWithNewExt(Application.ExecutablePath, "settings");
            try
            {
                settingsProvider.Load(StrUtils.GetExecutableFileNameWithNewExt(Application.ExecutablePath, "settings"));
            }
            catch (Exception ex)
            {
                MessageBox.Show(
                    string.Format("Unable load settings from {0} properly due to {1}, default settings will be used instead", settingsFileName, ex.Message),
                    "Error",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error);
            }

            #endregion

            #region gnssWrapper initialization

            gnssWrapper = new GNSSReceiverWrapper(settingsProvider.Data.PortSettings);
            gnssWrapper.GLLEvent += new EventHandler<GLLEventArgs>(gnssWrapper_GLLEvent);
            gnssWrapper.GSVEvent += new EventHandler<GSVEventArgs>(gnssWrapper_GSVEvent);
            gnssWrapper.VTGEvent += new EventHandler<VTGEventArgs>(gnssWrapper_VTGEvent);
            gnssWrapper.GGAEvent += new EventHandler<GGAEventArgs>(gnssWrapper_GGAEvent);
            gnssWrapper.RMCEvent += new EventHandler<RMCEventArgs>(gnssWrapper_RMCEvent);
            gnssWrapper.LogEvent += new EventHandler<LogEventArgs>(gnssWrapper_LogEvent);

            #endregion

            #region geoPlot initialization

            geoPlot.Init(100);

            #endregion
        }

        #endregion

        #region Methods

        #endregion

        #region Handlers

        #region gnssWrapper

        private void gnssWrapper_GLLEvent(object sender, GLLEventArgs e)
        {
            GeoCoordinate2D newPoint = new GeoCoordinate2D();
            newPoint.Latitude = e.Latitude;
            newPoint.Longitude = e.Longitude;

            InvokeAddPoint(geoPlot, newPoint);
            InvokeInvalidate(geoPlot);

            InvokeSetText(gllDataTxb, 
                string.Format("UTC Time: {0}.{1}\r\nLAT: {2}\r\nLON:{3}", 
                e.TimeFix.ToLongTimeString(), 
                e.TimeFix.Millisecond, 
                StrUtils.AngleToString(e.Latitude), 
                StrUtils.AngleToString(e.Longitude)));
        }

        private void gnssWrapper_GSVEvent(object sender, GSVEventArgs e)
        {
            List<string> infos = new List<string>();
            for (int i = 0; i < e.SatellitesData.Length; i++)
                infos.Add(e.SatellitesData[i].ToString());

            InvokeSetLines(gsvLbx, infos.ToArray());
        }

        private void gnssWrapper_VTGEvent(object sender, VTGEventArgs e)
        {
            InvokeSetText(vtgTxb,
                string.Format("Speed: {0:F03} km/h, ({1:F03} m/s)\r\nTrack (TRUE): {2:F01}\r\nTrack (Magnetic): {3:F01}",
                e.SpeedKmh,
                e.SpeedKmh / 3.6,
                e.TrackTrue,
                e.TrackMagnetic));
        }

        private void gnssWrapper_GGAEvent(object sender, GGAEventArgs e)
        {
            InvokeSetText(ggaTxb, string.Format("UTC Time: {0}, {1}.{2}\r\nLAT: {3}\r\nLON:{4}\r\nALT: {5:F02} m\r\nSatellites in use: {6}\r\nGPS quality: {7}\r\nPrecision of horizontal dilution: {8}\r\nGeoidal separation: {9} m\r\nDifferentian reference station: {10}",
                e.TimeFix.ToLongDateString(),
                e.TimeFix.ToLongTimeString(),
                e.TimeFix.Millisecond,
                StrUtils.AngleToString(e.Latitude),
                StrUtils.AngleToString(e.Longitude),
                e.AntennaAltitude,
                e.SatellitesInUse,
                e.GPSQualityIndicator,
                e.PrecisionHorizontalDilution,
                e.GeoidalSeparation,
                e.DifferentianReferenceStation));
        }

        private void gnssWrapper_RMCEvent(object sender, RMCEventArgs e)
        {
            InvokeSetText(rmcTxb, string.Format("UTC time: {0}, {1}.{2}\r\nLAT: {3}\r\nLON: {4}\r\nSpeed: {5:F03} km/h ({6:F03} m/s)\r\nTrack: {7:F02}\r\nMagnetic variation: {8}",
                e.TimeFix.ToLongDateString(),
                e.TimeFix.ToLongTimeString(),
                e.TimeFix.Millisecond,
                StrUtils.AngleToString(e.Latitude),
                StrUtils.AngleToString(e.Longitude),
                e.SpeedKmh,
                e.SpeedKmh / 3.6,
                e.TrackTrue,
                e.MagneticVariation));

        }

        private void gnssWrapper_LogEvent(object sender, LogEventArgs e)
        {
            InvokeAppendText(rawOutTxb, e.LogString);
        }

        #endregion

        #region mainToolStrip

        private void openCloseBtn_Click(object sender, EventArgs e)
        {
            if (gnssWrapper.IsOpen)
            {
                try
                {
                    gnssWrapper.Close();
                    openCloseBtn.Checked = false;
                    settingsBtn.Enabled = true;
                }
                catch (Exception ex)
                {
                    MessageBox.Show(string.Format("Unable stop GNSSWrapper due to {0}", ex.Message), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            else
            {
                try
                {
                    gnssWrapper.Open();
                    openCloseBtn.Checked = true;
                    settingsBtn.Enabled = false;
                }
                catch (Exception ex)
                {
                    MessageBox.Show(string.Format("Unable start GNSSWrapper due to {0}", ex.Message), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }

        private void settingsBtn_Click(object sender, EventArgs e)
        {
            using (SettingsEditor sEditor = new SettingsEditor())
            {
                sEditor.Settings = settingsProvider.Data;

                if (sEditor.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    settingsProvider.Data = sEditor.Settings;

                    try
                    {
                        settingsProvider.Save(StrUtils.GetExecutableFileNameWithNewExt(Application.ExecutablePath, "settings"));

                        if (MessageBox.Show("Settings have been saved, restart application to apply?", "Question", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes)
                            Application.Restart();
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(string.Format("Unable save settings due to {0}", ex.Message),
                            "Error",
                            MessageBoxButtons.OK,
                            MessageBoxIcon.Error);
                    }
                }
            }
        }

        private void exitBtn_Click(object sender, EventArgs e)
        {
            if (gnssWrapper.IsOpen)
                gnssWrapper.Close();

            Application.Exit();
        }
        
        #endregion

        #region rawOutTxb

        private void rawOutTxb_TextChanged(object sender, EventArgs e)
        {
            if (rawOutTxb.TextLength > ushort.MaxValue)
                rawOutTxb.Clear();
            else
                rawOutTxb.ScrollToCaret();
        }

        #endregion

        #endregion
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) JSC "SHTIL"
Russian Federation Russian Federation
underwater acoustics, communication and positioning.
Embedded software development. Digital signal processing.

Graduate of Volgograd Technical State University (2007),
Postgraduate student in Kovrov Technological State Academy (2012).

Comments and Discussions