Netduino home hardware projects downloads community

Jump to content


The Netduino forums have been replaced by new forums at community.wildernesslabs.co. This site has been preserved for archival purposes only and the ability to make new accounts or posts has been turned off.
Photo

SerialPort buffer overflow on Netduino 2


Best Answer nhale, 24 March 2014 - 10:34 PM

Ok, got it running.

What did I do?

- Introduce check to see if more than 1 byte is there to read (read in the forum, that check for >0 can be a problem)

- Then I had several messages "Failed to allocate 5 blocks 60 bytes". I tried to set the buffer array as instance variable instead newly created on every DataReceived event. But the problem still existed. (the step with the instance variable was also posted as possible solution in the forum)

- Then I tried to switch between the different Baudrates the GPS receiver support, and boom that's it, now it's running. It seems that the receiver was reset in the meantime, with the full app I set it to 115200 baud but removed this to eliminate every unnecessary. So I think the points above fixed it.

 

Now I try to enhance the code skeleton to finally provide the full functionality in parsing the NMEA strings.

 

If someone is interested, here is the code which is running fine now.

public static void Main()
        {
            //Required, otherwise redeploy not possible due to Buffer overflow
            Thread.Sleep(8000);

            GpsConnector _gpsConnector = new GpsConnector();

            Thread.Sleep(Timeout.Infinite);
            Debug.Print("EXIT - should not happen");
        }

    public class GpsConnector
    {
        SerialPort _serialPort;
        private byte[] _buffer;

        		
        public GpsConnector()
        {		
            _serialPort = new SerialPort("COM2", 9600, Parity.None, 8, StopBits.One);
            _serialPort.ReadTimeout = 500;		
            _serialPort.Open();
            if (_serialPort.IsOpen)
            {                               
                _serialPort.DataReceived += _serialPort_DataReceived;
                _serialPort.ErrorReceived += _serialPort_ErrorReceived;
            }
        }

        void _serialPort_ErrorReceived(object sender, SerialErrorReceivedEventArgs e)
        {
            Debug.Print("Exception event raised: " + e.EventType.ToString());
        }

        void _serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            Debug.Print("Data received");
            try
            {
                int bytesToRead = _serialPort.BytesToRead;
                if (bytesToRead > 1)
                {
                    // get the waiting data
                    _buffer = new byte[bytesToRead];
                    _serialPort.Read(_buffer, 0, _buffer.Length);

                    //copy the byte array to a readable string
                    String str = new String(System.Text.Encoding.UTF8.GetChars(_buffer));
                    if (str != null)
                    {
                        Debug.Print("Value "+str);
                    }
                }
            }
            catch (Exception ex)
            {
                Debug.Print("Exception raised on data received: "+ex.ToString());
            }
        }
    }
Go to the full post


  • Please log in to reply
3 replies to this topic

#1 nhale

nhale

    Advanced Member

  • Members
  • PipPipPip
  • 64 posts
  • LocationHeidelberg, Germany

Posted 23 March 2014 - 10:21 PM

So I nailed it down why my N2 does not work since I got it last year. Now I upgraded again and still did not work.

The problem is that the same code below runs on the N1 and N1+ without any problem, but on N2 and N2+ nothing works.

When starting MFDeploy after deploying the code to the N2(+), the console shows an endless list of "Buffer overflw" messages. Again on N1(+) it's running for hours without any problem.

 

Please advice what's wrong here...because it's still an issue in 4.3.1

There is just an Adafruit Ultimate GPS sensor v3 connected to the N2 nothing else

public class Program
    {
        public static void Main()
        {
            //Required, otherwise redeploy not possible due to Buffer overflow
            Thread.Sleep(8000);

            GpsConnector _gpsConnector = new GpsConnector();

            Thread.Sleep(Timeout.Infinite);
        }
    }

    public class GpsConnector
    {
        SerialPort _serialPort;
        private char[] splitBy = new Char[] {'\r', '\n'};
        private bool _isStarted;
        
        //'objectified' main		
        public GpsConnector()
        {		
            _serialPort = new SerialPort("COM2", 115200, Parity.None, 8, StopBits.One);
            _serialPort.Handshake = Handshake.None;
            		
            _serialPort.Open();
            if (_serialPort.IsOpen)
            {
                _isStarted = true;
                DoProcessing();
            }
        }

        private void DoProcessing()
        {           
            if (!_serialPort.IsOpen)
            {
                _serialPort.Open();
            }

            while (_isStarted)
            {
                int bytesToRead = _serialPort.BytesToRead;
                // get the waiting data
                byte[] buffer = new byte[bytesToRead];
                _serialPort.Read(buffer, 0, buffer.Length);
                _serialPort.Flush();
                //only accept a statement starting with $
                if (buffer[0] != 36)
                    continue;

                //copy the byte array to a readable string
                String str = new String(System.Text.Encoding.UTF8.GetChars(buffer));

                //break up string into statements
                string[] statements = null;
                statements = str.Split(splitBy);

                for (int i = 0; i < statements.Length; i++)
                {
                    //only accept statements with a checksum
                    String currStatement = statements[i];
                    if (currStatement.Length > 0 && currStatement.IndexOf("*") >= 0)
                    {
                        Debug.Print(currStatement);
                    }
                }
            }
        }
    }


#2 wendo

wendo

    Advanced Member

  • Members
  • PipPipPip
  • 85 posts

Posted 24 March 2014 - 06:06 AM

You don't appear to be checking that you actually have buffer data. There is no test to make sure buffer > 0

 

The N2 is obviously a lot faster and so may be hitting some occurance to do with that where the N1 wouldn't.

 

Typically you'de use an event handler to fire off your data handling only when new data was actually available



#3 nhale

nhale

    Advanced Member

  • Members
  • PipPipPip
  • 64 posts
  • LocationHeidelberg, Germany

Posted 24 March 2014 - 10:38 AM

I will try that and hope it helps

#4 nhale

nhale

    Advanced Member

  • Members
  • PipPipPip
  • 64 posts
  • LocationHeidelberg, Germany

Posted 24 March 2014 - 10:34 PM   Best Answer

Ok, got it running.

What did I do?

- Introduce check to see if more than 1 byte is there to read (read in the forum, that check for >0 can be a problem)

- Then I had several messages "Failed to allocate 5 blocks 60 bytes". I tried to set the buffer array as instance variable instead newly created on every DataReceived event. But the problem still existed. (the step with the instance variable was also posted as possible solution in the forum)

- Then I tried to switch between the different Baudrates the GPS receiver support, and boom that's it, now it's running. It seems that the receiver was reset in the meantime, with the full app I set it to 115200 baud but removed this to eliminate every unnecessary. So I think the points above fixed it.

 

Now I try to enhance the code skeleton to finally provide the full functionality in parsing the NMEA strings.

 

If someone is interested, here is the code which is running fine now.

public static void Main()
        {
            //Required, otherwise redeploy not possible due to Buffer overflow
            Thread.Sleep(8000);

            GpsConnector _gpsConnector = new GpsConnector();

            Thread.Sleep(Timeout.Infinite);
            Debug.Print("EXIT - should not happen");
        }

    public class GpsConnector
    {
        SerialPort _serialPort;
        private byte[] _buffer;

        		
        public GpsConnector()
        {		
            _serialPort = new SerialPort("COM2", 9600, Parity.None, 8, StopBits.One);
            _serialPort.ReadTimeout = 500;		
            _serialPort.Open();
            if (_serialPort.IsOpen)
            {                               
                _serialPort.DataReceived += _serialPort_DataReceived;
                _serialPort.ErrorReceived += _serialPort_ErrorReceived;
            }
        }

        void _serialPort_ErrorReceived(object sender, SerialErrorReceivedEventArgs e)
        {
            Debug.Print("Exception event raised: " + e.EventType.ToString());
        }

        void _serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            Debug.Print("Data received");
            try
            {
                int bytesToRead = _serialPort.BytesToRead;
                if (bytesToRead > 1)
                {
                    // get the waiting data
                    _buffer = new byte[bytesToRead];
                    _serialPort.Read(_buffer, 0, _buffer.Length);

                    //copy the byte array to a readable string
                    String str = new String(System.Text.Encoding.UTF8.GetChars(_buffer));
                    if (str != null)
                    {
                        Debug.Print("Value "+str);
                    }
                }
            }
            catch (Exception ex)
            {
                Debug.Print("Exception raised on data received: "+ex.ToString());
            }
        }
    }





0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

home    hardware    projects    downloads    community    where to buy    contact Copyright © 2016 Wilderness Labs Inc.  |  Legal   |   CC BY-SA
This webpage is licensed under a Creative Commons Attribution-ShareAlike License.