none
SerialPort not receiving bytes RRS feed

  • Question

  • I have an RS-232 to USB adapter that is assigned to COM3.  I can read data from it using Putty with the following configuration:

    • Serial line to connect to: COM3
    • Speed (baud): 10000
    • Data bits: 8
    • Stop bits: 1
    • Parity: None
    • Flow Control: None

    Yes, I know that 10000 is not a standard baud rate, but I have verified it multiple times with an oscilloscope, so I am using that value.

    I am trying to write a trivial C# program to read data from the port and process it, but I cannot get it to read any data.  The DataReceived handler is not called before the 10 seconds is over.  Could someone suggest how to change the program so that it will read?

    using (var port = new SerialPort("COM3", 10000, Parity.None, 8, StopBits.One))
    {
       port.DataReceived +=port_DataReceived;
       port.Open();
       Thread.Sleep(10000);
    }

    Tuesday, February 5, 2013 7:45 PM

Answers

  • "Since I am using the default Handshake value (None) I didn't think that I needed to set these properties. Why did I need to set these properties?"

    Because the connected device may use these signals for handshake. If they are not set, the device may not start the transmission.


    Everything should be made as simple as possible, but not simpler. Any fool can write code that a computer can understand. Good programmers write code that humans understand.

    • Marked as answer by diltsman Wednesday, February 6, 2013 5:09 PM
    Wednesday, February 6, 2013 4:43 PM

All replies

  • Hi,

    I am not sure if that code compiles becouse has this line and you miss the do the 'new'.

    port.DataReceived +=port_DataReceived;

    have you done this in other part of your code?

    port_DataReceived = new SerialDataReceivedEventHandler(DataReceivedHandler);

    But better, you could visit this page

    http://msdn.microsoft.com/en-us/library/system.io.ports.serialport.datareceived.aspx

    Tuesday, February 5, 2013 8:17 PM
  • Have you verified with a breakpoint that the event handler is never called?  Or are you just not seeing the results you expect?

    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    Tuesday, February 5, 2013 8:24 PM
    Moderator
  • It does compile because port_DataReceived is a member function.

    Tuesday, February 5, 2013 8:27 PM
  • I have verified with a break point that the port_DataReceived function is never called.  Also, when the 10 seconds times out, I verified that BytesToRead is 0.
    Tuesday, February 5, 2013 8:28 PM
  • What is that 10 seconds thread sleep doing? It is certainly not a very clever way to use SerialPort and the DataReceived event.

    You need to study how SerialPort utilizes multithreading and how to transfer data to the UI thread from the tread pool thread the handler for the DataReceived event uses. I have written a very big tutorial, which describes all this in details. It may be helpful to you although all examples are in VB. C# works in (almost) the same way.


    Everything should be made as simple as possible, but not simpler. Any fool can write code that a computer can understand. Good programmers write code that humans understand.

    Tuesday, February 5, 2013 8:58 PM
  • My guess?

    You instanced the data received event subscription on thread A (whatever thread that is), opened it on thread A, and put the thread to sleep, theoretically releasing to other threads.

    However, you don't know that calling Open spins a receiver thread, nor that the thread is immediately working against the port.

    SerialPorts, Sockets, NetworkStreams, et. al. should be approached asynchronously because that's how external communications generally operate.

    Create a module level SerialPort for your test.  Get rid of that using statement and instance the SerialPort without automatic disposal.  When you open the port, set a System.Timers.Timer running for a 10 sec interval to release the processor and end the thread you are on.  In the elapsed event of the timer, close and dispose your serial port.  You should see the data then.

    However, regardless of whether putty supports 10000 baud, the SerialPort class may be expecting a "standard" setting (it's not really the most robust communications tool in the .NET box, and has a few shortcomings).  Before you do anything else, see if you can get it to show data at 19,200 or some other "standard" baud rate.

    Tuesday, February 5, 2013 9:40 PM
  • "Yes, I know that 10000 is not a standard baud rate, but I have verified it multiple times with an oscilloscope, so I am using that value."

    Use 9600.

    You've provided insufficient info for any other advice.
    • Edited by JohnWein Tuesday, February 5, 2013 10:22 PM
    Tuesday, February 5, 2013 10:21 PM
  • @ CS001

    "When you open the port, set a System.Timers.Timer running for a 10 sec interval to release the processor and end the thread you are on. In the elapsed event of the timer, close and dispose your serial port. "

    Why use a 10 second timer and why close the port before you close the applications? To my opinion it is a rather crazy use of serialPort.

    "However, regardless of whether putty supports 10000 baud, the SerialPort class may be expecting a "standard" setting (it's not really the most robust communications tool in the .NET box, and has a few shortcomings)."

    This is all up to the UART. If it has a clock generator, which supports 10kbit/s, it is all right as the oscilloscope also shows. The non-standard rate is not the problem. I also use non-standard bit rates such as 4.9152 Mbit/s and it works fine. I have actually tested this on several UART's including 16C950 and most USB-serial converters before making the N*300 bit/s row standard for my new fieldbus Max-i - even at high speeds where N*450 bit/s is usually used. 


    Everything should be made as simple as possible, but not simpler. Any fool can write code that a computer can understand. Good programmers write code that humans understand.

    Wednesday, February 6, 2013 8:44 AM
  • I tried to take the advice that was offered and I have gotten to the point where this is my code.  Still no change in results with either 9600 or 10000 baud.

    private SerialPort _port = null;
    
    private void ViewModel_CurrentChanged(object sender, EventArgs e)
    {
       if (_port != null)
       {
          _port.DataReceived -= port_DataReceived;
          _port.Dispose();
       }
       _port = new SerialPort("COM3", 9600, Parity.None, 8, StopBits.One);
       _port.DataReceived += port_DataReceived;
       _port.Open();
    }
    
    private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
       //throw new NotImplementedException();
    }

    Wednesday, February 6, 2013 2:43 PM
  • Looking over Carsten's tutorial, I noticed that it suggested that there are issues with SerialPort in .NET 3.X.  I am using .NET 4.5.  Is that likely to be an issue?  I tried the sample program on the page, and it read data off of the serial port beautifully.
    Wednesday, February 6, 2013 2:58 PM
  • The different versions of the serial port behave differently, particulary for Carsten's application with baud rates above 1 Mbps.  Any of the SerialPorts will work with any of the sample code in the help documentation for standard baud rates.  If it works with the sample, your code is in error.  The difference in baud rates of 9600 and 10000 shouldn't make any difference.  If you're curious, handle the ErrorReceived event and catch framing errors.
    • Edited by JohnWein Wednesday, February 6, 2013 3:24 PM
    Wednesday, February 6, 2013 3:23 PM
  • I looked in more detail over the example, and it sets RtsEnable and DtrEnable to true after opening the COM port.  When I added this, it worked.

    Since I am using the default Handshake value (None) I didn't think that I needed to set these properties.  Why did I need to set these properties?

    Wednesday, February 6, 2013 3:34 PM
  • "Since I am using the default Handshake value (None) I didn't think that I needed to set these properties. Why did I need to set these properties?"

    Because the connected device may use these signals for handshake. If they are not set, the device may not start the transmission.


    Everything should be made as simple as possible, but not simpler. Any fool can write code that a computer can understand. Good programmers write code that humans understand.

    • Marked as answer by diltsman Wednesday, February 6, 2013 5:09 PM
    Wednesday, February 6, 2013 4:43 PM
  • I presume this is some sort of test code.  The 10 seconds is merely in keeping with the structure of the test being performed (i.e. "sleeping" the thread for 10 secs versus waiting on a timer for 10 secs).

    The other point was just a guess.  I can't speak to it except to speculate due to other shortcomings of the SerialPort class (like the mandatory wait period after a close before reopenint).

    Wednesday, February 6, 2013 9:29 PM
  • This worked for me fine!

                _serialport.RtsEnable =

    true;

                _serialport.DtrEnable =

    true;

    Wednesday, January 8, 2014 4:57 PM