Я работаю над приложением С#. Мое приложение должно осуществлять последовательную связь с аппаратным устройством. Устройство подключено к моей системе через COM-порт "COM4". Код:

serialPort = new SerialPort("COM4", 2400, Parity.Odd, 8, StopBits.One);
serialPort.WriteTimeout = 5000;
serialPort.ReadTimeout = 5000;
serialPort.Open();
serialPort.Handshake = Handshake.None;
serialPort.DtrEnable = true;
serialPort.RtsEnable = true;

После этого я делаю операцию записи, это работает нормально. Код:

private void WriteMessage(byte[] busMsg)
{
    BinaryWriter writer = new BinaryWriter(serialPort.BaseStream);
    writer.Write(busMsg);
    writer.Flush();
}

После записи, когда я выполняю операцию ReadByte, я получаю исключение тайм-аута. Код:

private byte ReadAEBusMessageResponse()
{
    BinaryReader reader = new BinaryReader(serialPort.BaseStream);
    return reader.ReadByte();
}

Я где-то читал в Google, что BaseStream может вызвать проблему, поэтому я попробовал приведенный ниже код для чтения, но все равно не повезло, и я все еще получаю исключение тайм-аута.

private byte ReadAEBusMessageResponse()
{
    SerialPort currentPort = serialPort;
    return Convert.ToByte(currentPort.ReadByte());
}

Я получаю ответ, когда пытаюсь связаться с Hercules, поэтому я предполагаю, что с ответом от устройства проблем нет. Что я делаю не так с последовательной связью? Любая помощь приветствуется.

0
Waleed Naveed 8 Апр 2020 в 11:04
«После записи, когда я выполняю операцию ReadByte». Что, если не писать, а просто читать, результат будет другим?
 – 
Louis Go
8 Апр 2020 в 11:07
Позвольте мне проверить, но я должен написать, так как это команда, которую я отправляю на устройство, и устройство отвечает в соответствии с этой командой
 – 
Waleed Naveed
8 Апр 2020 в 11:09
Все еще получаю исключение тайм-аута, что довольно очевидно
 – 
Waleed Naveed
8 Апр 2020 в 11:15
Возможно, устройство на самом деле не получило сообщение от системы, поэтому нет ответа (байта) для чтения. Проверьте SerialPort.BytesToRead после того, как ваша запись может помочь. Было бы очень полезно, если бы ваше устройство имело возможность показывать полученное сообщение.
 – 
Louis Go
8 Апр 2020 в 11:23
Получение 0 в «SerialPort.BytesToRead». Устройство является реальным аппаратным устройством, поэтому не может отображать полученное сообщение. @LouisGo
 – 
Waleed Naveed
8 Апр 2020 в 11:43

1 ответ

Я обнаружил, что работает только асинхронное событие. Я создал свой собственный буфер приема байтов, а затем обрабатываю событие:

static byte[] RXbuffer = new byte[512]; //"static" so it can be used all over

public void SerialPort_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            Byte_Size = SerialPort.BytesToRead;

            SerialPort.Read(RXbuffer, 0, Byte_Size);

            /* Return to UI thread */
            this.Invoke(new EventHandler(DisplayText));                       
        }

DisplayText — это метод печати буфера в текстовом поле.

private void DisplayText(object sender, EventArgs e)
        {
            int i = 0;
            byte[] Received_Bytes = new byte[Byte_Size];

            while (i < Byte_Size)
            {             
                Received_Bytes[i] = RXbuffer[i];
                i++;
            }
                

            TB_Info.AppendText("\r\nBytes Received: ");
            TB_Info.AppendText(Byte_Size.ToString());

            TB_Info.AppendText("\r\n--> ");
            TB_Info.AppendText(BitConverter.ToString(Received_Bytes));
            TB_Info.AppendText("\r\n");

           //Array.Copy(RXbuffer,Full_RX_Buff,)
        }

Затем вы можете читать/манипулировать значениями позже.

*** Не забывайте, что в объекте SerialPort, который помещается в вашу форму, вы должны зайти в диалоговое окно свойств/событий и назначить функцию, которая обрабатывает событие полученных данных!

1
Mark Wille 13 Сен 2021 в 18:57