I am asking you for help, please tell me the following question: A device is connected to the PC via a serial COM port , the RS-232 protocol is used. The task is to send commands to the device and receive a response.

Code Example 1:

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.IO.Ports; using System.Threading; namespace PortDataReceived { class Program { static void Main(string[] args) { SerialPort mySerialPort = new SerialPort("COM1"); string KeyWord = "exit"; string EnterWord = ""; mySerialPort.BaudRate = 9600; mySerialPort.Parity = Parity.None; mySerialPort.StopBits = StopBits.One; mySerialPort.DataBits = 8; mySerialPort.Handshake = Handshake.None; mySerialPort.RtsEnable = true; mySerialPort.DataReceived += new SerialDataReceivedEventHandler (DataReceivedHandler); mySerialPort.Open(); while(true) { Console.Write(">>"); EnterWord = Console.ReadLine(); if (EnterWord == KeyWord) { Console.WriteLine("Вы вышли из программы"); break; } else { Console.WriteLine("Отправили комманду на COM-порт"); mySerialPort.WriteLine(EnterWord); } } Console.ReadKey(); mySerialPort.Close(); } private static void DataReceivedHandler( object sender, SerialDataReceivedEventArgs e) { SerialPort sp = (SerialPort)sender; string indata = sp.ReadExisting(); //string indata = sp.ReadLine(); if (indata == null) { Console.WriteLine("Нет данных"); } else { Thread.Sleep(2000); Console.WriteLine("Data Received:"); Thread.Sleep(2000); Console.WriteLine(indata); } } } } 

Conclusion number 1: Conclusion number 1: Comment :

1) It is necessary to output one line entirely - "Service connection opened (COM0)" 2) It is necessary to output one line entirely - "10 values ​​in one line"

In the program code cycle the command input is added (on the screen it looks like ">>" . How to make the command input available only when the response to the request is completely received?

Code example number 2 (the difference is instead of the string string indata = sp.ReadExisting (); the string indata = sp.ReadLine ();) is used:

 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.IO.Ports; using System.Threading; namespace PortDataReceived { class Program { static void Main(string[] args) { SerialPort mySerialPort = new SerialPort("COM1"); string KeyWord = "exit"; string EnterWord = ""; mySerialPort.BaudRate = 9600; mySerialPort.Parity = Parity.None; mySerialPort.StopBits = StopBits.One; mySerialPort.DataBits = 8; mySerialPort.Handshake = Handshake.None; mySerialPort.RtsEnable = true; mySerialPort.DataReceived += new SerialDataReceivedEventHandler (DataReceivedHandler); mySerialPort.Open(); while(true) { Console.Write(">>"); EnterWord = Console.ReadLine(); if (EnterWord == KeyWord) { Console.WriteLine("Вы вышли из программы"); break; } else { Console.WriteLine("Отправили комманду на COM-порт"); mySerialPort.WriteLine(EnterWord); } } Console.ReadKey(); mySerialPort.Close(); } private static void DataReceivedHandler( object sender, SerialDataReceivedEventArgs e) { SerialPort sp = (SerialPort)sender; //string indata = sp.ReadExisting(); string indata = sp.ReadLine(); if (indata == null) { Console.WriteLine("Нет данных"); } else { Thread.Sleep(2000); Console.WriteLine("Data Received:"); Thread.Sleep(2000); Console.WriteLine(indata); } } } } 

Conclusion number 2: ** Conclusion number 2: ** Comment:

1) After the message - "Data Received" , an empty string is displayed. After entering the command - "open" on the screen from the program (" Advanced Serial Port Monitor ") you can see that it is written on the spot of the pass - "[len = 1]" . Apparently this message is not displayed. How to make it displayed? Or that this message is not displayed at all? 2) The answer to the request - "paramset", each parameter is displayed separately. The output of the response took the form because the data reading method changed from "ReadExisting" to "ReadLine" . I like Example 2 more, because the answers to the requests - "open" and "rep test" are displayed properly. Only the query input character - ">>" spoils the type of output. Here it is necessary to make also that input of new request was available only after the end of the answer. And to make an answer to the request - "paramset" as in output No. 1 (so that all fields are displayed immediately, and not in turn, separated from each other by a message - Data Received .

The output of the program "Advanced Serial Port Monitor": ** Output of the program "Advanced Serial Port Monitor": ** Comment:

Ideally, in my code, I want to make a conclusion like in this program,

Only without messages of the type - "[len = 1]" . Only parameter values.

How to quickly change the code and not make it difficult? What is better to add:

1) its buffer in the form of an array and make a conclusion bit by bit using the methods "BytesToRead" , "ReadByte" ?

2) check the beginning and end of the message?

I tried to describe the task in as much detail as possible so that you understand what I need exactly.

  • You use WriteLine to read the read data, but the serial port simply sends bytes. If at some point the OS informs you that there are several bytes in the buffer, you output them in a separate line, without waiting for an explicit line feed from the sender. And your monitor is not writing the best logs ... - Vladimir Martyanov
  • Well, at least check indata for isNullOrEmpty, then from where are such large delays? Thread.Sleep (2000). It is better to initiate an asynchronous data read operation. Set the protocol - how much the server sends data and how much you are ready to accept. - QuaternioNoir
  • Thank you all for the advice. Delays used for a more visual output. I will correct the code based on the information provided. - LapaTheBeast

0