예제 #1
0
        /// <summary>
        ///     This event is called whenever new data is available on our
        ///     serial port.  This method is responsible for managing the input
        ///     buffer and turning the bytes into strings that downstream methods
        ///     can parse.
        /// </summary>
        /// <param name="ignored1">not used</param>
        /// <param name="ignored2">not used</param>
        private void serialPort_DataReceived(object ignored1, SerialDataReceivedEventArgs ignored2)
        {
            lock (this)
            {
                // if the buffer was all scanned and not useful then dump it
                if (m_bufferUsed == m_buffer.Length)
                {
                    m_bufferUsed = 0;
                }

                // assume that all of the existing buffer was already scanned
                // for newlines.  We will scan what we just received.
                int lastScanIndex = this.m_bufferUsed;

                // this hack backs up our scan by one byte if we saw the CR,
                // but didn't find the LF because it's in the next byte
                if (this.m_bufferUsed > 0 && this.m_buffer[this.m_bufferUsed - 1] == '\r')
                {
                    lastScanIndex--;
                }

                // read all of the data that is avaiable
                int toRead    = System.Math.Min(this.m_serialPort.BytesToRead, (this.m_buffer.Length - this.m_bufferUsed));
                int bytesRead = this.m_serialPort.Read(this.m_buffer, this.m_bufferUsed, toRead);

                // publish the debug event if one is registered
                if (this.RawDataDebugEvent != null)
                {
                    byte[] rawDataBuffer = new byte[bytesRead];
                    Array.Copy(m_buffer, m_bufferUsed, rawDataBuffer, 0, bytesRead);
                    var rawData = new NmeaInputDebugEventArgs(rawDataBuffer);
                    RawDataDebugEvent(this, rawData);
                }

                this.m_startProcessing = DateTime.Now.Ticks;
                this.m_bufferUsed     += bytesRead;

                // loop looking for newlines
                bool foundNewline = true;
                while (foundNewline)
                {
                    // scan the buffer for a new line from the last point scanned
                    int nextNewline = 0;
                    int pastNewline = 0;
                    int i;
                    for (i = lastScanIndex; i < this.m_bufferUsed; i++)
                    {
                        // check for a \r\n line ending.
                        if ((this.m_bufferUsed - i) >= 2 &&
                            (this.m_buffer[i] == (byte)'\r' && this.m_buffer[i + 1] == (byte)'\n'))
                        {
                            nextNewline = i;
                            pastNewline = i + 2;
                            break;
                        }
                        // check for a \n line ending
                        else if (this.m_buffer[i] == (byte)'\n')
                        {
                            nextNewline = i;
                            pastNewline = i + 1;
                            break;
                        }
                    }

                    // we found a line ending
                    if (nextNewline > 0)
                    {
                        char[] chars = System.Text.Encoding.UTF8.GetChars(this.m_buffer, 0, nextNewline);
                        string line  = new string(chars);
                        if (line != null)
                        {
                            ParseNmeaSentence(line);
                            m_startProcessing = DateTime.Now.Ticks;
                        }

                        // shuffle the buffer.  not very efficient, we really should use a circular array
                        int toCopy = this.m_bufferUsed - pastNewline;
                        if (toCopy == 0)
                        {
                            // we used the whole buffer, just reset what we've got
                            this.m_bufferUsed = 0;
                        }
                        else
                        {
                            var newBuffer = new byte[this.m_buffer.Length];
                            Array.Copy(this.m_buffer, pastNewline, newBuffer, 0, this.m_buffer.Length - pastNewline);
                            this.m_bufferUsed = toCopy + 1;
                            this.m_buffer     = newBuffer;
                        }
                    }
                    else
                    {
                        foundNewline = false;
                    }
                }
            }
        }
예제 #2
0
 void m_nmeaInputPort_RawDataDebugEvent(object sender, NmeaInputDebugEventArgs args)
 {
     char[] chars = System.Text.Encoding.UTF8.GetChars(args.RawData, 0, args.RawData.Length);
     m_oled.DrawStringAndScroll(m_debugFont, 0, 63, new string(chars));
 }