如何在.NET中不断检查串口的状态?

时间:2017-11-02 03:00:07

标签: c# .net serial-port

我目前正在使用SerialPort类,但我希望在我的WPF应用程序中拥有该端口的状态(存在/不存在),以检查读卡器是否在物理上断开连接。 / p>

有没有办法在.NET中执行此操作?

我使用的代码是

public class Proxi
    {
        public string proxicard = "";
        public DateTime readingtime = DateTime.MinValue;
        public bool Ready = false;
        public bool Correct = false;
        public bool COMreader = false;
        public bool COMAccess = false;
        public bool COMDataCorrect = false;
        public MemoryStream COMdata = new MemoryStream();
        public SerialPort port;

        // Public Event to allow other classes to subscribe to.
        public event EventHandler CardDetected = delegate { };

        public Proxi(string portname, bool isCOM)
        {
            try
            {
                port = new SerialPort(portname, 9600, Parity.None, 8, StopBits.One)
                {
                    DtrEnable = true,
                    RtsEnable = true
                };
                port.Open();
                port.DataReceived += new SerialDataReceivedEventHandler(Port_DataReceived);
                Ready = true;
                COMreader = isCOM;
            }
            catch
            {
                proxicard = "There is no port " + portname;
            }
        }

        private void Port_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            SerialPort serialPort = (SerialPort)sender;
            byte[] buffer = new byte[serialPort.BytesToRead];
            serialPort.Read(buffer, 0, buffer.Length);
            proxicard = "";

            if ((int)buffer[0] == 58 && !COMreader)
            {
                for (int index = 1; index < buffer.Length; ++index)
                    proxicard = proxicard + ((char)buffer[index]).ToString();

                if (proxicard.Length >= 12)
                {
                    byte[] numArray = ConvertHexToByte(proxicard, 6);
                    byte num = 0;
                    for (int index = 0; index < numArray.Length - 1; ++index)
                        num += numArray[index];
                    Correct = (int)(byte)((uint)~num + 1U) == (int)numArray[numArray.Length - 1];
                    readingtime = DateTime.Now;
                }
                else
                    Correct = false;
            }
            if ((int)buffer[0] == 1 && COMreader)
            {
                COMdata = new MemoryStream();
                COMAccess = true;
                if (buffer.Length > 1)
                    COMdata.Write(buffer, 1, buffer.Length - 1);
            }

            if (!COMAccess || !COMreader || COMdata.Length < 7L)
            {

                // Raise Event, which triggers all method subscribed to it!
                CardDetected(this, new EventArgs());

                return;
            }

            MemoryStream memoryStream = new MemoryStream();
            memoryStream.Write(new byte[1] { (byte)1 }, 0, 1);
            for (int offset = (int)COMdata.Length - 2; offset >= 0; --offset)
                memoryStream.Write(COMdata.ToArray(), offset, 1);
            Correct = (int)CRC.CRC8(memoryStream.ToArray(), (int)memoryStream.Length) == (int)COMdata.ToArray()[COMdata.Length - 1L];
            proxicard = Proxi.GetRecordHEXBytes(COMdata.ToArray(), 1, 5);
            COMdata = new MemoryStream();
            COMAccess = false;

            // Raise Event, which triggers all method subscribed to it!
            CardDetected(this, new EventArgs());
        }

        public static string GetRecordHEXBytes(byte[] data, int position, int length)
        {
            if (position + length > data.Length)
                return "";
            string str = "";
            for (int index = 0; index < length; ++index)
            {
                byte num = data[position + index];
                str += num.ToString("X2");
            }
            return str;
        }

        public byte[] ConvertHexToByte(string HexValue, int length)
        {
            byte[] numArray = new byte[length];
            for (int index = 0; index < length; ++index)
                numArray[index] = (byte)Convert.ToChar(Convert.ToUInt32(HexValue.Substring(index * 2, 2), 16));
            return numArray;
        }

        public void Close()
        {
            port.Close();
        }
    }

1 个答案:

答案 0 :(得分:1)

考虑阅读器连接有两个条件:

  1. COM端口已成功打开
  2. 执行一些测试通信。这可以是双向通信(您向读者询问某些内容,例如版本),或者如果读者定期通信并且每隔几秒钟发送一些测试数据,您可以等待它们。
  3. 如果只满足条件1,请记住,这对于读者存在检测绝对没有意义。如果用户将通信端口设置为始终存在的端口号(例如非USB设备),则即使没有任何连接,也可以打开这样的端口。

    注意仅处理接收事件可能不够,因为根据通信协议,即使连接了阅读器,也不会收到任何数据。

    对于连续检测,您可能希望创建一个线程,该线程将定期尝试打开串行端口并与读取器进行一些测试通信。如果所有这些都成功,您只需在模型类中更改一些bool变量(例如IsConnected),表示读者已连接。在视图方面,您应该将一些控件内容绑定到IsConnected标志。