Implementation of C# simple serial port monitoring host computer

To realize the communication between the upper computer and the lower computer, the serial communication is usually used. Next, a serial communication test is completed through the upper computer and the serial debugging assistant.

First, create a WInfrom form application project file. The creation process can be referred to https://www.cnblogs.com/xionglaichuangyichuang/p/13734179.html ;

Under the created project, the interface is built through the existing controls in the toolbox, as shown in the figure below. In order to make it easy for beginners to understand the program, the names of the controls are marked in the figure below:

 

Go straight to the topic and paste the complete engineering Code:

  1 using System;
  2 using System.Collections.Generic;
  3 using System.ComponentModel;
  4 using System.Data;
  5 using System.Drawing;
  6 using System.Linq;
  7 using System.Text;
  8 using System.Threading.Tasks;
  9 using System.Windows.Forms;
 10 using System.IO.Ports;
 11 using System.Diagnostics;
 12 
 13 namespace Tem_Hum_Monitorring
 14 {
 15     
 16     public partial class Form1 : Form
 17     {
 18         //Instantiate serial port
 19         SerialPort s = new SerialPort();
 20 
 21         public Form1()
 22         {
 23             InitializeComponent();
 24             Control.CheckForIllegalCrossThreadCalls = false;
 25             button1.Text = "Open serial port";
 26             int[] item = { 9600,115200};    //ergodic
 27             foreach (int a in item)
 28             {
 29                 comboBox2.Items.Add(a.ToString());
 30             }
 31             comboBox2.SelectedItem = comboBox2.Items[1];
 32         }
 33 
 34         private void Form1_Load(object sender, EventArgs e)
 35         {
 36             portInit();
 37         }
 38 
 39         /// <summary>
 40         /// Serial port initialization
 41         /// </summary>
 42         private void portInit()
 43         {
 44             string[] ports = SerialPort.GetPortNames();
 45             comboBox1.Items.AddRange(ports);
 46             comboBox1.SelectedItem = comboBox1.Items[0];
 47         }
 48 
 49         #region Switch serial port
 50         private void button1_Click(object sender, EventArgs e)
 51         {
 52             try
 53             {
 54                 if (!s.IsOpen)
 55                 {
 56                     s.PortName = comboBox1.SelectedItem.ToString();
 57                     s.BaudRate = Convert.ToInt32(comboBox2.SelectedItem.ToString());
 58                     s.Open();
 59                     s.DataReceived += s_DataReceived; //"+="Represents the method to be called when specifying the response event
 60                     button1.Text = "Close the serial port";
 61                 }
 62                 else
 63                 {
 64                     s.Close();
 65                     s.DataReceived -= s_DataReceived;
 66                     button1.Text = "Open serial port";
 67                 }
 68             }
 69             catch(Exception ee)
 70             {
 71                 MessageBox.Show(ee.ToString());
 72             }
 73         }
 74         #endregion
 75 
 76         #region Serial port receiving
 77         void s_DataReceived(object sender, SerialDataReceivedEventArgs e)
 78         {
 79             int count = s.BytesToRead;
 80             string str = null;
 81             if (count == 8)
 82             {
 83                 //Data analysis
 84                 byte[] buff = new byte[count];
 85                 s.Read(buff, 0, count);
 86                 foreach (byte item in buff)
 87                 {
 88                     str += item.ToString("X2") + " ";
 89                 }
 90                 richTextBox1.Text = "[" + System.DateTime.Now.ToString() + "] " + str + "\n" + richTextBox1.Text;
 91                 if (buff[0] == 0x04)
 92                 {
 93                     ID.Text = buff[0].ToString();
 94                     switch (buff[2])
 95                     {
 96                         case 0x01:
 97                             {
 98                                 Tem.Text = (buff[5] * 4 + buff[4] * 0.05 - 30).ToString();
 99                                 Hum.Text = (buff[6] + buff[7]).ToString();
100                                 break;
101                             }
102                         case 0x02:
103                             {
104                                 Light.Text = (buff[6] + buff[7]).ToString();
105                                 break;
106                             }
107                         case 0x04:
108                             {
109                                 Dust.Text = (buff[6] + buff[7]).ToString();
110                                 break;
111                             }
112                         default:
113                             break;
114                     }
115                 }
116             }
117             else
118             {
119                 //When the received data is not within the set data bit range, the received data will always be stored in the receiving buffer, and the last data will be superimposed every time the data is received, resulting in the data in the buffer can only be cleared by closing the serial port
120                 s.DiscardInBuffer(); //Discards data from the receive buffer of the serial driver
121             }
122         }
123         #endregion
124 
125         #region Serial port transmission
126         private void button3_Click(object sender, EventArgs e)
127         {
128             string[] sendbuff = richTextBox2.Text.Split();
129             Debug.WriteLine("Bytes sent:" + sendbuff.Length);
130             foreach (string item in sendbuff)
131             {
132                 int count = 1;
133                 byte[] buff = new byte[count];
134                 buff[0] = byte.Parse(item, System.Globalization.NumberStyles.HexNumber);
135                 s.Write(buff,0,count);
136             }
137         }
138         #endregion
139 
140         private void button2_Click(object sender, EventArgs e)
141         {
142             int count = 1;
143             byte[] buff = new byte[count];
144             buff[0] = byte.Parse("04", System.Globalization.NumberStyles.HexNumber);
145             s.Write(buff, 0, count);
146         }
147     }
148 }

In Winfrom form design, the serial port can be realized through the serial port control in the toolbox. However, it is generally recommended to instantiate the serial port directly through code. The instantiated serial port needs to be realized by using the following code:

    //Instantiate serial port
    SerialPort s = new SerialPort();

Serial port initialization can be realized in the Load function of the form. The following initialization can automatically take the existing serial ports in the current device, including real serial ports and virtual serial ports:

private void Form1_Load(object sender, EventArgs e)
        {
            portInit();
        }

        /// <summary>
        /// Serial port initialization
        /// </summary>
        private void portInit()
        {
            string[] ports = SerialPort.GetPortNames();
            comboBox1.Items.AddRange(ports);
            comboBox1.SelectedItem = comboBox1.Items[0];
        }

Through the click event of the button 1 control, the serial port can be switched on and off. Through the text modification of the control, the function of a control can be turned on and off:

        #region Switch serial port
        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                if (!s.IsOpen)
                {
                    s.PortName = comboBox1.SelectedItem.ToString();
                    s.BaudRate = Convert.ToInt32(comboBox2.SelectedItem.ToString());
                    s.Open();
                    s.DataReceived += s_DataReceived; //"+="Represents the method to be called when specifying the response event
                    button1.Text = "Close the serial port";
                }
                else
                {
                    s.Close();
                    s.DataReceived -= s_DataReceived;
                    button1.Text = "Open serial port";
                }
            }
            catch(Exception ee)
            {
                MessageBox.Show(ee.ToString());
            }
        }
        #endregion

For serial port data reception and data analysis, first obtain the byte length of data in the data reception buffer, and confirm whether the length is the length in the setting. If it is the set 8-bit data length, analyze the received data:

        #region Serial port receiving
        void s_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            int count = s.BytesToRead;
            string str = null;
            if (count == 8)
            {
                //Data analysis
                byte[] buff = new byte[count];
                s.Read(buff, 0, count);
                foreach (byte item in buff)
                {
                    str += item.ToString("X2") + " ";
                }
                richTextBox1.Text = "[" + System.DateTime.Now.ToString() + "] " + str + "\n" + richTextBox1.Text;
                if (buff[0] == 0x04)
                {
                    ID.Text = buff[0].ToString();
                    switch (buff[2])
                    {
                        case 0x01:
                            {
                                Tem.Text = (buff[5] * 4 + buff[4] * 0.05 - 30).ToString();
                                Hum.Text = (buff[6] + buff[7]).ToString();
                                break;
                            }
                        case 0x02:
                            {
                                Light.Text = (buff[6] + buff[7]).ToString();
                                break;
                            }
                        case 0x04:
                            {
                                Dust.Text = (buff[6] + buff[7]).ToString();
                                break;
                            }
                        default:
                            break;
                    }
                }
            }
            else
            {
                //When the received data is not within the set data bit range, the received data will always be stored in the receiving buffer, and the last data will be superimposed every time the data is received, resulting in the data in the buffer can only be cleared by closing the serial port
                s.DiscardInBuffer(); //Discards data from the receive buffer of the serial driver
            }
        }
        #endregion

When the length of the received data is not equal to 8, the data from the receiving buffer of the serial driver will be discarded. Next, through breakpoint debugging, analyze the two cases of discarding the buffer and not discarding the buffer data for simulation, and analyze the following points.

  • Use the serial port assistant to send the data with the length of 8 bits to the upper computer. The display interface of the serial port debugging assistant and the terminal of the upper computer is as follows. The data at the sending end is the same as that at the receiving end, and there is no exception:

 

  • After modifying the data bit sent by the serial port debugging assistant to 9 bits and sending it, it can be found that the upper computer does not receive relevant data:

 

  • Then modify the sending data bit of the serial port debugging assistant to 8 bits. It can be found that the upper computer has not received the data from the serial port debugging assistant. Why?

 

  • Next, the debugging will be carried out step by step through the breakpoint to explain why the upper computer does not receive the data sent by the debugging assistant. When the data length sent by the serial port debugging assistant is 9 bits, the data length in the receiving buffer can be viewed through the monitor as 9 bits

 

 

  • After clicking send for the first time, the host computer fails to receive the data successfully. We will be curious, and generally click for the second time, the third time, or even keep clicking to observe whether there will be any abnormal phenomenon. When clicking for the second time, through the monitoring window, we can observe that the data length of the serial port buffer becomes 18, because the buffer retains the last received data and does not delete it, Even if the length of the data sent next time is 8 bits, it is also saved to the buffer by superposition, which will cause the data bit length of the buffer to be greater than 8 all the time; If you do not discard the data from the receiving buffer of the serial driver through the s.DiscardInBuffer() method, you can only clear the data from the buffer by closing the serial port and then reopening the corresponding serial port.

 

  • Use s.DiscardInBuffer() to discard data that does not meet the length. The effect is as follows:

 

Friends who need complete source code can download it through the following link. If there are leaders who have better optimization opinions, welcome to discuss it together. Thank you!

Link: https://pan.baidu.com/s/1Yb1YjdAZfficRtx2srBpzw
Extraction code: 7yc2

 

Tags: C#

Posted by fantic on Fri, 06 May 2022 21:33:18 +0300