/// <summary> /// If there is existing NMEA data, this will combine the /// data. This will take the existing data and add it to a /// buffer. It will then add the new data to the buffer and /// parse the buffer. /// </summary> /// <param name="nmeaData">New data to combine to this dataset.</param> /// <param name="maxSentences">Maximum number of sentences to have in the data set.</param> public void MergeNmeaData(string nmeaData, int maxSentences) { StringBuilder builder = new StringBuilder(); if (NmeaStrings != null) { // Remove the oldest messages // Plus 1 to include the new message that will be added while (NmeaStrings.Count > maxSentences + 1) { NmeaStrings.RemoveAt(0); } // Append all the NMEA data to a string for (int x = 0; x < NmeaStrings.Count; x++) { builder.Append(NmeaStrings[x]); } } // Add the incoming NMEA data to existing data builder.Append(nmeaData); // Parse the data SetNmeaStringArray(builder.ToString()); }
/// <summary> /// Decode the NMEA sentence from the array. Then add /// it to the list of NMEA sentences. Set value will try /// to update the NMEA data with the latest information. /// </summary> /// <param name="nmeaSentences">All the NMEA setences.</param> private void DecodeNmeaData(string[] nmeaSentences) { // Create a list of all the NMEA setences LinkedList <string> list = new LinkedList <string>(); if (nmeaSentences != null) { for (int x = 0; x < nmeaSentences.Length; x++) { // Create a NMEA sentence and verify its valid NmeaSentence sentence = new NmeaSentence(nmeaSentences[x]); if (sentence.IsValid) { // Add to the list NmeaStrings.Add(sentence.Sentence); // Set values from the NMEA data SetValues(sentence); } } } // Copy the list to the NmeaStrings //NmeaStrings = new string[list.Count]; //list.CopyTo(NmeaStrings, 0); }
///// <summary> ///// ///// </summary> ///// <param name="gga"></param> ///// <returns></returns> //private byte[] ProcessGGA(string gga) //{ // // Add \r\n\u // // Carriage Return 0x0d // // New Line 0x0a // // Null 0x00 // // First trim, then add the characters // gga = gga.Trim(); // gga += "\r\n"; // // Message Size // ushort msgSize = (ushort)(BYTES_PER_HEADER + gga.Length); // byte msgSizeLsb, msgSizeMsb; // MathHelper.LsbMsbUShort(msgSize, out msgSizeLsb, out msgSizeMsb); // // Delta Time // double dTime = 0.0; // byte[] deltaTime = BitConverter.GetBytes(dTime); // if (deltaTime.Length < 8) // { // deltaTime = new byte[8]; // } // // Create the array // byte[] data = new byte[msgSize]; // data[0] = ID_LSB; // General ID LSB 0x20 // data[1] = ID_MSB; // General ID MSB 0x22 // data[2] = ID_NMEA_GGA_V2_LSB; // Specific ID LSB 0x01 // data[3] = ID_NMEA_GGA_V2_MSB; // Specific ID MSB 0x04 // data[4] = msgSizeLsb; // Message Size LSB // data[5] = msgSizeMsb; // Message Size MSB // data[6] = deltaTime[0]; // Delta Time // data[7] = deltaTime[1]; // Delta Time // data[8] = deltaTime[2]; // Delta Time // data[9] = deltaTime[3]; // Delta Time // data[10] = deltaTime[4]; // Delta Time // data[11] = deltaTime[5]; // Delta Time // data[12] = deltaTime[6]; // Delta Time // data[13] = deltaTime[7]; // Delta Time // // Msg // byte[] msg = Encoding.ASCII.GetBytes(gga); // // Copy the message to the result // Buffer.BlockCopy(msg, 0, data, 14, msg.Length); // return data; //} ///// <summary> ///// ///// </summary> ///// <param name="gga"></param> ///// <returns></returns> //private byte[] DecodeGGAStruct(GpggaSentence gga) //{ // // Message Size // ushort msgSize = BYTES_PER_HEADER + BYTES_PER_GGA; // byte msgSizeLsb, msgSizeMsb; // MathHelper.LsbMsbUShort(msgSize, out msgSizeLsb, out msgSizeMsb); // // Delta Time // double dTime = 0.0; // byte[] deltaTime = BitConverter.GetBytes(dTime); // if(deltaTime.Length < 8) // { // deltaTime = new byte[8]; // } // // Create the array // byte[] data = new byte[msgSize]; // data[0] = ID_LSB; // General ID LSB 0x20 // data[1] = ID_MSB; // General ID MSB 0x22 // data[2] = ID_NMEA_GGA_V2_LSB; // Specific ID LSB 0x01 // data[3] = ID_NMEA_GGA_V2_MSB; // Specific ID MSB 0x04 // data[4] = msgSizeLsb; // Message Size LSB // data[5] = msgSizeMsb; // Message Size MSB // data[6] = deltaTime[0]; // Delta Time // data[7] = deltaTime[1]; // Delta Time // data[8] = deltaTime[2]; // Delta Time // data[9] = deltaTime[3]; // Delta Time // data[10] = deltaTime[4]; // Delta Time // data[11] = deltaTime[5]; // Delta Time // data[12] = deltaTime[6]; // Delta Time // data[13] = deltaTime[7]; // Delta Time // // Msg Body // #region $GPGGA Header // byte[] szHeader = Encoding.ASCII.GetBytes(gga.CommandWord); // if (szHeader.Length != 7) // { // szHeader = new byte[7]; // } // data[14] = szHeader[0]; // Header // data[15] = szHeader[1]; // Header // data[16] = szHeader[2]; // Header // data[17] = szHeader[3]; // Header // data[18] = szHeader[4]; // Header // data[19] = szHeader[5]; // Header // data[20] = szHeader[6]; // Header // #endregion // #region HHMMSS.SS // byte[] szUTC = new byte[10]; // if (gga.Words.Length > 2) // { // szUTC = Encoding.ASCII.GetBytes(gga.Words[1]); // if (szUTC.Length != 10) // { // szUTC = new byte[10]; // } // } // data[21] = szUTC[0]; // UTC time // data[22] = szUTC[1]; // UTC time // data[23] = szUTC[2]; // UTC time // data[24] = szUTC[3]; // UTC time // data[25] = szUTC[4]; // UTC time // data[26] = szUTC[5]; // UTC time // data[27] = szUTC[6]; // UTC time // data[28] = szUTC[7]; // UTC time // data[29] = szUTC[8]; // UTC time // data[30] = szUTC[9]; // UTC time // #endregion // #region Latitude // byte[] dLatitude = new byte[8]; // dLatitude = MathHelper.DoubleToByteArray(gga.Position.Latitude.DecimalDegrees); // if (dLatitude.Length != 8) // { // dLatitude = new byte[8]; // } // byte tcNS = Convert.ToByte('N'); // if(gga.Position.Latitude.Hemisphere == LatitudeHemisphere.South) // { // tcNS = Convert.ToByte('S'); // } // data[31] = dLatitude[0]; // Latitude // data[32] = dLatitude[1]; // Latitude // data[33] = dLatitude[2]; // Latitude // data[34] = dLatitude[3]; // Latitude // data[35] = dLatitude[4]; // Latitude // data[36] = dLatitude[5]; // Latitude // data[37] = dLatitude[6]; // Latitude // data[38] = dLatitude[7]; // Latitude // data[39] = tcNS; // North or South // #endregion // #region Longitude // byte[] dLongitude = new byte[8]; // dLongitude = MathHelper.DoubleToByteArray(gga.Position.Longitude.DecimalDegrees); // if (dLongitude.Length != 8) // { // dLongitude = new byte[8]; // } // byte tcEW = Convert.ToByte('E'); // if (gga.Position.Longitude.Hemisphere == LongitudeHemisphere.West) // { // tcNS = Convert.ToByte('W'); // } // data[40] = dLongitude[0]; // Latitude // data[41] = dLongitude[1]; // Latitude // data[42] = dLongitude[2]; // Latitude // data[43] = dLongitude[3]; // Latitude // data[44] = dLongitude[4]; // Latitude // data[45] = dLongitude[5]; // Latitude // data[46] = dLongitude[6]; // Latitude // data[47] = dLongitude[7]; // Latitude // data[48] = tcNS; // East or West // #endregion // #region Quality // byte ucQuality = Convert.ToByte(gga.FixQuality); // data[49] = ucQuality; // Quality // #endregion // #region Number of Satellites // byte ucNmbSat = Convert.ToByte(gga.FixedSatelliteCount); // data[50] = ucNmbSat; // Number of Satellites // #endregion // #region HDOP // byte[] fHDOP = MathHelper.FloatToByteArray(gga.HorizontalDilutionOfPrecision.Value); // if(fHDOP.Length != 4) // { // fHDOP = new byte[4]; // } // data[51] = fHDOP[0]; // HDOP // data[52] = fHDOP[1]; // HDOP // data[53] = fHDOP[2]; // HDOP // data[54] = fHDOP[3]; // HDOP // #endregion // #region Altitude // byte[] fAltitude = MathHelper.FloatToByteArray((float)gga.Altitude.ToMeters().Value); // Force to Meters // if (fAltitude.Length != 4) // { // fAltitude = new byte[4]; // } // byte tcAltUnit = Convert.ToByte('M'); // data[55] = fAltitude[0]; // Altitude // data[56] = fAltitude[1]; // Altitude // data[57] = fAltitude[2]; // Altitude // data[58] = fAltitude[3]; // Altitude // data[59] = tcAltUnit; // Altitude unit // #endregion // #region Geoid // byte[] fGeoid = MathHelper.FloatToByteArray((float)gga.GeoidalSeparation.ToMeters().Value); // Force to Meters // if (fGeoid.Length != 4) // { // fGeoid = new byte[4]; // } // byte tcGeoidUnit = Convert.ToByte('M'); // data[60] = fGeoid[0]; // Altitude // data[61] = fGeoid[1]; // Altitude // data[62] = fGeoid[2]; // Altitude // data[63] = fGeoid[3]; // Altitude // data[64] = tcGeoidUnit; // Altitude unit // #endregion // #region Age of DGPS // byte[] fAgeDGPS = MathHelper.FloatToByteArray((float)gga.DifferentialGpsAge.TotalSeconds); // Force to Seconds // if (fAgeDGPS.Length != 4) // { // fAgeDGPS = new byte[4]; // } // data[65] = fAgeDGPS[0]; // Age of Differential GPS data // data[66] = fAgeDGPS[1]; // Age of Differential GPS data // data[67] = fAgeDGPS[2]; // Age of Differential GPS data // data[68] = fAgeDGPS[3]; // Age of Differential GPS data // #endregion // #region Ref Station ID // byte[] sRefStationId = MathHelper.UInt16ToByteArray((UInt16)gga.DifferentialGpsStationID); // if (sRefStationId.Length != 2) // { // sRefStationId = new byte[2]; // } // data[69] = sRefStationId[0]; // Differential GPS Station ID // data[66] = sRefStationId[1]; // Differential GPS Station ID // #endregion // return data; //} #endregion #region Add NMEA /// <summary> /// Add another NMEA string to the dataset. /// </summary> /// <param name="nmeaString"></param> public void AddNmea(string nmeaString) { // Create a NMEA sentence and verify its valid NmeaSentence sentence = new NmeaSentence(nmeaString); if (sentence.IsValid) { // Add to the list NmeaStrings.Add(sentence.Sentence); // Set values from the NMEA data SetValues(sentence); } }
/// <summary> /// Parse the string of all valid NMEA sentences. /// Store them to the array. /// </summary> /// <param name="nmeaStrings">String containing NMEA sentences.</param> private void SetNmeaStringArray(string nmeaStrings) { LinkedList <NmeaSentence> list = new LinkedList <NmeaSentence>(); // Find the first $ while (nmeaStrings.Contains("$") && nmeaStrings.Contains("*")) { int start = nmeaStrings.IndexOf("$"); nmeaStrings = nmeaStrings.Substring(start); // Check if a checksum exist in the data // If so, being parsing int checksumLoc = nmeaStrings.IndexOf("*"); string nmea = ""; // Find the start of the checksum // Add NMEA_CHECKSUM_SIZE to include the * and checksum value if (checksumLoc >= 0) { if (nmeaStrings.Length >= checksumLoc + NMEA_CHECKSUM_SIZE) { // Check if the checksum is good if (!nmeaStrings.Substring(checksumLoc, NMEA_CHECKSUM_SIZE).Contains("$")) { // Get the NMEA string and remove it from the buffer. nmea = nmeaStrings.Substring(0, checksumLoc + NMEA_CHECKSUM_SIZE); nmeaStrings = nmeaStrings.Remove(0, nmea.Length); // Remove any trailing new lines nmea = nmea.TrimEnd(REMOVE_END); } else { // Bad Nmea string, $ within checksum // Remove the bad string nmeaStrings = nmeaStrings.Remove(0, checksumLoc); } } else { nmeaStrings = nmeaStrings.Remove(0, checksumLoc); } } if (nmea.Length > 0) { try { // Create a NMEA sentence and verify its valid NmeaSentence sentence = new NmeaSentence(nmea); if (sentence.IsValid) { // Add the nmea data to list NmeaStrings.Add(sentence.Sentence); // Set values from the NMEA data SetValues(sentence); } } catch (Exception e) { log.Error("Error decoding NMEA sentence.", e); } } } // Store the Nmea data //NmeaStrings = new NmeaSentence[list.Count]; //list.CopyTo(NmeaStrings, 0); }