"Unity development can also be linked to hardware"-come and take a look (serial communication)

"Unity development can also be linked to hardware"-come and take a look (serial communication)

1. C# serial port introduction and simple serial port communication program design and implementation

Simple serial communication tool, based on C# application WinFrom

Serial port introduction

Serial interface is abbreviated as serial port, also called serial communication interface or serial communication interface (usually referred to as COM interface), which is an extended interface using serial communication. (As for further details, Baidu yourself)

Serial port application

It is widely used in industrial fields, such as: data acquisition, equipment control, etc., many of which are realized by serial communication! If you are careful, you will find that the current home state grid smart energy meter has RS485 communication bus (a type of serial bus) and RS232 can be mutually converted (of course, non-professionals will not be spared. Look blindly on the meter, at most you can see how many kilowatt-hours are gone)

Introduction to RS232 DB9

1. Schematic

2. Pin introduction

  • Carrier Detect (DCD)
  • Receive data (RXD)
  • Send data (TXD)
  • Data terminal ready (DTR)
  • Signal ground (SG)
  • Data ready (DSR)
  • Request to send (RTS)
  • Clear to send (CTS)
  • Ringing indication (RI)

3. Physical map

The following is a USB to serial cable: this head is a male head, and the other end is a USB port

Stupid kid serial tool running diagram

1. Start the program

2. Send a line of string HelloBenXH

It can be tested by directly linking the sending and receiving of the pins (pin 2 receives data (RXD) and 3 sends data (TXD))

C# code implementation: using SerialPort

1. Instantiate a SerialPort

private SerialPort ComDevice = new SerialPort(); Copy code

2. Initial parameter binding to receive data events

public void init () { btnSend.Enabled = false ; cbbComList.Items.AddRange(SerialPort.GetPortNames()); if (cbbComList.Items.Count> 0 ) { cbbComList.SelectedIndex = 0 ; } cbbBaudRate.SelectedIndex = 5 ; cbbDataBits.SelectedIndex = 0 ; cbbParity.SelectedIndex = 0 ; cbbStopBits.SelectedIndex = 0 ; pictureBox1.BackgroundImage = Properties.Resources.red; ComDevice.DataReceived += new SerialDataReceivedEventHandler(Com_DataReceived); //Binding event } Copy code

3. Open the serial button event

/// <summary> /// Open the serial port /// </summary> /// <param name="sender"> </param> /// <param name="e"> </param> private void btnOpen_Click ( object sender, EventArgs e ) { if (cbbComList.Items.Count <= 0 ) { MessageBox.Show( "No serial port was found, please check the line!" ); return ; } if (ComDevice.IsOpen == false ) { ComDevice.PortName = cbbComList.SelectedItem.ToString(); ComDevice.BaudRate = Convert.ToInt32(cbbBaudRate.SelectedItem.ToString()); ComDevice.Parity = (Parity)Convert.ToInt32(cbbParity.SelectedIndex.ToString()); ComDevice.DataBits = Convert.ToInt32(cbbDataBits.SelectedItem.ToString()); ComDevice.StopBits = (StopBits)Convert.ToInt32(cbbStopBits.SelectedItem.ToString()); try { ComDevice.Open(); btnSend.Enabled = true ; } catch (Exception ex) { MessageBox.Show(ex.Message, "Error" , MessageBoxButtons.OK, MessageBoxIcon.Error); return ; } btnOpen.Text = "Close the serial port" ; pictureBox1.BackgroundImage = Properties.Resources.green; } else { try { ComDevice.Close(); btnSend.Enabled = false ; } catch (Exception ex) { MessageBox.Show(ex.Message, "error" , MessageBoxButtons.OK, MessageBoxIcon.Error); } btnOpen.Text = "Open the serial port" ; pictureBox1.BackgroundImage = Properties.Resources.red; } cbbComList.Enabled = !ComDevice.IsOpen; cbbBaudRate.Enabled = !ComDevice.IsOpen; cbbParity.Enabled = !ComDevice.IsOpen; cbbDataBits.Enabled = !ComDevice.IsOpen; cbbStopBits.Enabled = !ComDevice.IsOpen; } Copy code

4. Send data

/// <summary> /// Send data /// </summary> /// <param name="sender"> </param> /// <param name="data"> </param> public bool SendData ( byte [] data ) { if (ComDevice.IsOpen) { try { ComDevice.Write(data, 0 , data.Length); //Send data return true ; } catch (Exception ex) { MessageBox.Show(ex.Message, "Error" , MessageBoxButtons.OK, MessageBoxIcon.Error); } } else { MessageBox.Show( "Serial port is not open" , "error" , MessageBoxButtons.OK, MessageBoxIcon.Error); } return false ; } /// <summary> /// Send data button event /// </summary> /// <param name="sender"> </param> /// <param name="e"> </param> private void btnSend_Click ( object sender, EventArgs e ) { byte [] sendData = null ; if (rbtnSendHex.Checked) { sendData = strToHexByte(txtSendData.Text.Trim()); } else if (rbtnSendASCII.Checked) { sendData = Encoding.ASCII.GetBytes(txtSendData.Text.Trim()); } else if (rbtnSendUTF8.Checked) { sendData = Encoding.UTF8.GetBytes(txtSendData.Text.Trim()); } else if (rbtnSendUnicode.Checked) { sendData = Encoding.Unicode.GetBytes(txtSendData.Text.Trim()); } else { sendData = Encoding.ASCII.GetBytes(txtSendData.Text.Trim()); } if ( this .SendData(sendData)) //Send data success count { lblSendCount.Invoke( new MethodInvoker( delegate { lblSendCount.Text = ( int .Parse(lblSendCount.Text) + txtSendData.Text.Length).ToString(); })); } else { } } /// <summary> /// String conversion hexadecimal byte array /// </summary> /// <param name="hexString"> </param> /// <returns> </returns> private byte [] strToHexByte ( string hexString ) { hexString = hexString.Replace( "" , "" ); if ((hexString.Length% 2 ) != 0 ) hexString += "" ; byte [] returnBytes = new byte [hexString.Length/2 ]; for ( int i = 0 ; i <returnBytes.Length; i++) returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2 , 2 ).Replace( "" , "" ), 16 ); return returnBytes; } Copy code

5. Receiving and data output

/// <summary> /// Receive data /// </summary> /// <param name="sender"> </param> /// <param name="e"> </param> private void Com_DataReceived ( object sender, SerialDataReceivedEventArgs e ) { byte [] ReDatas = new byte [ComDevice.BytesToRead]; ComDevice.Read (ReDatas, 0 , ReDatas.Length); //read the data the this .AddData (ReDatas); //the output data } /// <summary> /// Add data /// </summary> /// <param name="data"> byte array </param> public void AddData ( byte [] data ) { if (rbtnHex.Checked) { StringBuilder sb = new StringBuilder(); for ( int i = 0 ; i <data.Length; i++) { sb.AppendFormat( "{0:x2}" + "" , data[i]); } AddContent(sb.ToString().ToUpper()); } else if (rbtnASCII.Checked) { AddContent( new ASCIIEncoding().GetString(data)); } else if (rbtnUTF8.Checked) { AddContent( new UTF8Encoding( ).GetString(data)); } else if (rbtnUnicode.Checked) { AddContent( new UnicodeEncoding().GetString(data)); } else {} lblRevCount.Invoke( new MethodInvoker( delegate { lblRevCount.Text = ( int .Parse(lblRevCount.Text) + data.Length).ToString(); })); } /// <summary> /// Enter into the display area /// </summary> /// <param name="content"> </param> private void AddContent ( string content ) { this .BeginInvoke( new MethodInvoker( delegate { if (chkAutoLine.Checked && txtShowData.Text.Length> 0 ) { txtShowData.AppendText( "\r\n" ); } txtShowData.AppendText(content); })); } Copy code

6. Clear data area event

/// <summary> /// Clear the receiving area /// </summary> /// <param name="sender"> </param> /// <param name="e"> </param> private void btnClearRev_Click ( object sender, EventArgs e ) { txtShowData.Clear(); } /// <summary> /// Clear the sending area /// </summary> /// <param name="sender"> </param> /// <param name="e"> </param> private void btnClearSend_Click ( object sender, EventArgs e ) { txtSendData.Clear(); } Copy code

Run the program download address BXHSerialPort.exe source code project file download

OK step into the topic

2. Development of Unity3d and serial communication program

First make a simple UI to control the switch of the serial device

The code is relatively simple

Custom port API class

using System; //First introduce this namespace using System.IO.Ports; //This is the defined parameter of the connected serial device, sending this parameter can control the serial device public enum PortsType { //01, fully open: PC sends'I'; //02, fully closed: PC sends'i'; I,i, //03. The first channel is on: PC sends'A'; //04. The second channel is on: PC sends'B'; //05. The third channel is on: PC sends'C'; //06, Four-way open: PC sends'D'; //07, Fifth route open: PC sends'E'; //08, Sixth route open: PC sends'F'; //09, Seventh route open: PC Send'G'; //10. The eighth road is open: PC sends'H'; A,B,C,D,E,F,G,H, //11. The first pass: PC sends'a'; //12. The second pass: PC sends'b'; //13. The third pass: PC sends'c'; //14. Four-way pass: PC sends'd'; //15, Fifth pass: PC sends'e'; //16, Sixth pass: PC sends'f'; //17, Seventh pass: PC Send'g'; //18. The eighth pass: PC sends'h'; a,b,c,d,e,f,g,h } public class PortsContol { //The first parameter is the name of the port. I will talk about how to see the port. The second parameter is the baud rate. This is the parameter of the device itself. SerialPort sp = new SerialPort( "COM3" , 9600 ); //Declare one Serial port //This is a complete parameter, the name is port name, baud rate, parity check, data bits, flow control parameters //SerialPort sp1 = new SerialPort("COM3", 9600, Parity.None, 8, StopBits.None ); //This is a sending API, other programs call this API public void Send_Click ( PortsType data ) { sp.Open(); switch (data) { case PortsType.I: //Send data to the port sp.WriteLine( "I" ); break ; case PortsType.i: sp.WriteLine( "i" ); break ; case PortsType.A: sp.WriteLine( "A" ); break ; case PortsType.B: sp.WriteLine( "B" ); break ; case PortsType.C: sp.WriteLine( "C" ); break ; case PortsType.D: sp.WriteLine( "D" ); break ; case PortsType.E: sp.WriteLine( "E" ); break ; case PortsType.F: sp.WriteLine( "F" ); break ; case PortsType.G: sp.WriteLine( "G" ); break ; case PortsType.H: sp.WriteLine( "H" ); break ; case PortsType.a: sp.WriteLine( "a" ); break ; case PortsType.b: sp.WriteLine( "b" ); break ; case PortsType.c: sp.WriteLine( "c" ); break ; case PortsType.d: sp.WriteLine( "d" ); break ; case PortsType.e: sp.WriteLine( "e" ); break ; case PortsType.f: sp.WriteLine( "f" ); break ; case PortsType.g: sp.WriteLine( "g" ); break ; case PortsType.h: sp.WriteLine( "h" ); break ; default : break ; } sp.Close(); } } Copy code

Unity call

using UnityEngine; using System.Collections; public class ButtonClick1 : MonoBehaviour { //Initialize the custom port class PortsContol pc = new PortsContol(); //Use this for initialization void Start () { } //Update is called once per frame void Update () { } //The function called by the button "Open" public void Open_Click () { //The parameter is the enumeration in the custom class pc.Send_Click(PortsType.I); } //The function called by the button "close" public void Close_Click () { pc.Send_Click(PortsType.i); } //The function called by the button " 1Open " public void OneOpen_Click () { pc.Send_Click(PortsType.A); } //The function called by the button "1 Close" public void OneClose_Click () { pc.Send_Click(PortsType.a); } } Copy code

The script is bound to the main camera, the button Button calls the function OK on the main camera, and that's it, you can use Unity3d to control the serial port program

3. serial port to send data

text

1. Make a UI interface first

2. Code

using UnityEngine; using System.IO.Ports; using System.Text; using UnityEngine.UI; public class SerialPortTest : MonoBehaviour { private SerialPort sp = new SerialPort(); public Text m_TextSendDataPar; public Text m_TextShowData; //Use this for initialization void Start () { //Open the serial port Init( "COM1" , 9600 , Parity.None, 8 , StopBits.None); } //Send data button public void Btn_SendData () { Data_Send(m_TextSendDataPar.ToString()); } //Initialize the serial port class public void Init ( string _portName, int _baudRate,Parity _parity, int dataBits,StopBits _stopbits ) { sp = new SerialPort(_portName, _baudRate, _parity, dataBits, _stopbits); //Binding port sp.DataReceived += new SerialDataReceivedEventHandler(Data_Received); //Subscription commission } //Receive data private void Data_Received ( object sender, SerialDataReceivedEventArgs e ) { byte [] ReDatas = new byte [sp.BytesToRead]; sp.Read(ReDatas, 0 , ReDatas.Length); //Read data this .Data_Show(ReDatas); //Display data } /// <summary> /// Display data /// </summary> /// <param name="data"> byte array </param> public void Data_Show ( byte [] data ) { StringBuilder sb = new StringBuilder(); for ( int i = 0 ; i <data.Length; i++) { sb.AppendFormat( "{0:x2}" + "" , data[i]); } Debug.Log(sb.ToString()); m_TextShowData.text = sb.ToString(); } //Send data public void Data_Send ( string _parameter ) { sp.Open(); sp.WriteLine(_parameter); sp.Close(); } } Copy code

3. Binding parameters

4. The problem of not being able to find the namespace

In Unity, I referenced System.IO.Ports but found that the reference was not available. I checked it and saw that you need to modify the [API Compatibility Level] of [Optimization] under [Other Settings] to be under [Edit->Project Settings->Player] [.NET 2.0] (The default is [.NET 2.0 Subset]. Can be found

*PS: Thank you for your reminder

OK. . . Guys can try it right, the data is just received and then displayed, how to parse it, get the port number and so on, let the guys do it themselves. .