-1

I am writing a C# program to poll data from Arduino serial port which generates data through "serial.println". In C# program, I found "port.BytesToRead" sometimes returns 0 even though the "port.dataReceived" is called. As a result, it prints out the error message that I requested it to print. However, if the "port.BytesToRead" returns 0, it stops me from polling the data from the main polling loop when I should. Any suggestions to the cause of the error and how to fix that?

        _serialPort = new SerialPort();
        _serialPort.PortName = "COM7";//Set your board COM
        _serialPort.BaudRate = 9600;

        _serialPort.ReadTimeout = 500;
        _serialPort.WriteTimeout = 500;

        _serialPort.DtrEnable = true;
        _serialPort.RtsEnable = true;

        _serialPort.DataReceived += Watch_BLE_DataReceived;       
        
        private void Watch_BLE_DataReceived(object sender, EventArgs arg)
        {
            SerialPort port = sender as SerialPort;

            if (port == null)
            {
                return;
            }

           
            if (!(port.BytesToRead > 0))
            {
                // print error
            }
                
        }

In the main function, I write a polling loop like:

        while (true)
        {   
            
            try
            {
                if (!_serialPort.IsOpen)
                {
                    
                    _serialPort.Open();

                }
            }
            catch (Exception e)
            {

                continue;
            }

            try
            {
                
                

                if (_serialPort.BytesToRead > 0) {
                    // process read data
                }
            }
        }

1 Answer 1

1

Why are you both polling and using the SerialPort.DataReceived event? That's making little sense.

Decide upon only one approach, checking for and consuming the incoming data either by using a polling loop or by using the SerialPort.DataReceived event.

Because you are currently using both polling and the SerialPort.DataReceived event together, your program quite likely suffers from a race condition.

The SerialPort instance recognizes data incoming on the serial port, buffers that data in its receive buffer and raises the DataReceived event. And what is probably happening then sometimes is that the timing of the current iteration of your polling loop is just such that it manages to read and thus empty the receive buffer before the DataReceived event handler is getting around to check the port.BytesToRead value. This then leads to the situation where the DataReceived event handler sees no bytes to read because the polling loop was just a little quicker that time.

Sign up to request clarification or add additional context in comments.

1 Comment

I am using the handler to check whether the port.BytesToRead is actually a good check for whether data is in the buffer. Your explanation only explains the case where DataReceived event not fired, but doesn't explain the case I am asking for, where port.BytesToRead is 0 while DataReceived event is fired though.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.