c# Serial Communication and Processing Received Multiple Parameters

Keywords: Delphi encoding

Recently, I tried to make a PC and simply recorded the key parts.

The System.IO.Ports class is mainly used in c# serial communication, but it is very convenient in fact.
The final results are as follows:

Don't forget the following

Fill in the configuration of serial port

We can get the list of ports on this machine by GetPortNames method. Note that different devices may not have the same port after connecting to the computer.

string[] sps = SerialPort.GetPortNames();

Configure other serial port dependencies
For example, a baud rate list

string[] baud = { "300", "1200", "2400", "4800", "9600", "19200", "38400", "57600" };
comboBox2.Items.AddRange(baud);     //Add Baud Rate List

Open serial port

In fact, the main thing is to use the current serial properties to determine whether the open state?

private void Button1_Click(object sender, EventArgs e)
        {
            //trycatcj handles exceptions during serial port opening
            try
            {
                //Place code that may produce exceptions in try blocks
                //Judging whether to open or not according to the current serial port property
                if (serialPort1.IsOpen)
                {
                    //The serial port is already open
                    serialPort1.Close();    //Close serial port
                    button1.Text = "Open serial port";
                    button1.BackColor = Color.ForestGreen;
                    comboBox1.Enabled = true;
                    comboBox2.Enabled = true;
                    comboBox3.Enabled = true;
                    comboBox4.Enabled = true;
                    comboBox5.Enabled = true;
                   ReceptTb.Text = "";  //Clean up the receiving area
                    SendTb.Text = "";     //Clean up the sending area
                }
                else
                {
                    //If the serial port is already closed, it will be opened after setting the serial port property.
                    comboBox1.Enabled = false;
                    comboBox2.Enabled = false;
                    comboBox3.Enabled = false;
                    comboBox4.Enabled = false;
                    comboBox5.Enabled = false;
                    serialPort1.PortName = comboBox1.Text;
                    serialPort1.BaudRate = Convert.ToInt32(comboBox2.Text);
                    serialPort1.DataBits = Convert.ToInt16(comboBox3.Text);

                    if (comboBox4.Text.Equals("None"))
                        serialPort1.Parity = System.IO.Ports.Parity.None;
                    else if (comboBox4.Text.Equals("Odd"))
                        serialPort1.Parity = System.IO.Ports.Parity.Odd;
                    else if (comboBox4.Text.Equals("Even"))
                        serialPort1.Parity = System.IO.Ports.Parity.Even;
                    else if (comboBox4.Text.Equals("Mark"))
                        serialPort1.Parity = System.IO.Ports.Parity.Mark;
                    else if (comboBox4.Text.Equals("Space"))
                        serialPort1.Parity = System.IO.Ports.Parity.Space;

                    if (comboBox5.Text.Equals("1"))
                        serialPort1.StopBits = System.IO.Ports.StopBits.One;
                    else if (comboBox5.Text.Equals("1.5"))
                        serialPort1.StopBits = System.IO.Ports.StopBits.OnePointFive;
                    else if (comboBox5.Text.Equals("2"))
                        serialPort1.StopBits = System.IO.Ports.StopBits.Two;

                    serialPort1.Open();     //Open serial port
                    button1.Text = "Close serial port";
                    button1.BackColor = Color.Firebrick;
         
                    this.Activate();
                }
            }
            catch (Exception ex)
            {
                //Capture and process possible exceptions

                //Catch exceptions and create a new object that you can't reuse before
                serialPort1 = new System.IO.Ports.SerialPort();
                //Refresh COM Port Options
                comboBox1.Items.Clear();
                comboBox1.Items.AddRange(System.IO.Ports.SerialPort.GetPortNames());
                //Ring the bell and display the exception to the user
                System.Media.SystemSounds.Beep.Play();
                button1.Text = "Open serial port";
                button1.BackColor = Color.ForestGreen;
                MessageBox.Show(ex.Message);
                comboBox1.Enabled = true;
                comboBox2.Enabled = true;
                comboBox3.Enabled = true;
                comboBox4.Enabled = true;
                comboBox5.Enabled = true;
            }
        }

Message transmission

This is not too special, just call the Write method.

 private void SendBtn_Click(object sender, EventArgs e)
        {
            try
            {
                Console.WriteLine(serialPort1.IsOpen);
                //First, judge whether the serial port is open or not.
                if (serialPort1.IsOpen)
                {
                    //The serial port is open to send text from the sending area
                    serialPort1.Write(SendTb.Text);
                    SendTb.Text = "";
                }
            }
            catch (Exception ex)
            {
                //Catch exceptions and create a new object that you can't reuse before
                serialPort1 = new System.IO.Ports.SerialPort();
                //Refresh COM Port Options
                comboBox1.Items.Clear();
                comboBox1.Items.AddRange(System.IO.Ports.SerialPort.GetPortNames());
                //Ring the bell and display the exception to the user
                System.Media.SystemSounds.Beep.Play();
                button1.Text = "Open serial port";
                button1.BackColor = Color.ForestGreen;
                MessageBox.Show(ex.Message);
                comboBox1.Enabled = true;
                comboBox2.Enabled = true;
                comboBox3.Enabled = true;
                comboBox4.Enabled = true;
                comboBox5.Enabled = true;
            }
        }

In fact, the above basic functions only need to call methods and handle exceptions.

receive messages

This receipt of messages is very flexible, simple, difficult to say, but also a little difficult. If the requirements are not high, just to show the received messages, there can indeed be a very simple method.

This is the easiest way to do this. It's simply to stitch together the characters from the buffer. But if the incoming data is more than one type, we need to separate each of them. This kind of timely extraction from the buffer and stitching together is not suitable, because the characters from the buffer are not necessarily complete.

String str = serialPort1.ReadExisting();

So I turned to the search engine and learned that to solve this problem, we need to put the characters in the buffer first, wait for the buffer to accumulate a certain number of characters and then read them. After each extraction of a certain number of characters, we empty the buffer and convert the string of characters I got into an array.

        private void SerialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            try
            {
                //To access UI resources, you need to synchronize the UI using invoke
                this.Invoke((EventHandler)(delegate
                {
                    //String str = serialPort1.ReadExisting();
                    //string[] strArray = str.Split(',');

                    //Console.Write(str);
                    //ReceptTb.AppendText(str);
                    int byteNumber = serialPort1.BytesToRead;

                    Thread.Sleep(20);


                    //Delays wait for data to be received.
                    while ((byteNumber < serialPort1.BytesToRead) && (serialPort1.BytesToRead < 77))
                    {
                        byteNumber = serialPort1.BytesToRead;
                        Thread.Sleep(20);

                    }
                    int n = serialPort1.BytesToRead; //Record the number of bytes in the buffer 

                    //Console.WriteLine("n" + n);
                    byte[] buf = new byte[n]; //Declare a temporary array to store current serial data 
                    serialPort1.Read(buf, 0, n); //Read the buffer data into buf and remove it from the buffer 
                    string str = System.Text.Encoding.Default.GetString(buf);
                    string[] strArray = str.Split(',');
                    

                    int count = 0;
                    for (int i = 0; i < strArray.Length; i++)
                    {
                        if(count == 0)
                        {
                            textBox1.Text = strArray[i];
                        }else if(count == 1)
                        {
                            textBox2.Text = strArray[i];
                        }else if(count == 2)
                        {
                            textBox3.Text = strArray[i];
                        }
                        count++;
                        if(count == 3)
                        {
                            count = 0;
                        }

                    }


                    //string str = sb.ToString();
                    //float Num = float.Parse(str);


                    Console.Write(str);

                }
                   )
                );

            }
            catch (Exception ex)
            {
                //Ring the bell and display the exception to the user
                System.Media.SystemSounds.Beep.Play();
                MessageBox.Show(ex.Message);

            }
        }

Posted by brandone on Sat, 01 Jun 2019 10:56:23 -0700