Realize simple serial port communication on PC through Unity

The code only implements a simple string sending and receiving operation, and the serial port is closed. There are detailed comments in the code, and the method notes used in learning serial port communication

Error: When the serial port is closed, there will be a prompt that the serial port reads abnormally. I am a novice and have not found the reason.

attach code

The script is called "zibian"

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO.Ports;
using System.Threading;
using System;
using System.Text;

public class zibian : MonoBehaviour
{
    public string portName = "COM3";//串口
    public int baudRate = 9600;//波特率
    public Parity parity = Parity.None;//效验位
    public int dataBits = 8;//数据位
    public StopBits stopBits = StopBits.None;//停止位
    SerialPort serialPort=null;//端口
    Thread thread;//数据接收线程
    List<byte> list=new List<byte>();//泛型队列
    Queue<string> queue = new Queue<string>();
    string str_data;//接收消息队列
    char[] strchar = new char[100];//接收的字符信息转换为字符数组信息
    

    // Start is called before the first frame update
    void Start()
    {
        OpenPort();//打开串口
        thread = new Thread(new ThreadStart(DataReviceThread));//创建线程方法和处于线程中的方法
        thread.Start();//启动线程
    }

    // Update is called once per frame
    void Update()
    {
        
    }

    public void OpenPort()//打开串口
    {
        print("打开串口");
        serialPort = new SerialPort(portName, baudRate, parity, dataBits, stopBits);
       
        try
        {
            serialPort.Open();
        }
        catch(Exception ex)
        {
            print("串口打开异常:" + ex.Message);
        }
    }

    public void ClosePort()//关闭串口
    {
        print("关闭串口");
        try
        {
            serialPort.Close();//关闭端口
            thread.Abort();//终止线程
        }
        catch (Exception ex)
        {
            print("串口关闭异常:" + ex);
           
        }
    }

    private void OnApplicationQuit()//关闭程序或退出播放时调用关闭串口方法
    {
        ClosePort();
    }

    public void WriteData(string dataStr)//发送数据电脑往硬件发送
    {
        if (serialPort.IsOpen)
        {
            serialPort.Write(dataStr);//发送数据
        }
    }

    void DataReviceThread()//接收数据 外设到电脑
    {
        byte[] bytes_vs = new byte[1024];//存储字节
        int count;//存储字节长度
        while (serialPort != null && serialPort.IsOpen)
        {
            try
            {
                count = serialPort.BytesToRead;//获取接收缓冲区中数据的字节数。
                serialPort.Read(bytes_vs, 0, count);//读取消息并获取字节
                //count = serialPort.Read(bytes_vs, 0, bytes_vs.Length);//读取消息并获取字节
                if (count==0)
                {
                    continue;
                }
                else
                {
                    print("字节数量:" + count);//输出字节数
                    //string str1 = Encoding.UTF8.GetString(bytes_vs);//将字节转换成字符串并输出
                    //print(str1);


                    StringBuilder stringBuilder = new StringBuilder();//创建动态可变字符串
                    for (int i = 0; i < count; i++)
                    {
                        stringBuilder.Append(Convert.ToString(bytes_vs[i]));//将Bytes数据类型转换位string数据类型,并添加在字符串末尾
                    }
                    str_data = stringBuilder.ToString();//StringBuilder对象转换为string对象
                    print(str_data);//输出字符串
                    queue.Enqueue(str_data);//将接收的消息放入队列
                }
            }
            catch (Exception ex)
            {
                print("串口读取异常:" + ex.Message);
                
            }
            Thread.Sleep(10);//将当前线程挂起指定的时间。
        }
    }

    void PrintData()  //打印数据
    {
        for (int i = 0; i < list.Count; i++)
        {
            strchar[i] = (char)(list[i]);
            str_data = new string(strchar);
        }
        Debug.Log(str_data);
    }
}

Simple steps

1. Create an empty object a1 in Unity and drag the script into it.

2. Create a button button in Unity, create an event in the click event, drag a1 into the event, and refer to the WriteData() method in the script.

3. Download and install the virtual serial port vspdconfig, and create virtual serial ports COM3 and COM4 in the software

4. Install the serial port debugging assistant, XCOM or XTC-ISP, etc., I use XCOM

5. Open the serial port assistant, select COM4 as the serial port, and open the serial port.

6. Enter Unity and click Run. After the console prompts to open the serial port, the string serial port communication on the computer can be realized, and the ASCII code is transmitted during the communication between the two parties.

The following are the methods and classes used in learning serial communication

Note: More, better and more detailed introductions to methods and classes should be viewed in the .NET documentation of VS

Unity serial communication

tutorial

Referencing the namespace: System.IO.Ports

Serialport   class

The process is to set the communication port number, baud rate, data bit, stop bit and parity bit, then open the port connection, send data, receive data, and finally close the port connection step.

namespace used

using System.IO.Ports;

using System.IO;

using System.Threading;

using System;

using System.Text;

declare variable

public string portName = "COM4" ; // serial port number

    public int baudRate = 9600; // baud rate

    public Parity parity = Parity.None; // check bit

    public int dataBits = 8; // data bits

    public StopBits stopBits = StopBits.One; // stop bit

    SerialPort sp = null ;// Declare the serial port

SerialPort(); When using it, you must first declare a variable type that represents the serial port resource.

SerialPort (string portName, int baudRate, Parity parity, int dataBits, StopBits stopBits);

SerialPort( port name , baud rate , parity bits , data bits , stop bits )

例SerialPort sp=new SerialPort(portName, baudRate, parity, dataBits, stopBits)

To specify the port name, baud rate, parity bits, data bits, and stop bits, use this constructor to create a new instance of the class.

IsOpen ; Get a value indicating the open or closed state of the SerialPort (serial port) object. The default is false. Serial port name.IsOpen;

sp . Open() ; Open the serial port.

sp . Close() ; Close the serial port.

The number of milliseconds before a timeout occurs while the ReadTimeout operation is incomplete. The read timeout value is initially set to 500 milliseconds. The timeout value can be set to any value greater than zero.

Example: Sp.ReadTimeout=400;

_data==System.Text.Encoding.ASCII.GetBytes(testString)[0].ToString()

Encode the string tesString according to Simplified Chinese (ASCIIEncoding.ASCII),

Encoded into a byte stream array of Bytes type; judge whether the ASCII code of the string input by the peripheral is converted into a string consistent with the _data string

sp.Read(Byte[], Int32, Int32)sp.Read(Char[], Int32, Int32)

     Byte array, offset, maximum number of bytes to read character array

Reads some bytes from the SerialPort input buffer and writes those bytes at the specified offset in the byte array.

System.Text.Reference namespace

The Encoding class represents character encoding

Encoding.Default property to get the default encoding for this .NET implementation . It is recommended to use the Encoding. UTF8 attribute, the effect is the same and better, and it is not easy to lose data

Encoding. ASCII Gets the encoding for the ASCII (7-bit) character set.

Encoding.ASCII.GetBytes ( String ) When overridden in a derived class, encodes a set of characters as a sequence of bytes .

Encoding.UTF8.GetString ( Byte[ ] ) : When overridden in a derived class, decodes a sequence of bytes into a string.

Write() : Write data to the serial port output buffer

WriteLine() : Writes the specified string to the serial port output buffer

System.Text.Reference namespace

The StringBuilder class  represents mutable character strings. This class cannot be inherited. routines commonly used to perform extensive string manipulation

Instantiate the object: StringBuilder s1 = new StringBuilder (" String");

or StringBuilder s1 = new StringBuilder (" String", String capacity int);

s1.Append appends the information to the current end of s1      .

Convert StringBuilder object to string String:

s1.ToString();

A StringBuilder object must be converted to a String object before the string represented by the StringBuilder object can be passed to a method that includes a String parameter, or displayed in a user interface.

Convert class

Convert one data type to another specific data type. Convertible data types include ToInt32 , ToBoolean, ToString, ToChar, etc.

Example: string s2= Convert . ToString (data variable name)

yield return new WaitForSeconds(Time.deltaTime);   delay

OnApplicationQuit() is a method API sent to all game objects before the application exits. In the Editor, this function will be called when the user stops the playback mode.

OnDisable() is a method API that is called when the behavior is disabled, it is also called when the object is destroyed, it can be used in any cleanup code. OnDisable is called when the script is reloaded after compilation, and OnEnable is called after the script is loaded, cannot be used as a coroutine.

The Thread class creates and controls threads, sets their priority and obtains their status.

Thread variable name = new Thread(new ThreadStart ( method ))

variablename.Start ( ); // Causes the operating system to change the state of the current instance to Running , and choose to provide the object containing the data to be used by the method executed by the thread.

Running means that   the thread has started and has not stopped.

Put it in the Start method

The data receiving thread, the method of receiving data is placed in the serial communication code

Thread. Sleep ( milliseconds): Suspend the current thread for the specified time. During the specified time, the thread will not be scheduled for execution by the operating system.

The Abort() method of terminating threads is obsolete and is not used in .net5.0

List<T> class

Namespace System.Collections.Generic

List <byte> variable name = new List <byte>(); // Create a generic interface, similar to an array, byte is a variable type

List<T> generic interface

He can store any type of data type.

T represents the type of elements in the List list. If it is List<int>, all its elements are of type int

For example, List<string> Liststr = new List<string>();

All data of string type can be added to Liststr, others cannot. When traversing, it is also traversed with string

List<T> .Count property: Get the number of elements contained in List<T>

Queue<T> class: Represents a first-in, first-out collection of objects.

Example to create a string queue with default capacity

Queue<string> q1 = new Queue<string>()

The Enqueue method queues five strings

q1 . Enqueue (" String 1");

q1 . Enqueue (" String 2");

q1 . Enqueue (" String 3");

q1 . Enqueue (" String 4");

q1 . Enqueue (" String 5");

The ToArray method is used to create an array and copy the queue elements to the array, then pass the array to Queue<T> | | and copy the queue elements to the array.

例:Queue<string> q1= new Queue<string>(numbers.ToArray());

The Dequeue() method is used to dequeue the first string.

Example q1.Dequeue ();

The Peek() method is used to view the next item in the queue

q1.Peek();

q1. The Count property gets the number of elements contained in Queue<T>.

question

The solution to the problem that the using System.IO.Ports namespace does not exist

1. First check whether the System.IO.Ports package is installed in Visual Studio.

Checking method: Tools→Nuget Package Manager→Manage the Nuget package of the solution→Search for Ports, or System.IO.Ports→Select System.IO.Ports→Check if it is installed, and it is not installed for him, but in general There are all of them.

2. Set the Api Compatibility Level* (Api Compatibility Level) to .NET 4.x

Steps: Fild(file)→Generation Settings→Player Settings→Player→Other Settings→Api Compatibility Level→.NET 4.x

This is the first upload for a novice, please forgive me for any mistakes. The article will continue to be added, deleted, modified and checked in future studies.

Guess you like

Origin blog.csdn.net/podaosanshiliu/article/details/118890566