Azmeer
Azmeer

Reputation: 734

Visual C# 2015 Serial Port - reading data

I am trying to figure out what is wrong with my code. Serial modem is working. Just testing with ATI command to see the input, but I see nothing. What could be wrong? I am using a thread to read the data from serial buffer.

using System;
using System.IO.Ports;
using System.Threading;

namespace SerialPortProgram
{
    public class PortChat
    {
        static bool _continue = true;
        static SerialPort port = new SerialPort("COM1", 115200, Parity.None, 8, StopBits.One);

        public static void Main()
        {
            string message;
            StringComparer stringComparer = StringComparer.OrdinalIgnoreCase;
            Thread readThread = new Thread(Read);

            port.Open();
            port.WriteLine("ATI");
            Console.WriteLine("Type QUIT to exit");
            readThread.Start();
            while (_continue)
            {
                message = Console.ReadLine();

                if (stringComparer.Equals("quit", message))
                {
                    _continue = false;
                }
                else
                {
                    port.WriteLine(message);
                }
            }
            readThread.Join();
            port.Close();
            port.Dispose();
        }
        public static void Read()
        {
            Console.WriteLine("incoming...");
            Console.WriteLine(port.ReadExisting());
        }
    }
}

Upvotes: 0

Views: 970

Answers (2)

Azmeer
Azmeer

Reputation: 734

Thank you very much Peter Duniho, with your input I changed my code. Now it works like a charm..!

using System;
using System.IO.Ports;
using System.Threading;

namespace SerialPortProgram
{
    public class PortChat
    {
        static bool _continue = true;
        static SerialPort port = new SerialPort("COM1", 115200, Parity.None, 8, StopBits.One);

        public static void Main()
        {
            port.Handshake = Handshake.None;

            string message;
            StringComparer stringComparer = StringComparer.OrdinalIgnoreCase;
            port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);

            port.Open();
            port.WriteLine("ATI");
            Console.WriteLine("Type QUIT to exit");
            while (_continue)
            {
                message = Console.ReadLine();

                if (stringComparer.Equals("quit", message))
                {
                    _continue = false;
                }
                else
                {
                    port.WriteLine(message);
                }
            }
            port.Close();
            port.Dispose();
        }
        private static void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            // Show all the incoming data in the port's buffer
            Console.WriteLine(port.ReadExisting());
        }
    }
}

Upvotes: 1

Peter Duniho
Peter Duniho

Reputation: 70652

The SerialPort.ReadExisting() method doesn't block. So, your code starts a thread, which immediately calls ReadExisting(), which immediately returns an empty string, and then that thread exits. It won't ever see the echo from the modem of whatever command you enter; you can't type that fast.

You should not be using an explicit thread here anyway. Instead, handle the SerialPort.DataReceived event, and call ReadExisting() when the event is raised.

Even better, use the BaseStream property to get a Stream object, with which you can use the standard XXXAsync() methods, which work with async/await and allow you to write much more readable, easy-to-understand code. Even a console program can benefit from this approach, and if and when you move to a GUI API, it will work even better.

Upvotes: 3

Related Questions