locked
issue getting "line" instead of each char from COM port stream RRS feed

  • Question

  • Hello,

    I'm trying to listen to a telephone system connected to a usb-to-serial connector.

    Using ReadExisting I can see every char, but I would like every line (so I can then extrapolate the data out of it).

    I have tried ReadLine instead, but my interface dosn't display any data.

    I think this is because the feed isn't sending a \r\n (or 0x0d 0x0a)to represent an EoL (so , its listening to find an end of a call, but dosn't find the delimiter).

    NB: Manuals on the phone system seem hard to find  (to locate what the EoL char is )

    is this the correct way, or is there a better way of getting the data "per line" ?

    I am currently using this code:

        class Program
            {
            public static void Main()
                {
                /// create serial port to listen to 
                SerialPort mySerialPort = new SerialPort("COM4");
    
                mySerialPort.BaudRate = 9600;
                mySerialPort.Parity = Parity.None;
                mySerialPort.StopBits = StopBits.One;
                mySerialPort.DataBits = 8;
                mySerialPort.Handshake = Handshake.XOnXOff;
                mySerialPort.RtsEnable = true;
    
                /// Intercept data method
                mySerialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
    
                /// Open (above) port
                //mySerialPort.DtrEnable = true;
                mySerialPort.Open();
    
                /// Close the port  
                Console.WriteLine("Press any key to stop listening...");
                Console.WriteLine();
                Console.ReadKey();
                mySerialPort.Close();
                }
    
            private static void DataReceivedHandler(object sender,SerialDataReceivedEventArgs e)
                {
       
                SerialPort sp = (SerialPort)sender;
    
                /// "Reads all immediately available bytes, based on the encoding, in both the stream and the input buffer of the SerialPort object" - MS.
                string indata = sp.ReadExisting();
    			
                /// doesn't work (no \r\n?). - "ReadLine() method will return when the port receives a carriage return and line feed byte combination by default on Windows. Or \r\n, or 0x0d 0x0a if you prefer." - SO
                //string indata = sp.ReadLine();
    
                Console.Write(indata);
            }
        }

    Thank you

    Thursday, September 24, 2020 1:00 PM

All replies

  • Depending on your PBX system, which is what I assume you're actually connecting to via "serial" (is that RS232 or some other hardware spec?), then it may be sending \r\n (0x0d0a) or \r (0x0d) or \n (0x0a) as a line terminator.

    I don't believe RS232 has been updated in a really long time, so they're still probably spewing ASCII text and expecting standard network-style lineterms (0x0d0a).  Or put another way:  I suspect that whoever engineered the device may have modernized it "off spec" while DotNET's RS232 reading tools are "on spec."

                System.IO.Ports.SerialPort sp = new System.IO.Ports.SerialPort();
    
                System.IO.StreamReader sr = new StreamReader(sp.BaseStream);
                // Try sr.ReadLine - I've found that the StreamReader does a fine job of 
                // detecting multi-platform lineterms.
    
                sr.Close();
                sr.Dispose();
                sp.Close();
                sp.Dispose();


    Before you can learn anything new you have to learn that there's stuff you don't know.


    Thursday, September 24, 2020 1:29 PM
  • There is no way to know how much data to read unless you're sent some sort of header information. Thus you first need to determine how much data is being sent on each request. After that you have to keep reading until you've read it all. ReadExisting only reads up to what has been sent at the point you make the call, there can still be data left. I think we covered this in one of your other posts. You need to read until you've read all the data that is available. If you don't know that then there is no way to know when you've gotten to the end of "line" whatever line means to you.

    Example, ReadExisting returns "Bob". Is it done or is there more? There is no way to know that. I guess you could keep calling ReadExisting until it returns nothing but that isn't a guarantee. The remote end could have a hiccup and not send the next batch of data quite yet. Or maybe the remote end has already started sending the next set of messages. There is no way to tell without some sort of header information that should precede each "message" being sent. Unfortunately we have no way of knowing this protocol, as was mentioned in other posts. The best
    algorithm we can provide is this.

    Determine how much data is left to read
    Keep reading until all data read
    Process the message

    Since you're handling the data receive event you will need to create a buffer that this method puts the read results into. After each event (when the method is called) you need to read the next set of data (using ReadExisting is fine) and add it to the buffer you have. If you have received all the data for the current message then process the message that you've been storing in the buffer and then reset the buffer for the next message. If you haven't received all the data yet then don't do anything else. 


    Michael Taylor http://www.michaeltaylorp3.net

    Thursday, September 24, 2020 1:35 PM
  • Hello all, 

    for anyone else, and furture me, I resolved this my using

    string output = sp.ReadTo("                                ");

    as I trawled though all the data i could get and determined this was the EoL terminator.

    Thank you both for your help thought. it is always greatly received :-) 

    Wednesday, September 30, 2020 2:27 PM
  • Hi G-Oker,

    Your problem seems to be solved, please click on the "Mark as answer" option of the reply that solved your question, so that it will help other members to find the solution quickly if they face a similar issue.

    Best Regards,

    Timon


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Monday, October 5, 2020 8:32 AM