Как устранить неполадки SerialPort.Read () всегда возвращает 0 в C#? - PullRequest
0 голосов
/ 25 февраля 2020

У меня есть связь с монитором дисплея с использованием RS-232 C 9-контактный кабель D-Sub к стереофоническому кабелю для управления включением / выключением питания, увеличением / уменьшением громкости и т. П. c. Я создал образец программы на основе Microsoft Docs System.IO.Ports. Я могу открыть COM-порт, записать несколько байтовых массивов (на основе документа протокола) и никаких проблем. Но чтение в другом потоке всегда заканчивается и получает только «0». Согласно документу, я должен получить ACK или NAK (который отправит мне обратно в виде байтового массива, также начиная с 0xAA). Я вызываю метод Write () в главном классе драйвера.

Как я могу решить эту проблему? Мой метод чтения байтового массива неверен? Спасибо всем за вклад.

public class ComPortDemo
{
    private static bool _continue;
    private static SerialPort _serialPort;

    public ComPortDemo()
    {
        _serialPort = new SerialPort
        {
            PortName = "COM1",
            Parity = Parity.None,
            StopBits = StopBits.One,
            BaudRate = 9600,
            DataBits = 8,
            WriteTimeout = 2000,
            ReadTimeout = 5000,
            Handshake = Handshake.None,
        };

        _serialPort.DataReceived += SerialPortOnDataReceived;
        _serialPort.ErrorReceived += SerialPortOnErrorReceived;
        _serialPort.PinChanged += SerialPortOnPinChanged;
        _serialPort.DtrEnable = true;
        _serialPort.RtsEnable = true;
    }

    private void SerialPortOnPinChanged(object sender, SerialPinChangedEventArgs e)
    {
        Console.WriteLine($"Pin changed event occurred. " + e.EventType);
    }

    public void Write()
    {
        int bufferLength = 6;
        byte[] commands = new byte[bufferLength];

        commands[0] = 0xAA;
        commands[1] = 0x11;
        commands[2] = 0x02;
        commands[3] = 0x01;
        commands[4] = 0x01;
        commands[5] = 0x15;

        if (_serialPort.IsOpen)
            _serialPort.Close();

        _serialPort.Open();
        _continue = true;
        Thread readThread = new Thread(Read);
        readThread.Start();
        Console.WriteLine("Reader thread started and wait for response..");

        Console.Write("Sent: ");
        foreach (var command in commands)
        {
            Console.Write($"0x{command:X2} ");
        }

        Console.WriteLine();

        _serialPort.DiscardInBuffer();
        _serialPort.DiscardOutBuffer();
        _serialPort.Write(commands, 0, commands.Length);

        Console.WriteLine("ENTER to end reading thread..");
        Console.ReadLine();
        _continue = false;
        readThread.Join();
    }

    private static void SerialPortOnErrorReceived(object sender, SerialErrorReceivedEventArgs e)
    {

        Console.WriteLine("serial port on error : " + e.EventType);
    }

    private static void SerialPortOnDataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        //var serialPort = (SerialPort) sender;
        //string data = serialPort.ReadExisting();
        //Console.WriteLine($"{data}");
        Console.WriteLine("data received event");
    }

    public static void Read()
    {

        while (_continue)
        {
            try
            {
                if (_serialPort.BytesToRead <= 0)
                {
                    Console.WriteLine("No data to read");
                }

                byte[] buffer = new byte[7];
                Console.WriteLine("trying to read..");
                int readByte = _serialPort.Read(buffer, 0, buffer.Length);
                Console.WriteLine($"Read byte : {readByte}");
                //if (readByte > 0)
                foreach (var b in buffer)
                    Console.Write($"0x{b:X2} ");

            }
            catch (TimeoutException toe)
            {
                Console.WriteLine(toe.Message);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                Console.WriteLine(e.StackTrace);
            }

            Thread.Sleep(2000);
        }
    }

    public void Close()
    {
        _continue = false;
        if(_serialPort.IsOpen)
            _serialPort.Close();
    }
}
...