Unity3D 串口通讯(二)---进行串口通讯
传送门:Unity3D 串口通讯(一)---添加虚拟串口
写在前面:
代码中引用using System.IO.Ports;报错的话,把PlayerSettings界面下的OtherSettings下的Api Comatibility Level改为.NET2.0。
一、新建一个Dropdown,用于串口的切换,总共涉及两个脚本:SerialNameDropDown、SerialCommunication,把SerialNameDropDown脚本挂载在DropDown控件上。运行效果如下:
? ? ? ?由于我这里com2跟com3是一对虚拟的串口,所以与com1不能进行通讯,只能com2、com3之间互通。
二、脚本如下:
using System;
using System.Collections.Generic;
using System.IO.Ports;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class SerialNameDropDown : MonoBehaviour , IPointerDownHandler
{
private Dropdown portDropdown;
private List<string> portNames;
void Start ()
{
portDropdown = GetComponent<Dropdown>();
portDropdown.onValueChanged.AddListener(delegate { DropdownValueChanged(portDropdown); });
}
void OnGUI()
{
if (SerialCommunication.sp != null && SerialCommunication.sp.IsOpen)
{
byte[] data = { 0x01, 0x10, 0x00, 0x03, 0x00, 0x07, 0x0E, 0x00, 0x04, 0x00, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x46, 0x70, 0xD5 };
if (GUILayout.Button("SendData", GUILayout.Height(50), GUILayout.Width(100)))
{
SerialCommunication.SendData(data);
}
string by = "01 10 00 03 00 07 0E 00 04 00 46 00 00 00 00 00 00 00 04 00 46 70 D5";
if (GUILayout.Button("Send", GUILayout.Height(50), GUILayout.Width(100)))
{
SerialCommunication.SendData(SerialCommunication.StringToBytes(by));
}
}
}
public void OnPointerDown(PointerEventData eventData)
{
//如果有串口打开,关闭串口
SerialCommunication. ClosePort();
关闭接收数据的线程
//readThread.Abort();
portNames = new List<string>(GetPortNames());
//串口列表不为空时
if (portNames.Count > 0)
{
portNames.Sort();
//清除下拉列表中的选项列表
portDropdown.ClearOptions();
//根据串口列表,将多个选项添加到Dropdown的选项中
portDropdown.AddOptions(portNames);
}
}
/// <summary>获取串口
/// </summary>
/// <param name="ports"></param>
public string[] GetPortNames()
{
string[] portName;
try
{
portName = SerialPort.GetPortNames();
if (portName.Length == 0)
{
portName = null;
}
}
catch (Exception e)
{
Debug.LogError("串口错误" + e.ToString());
portName = null;
}
return portName;
}
private void DropdownValueChanged(Dropdown portDropdown)
{
//串口列表不为空时,打开串口
if (portNames.Count > 0)
{
Debug.Log(portNames[portDropdown.value]);
//要打开的串口
SerialCommunication.portName = portNames[portDropdown.value];
SerialCommunication.OpenPort();
}
}
}
using System;
using System.IO.Ports;
using System.Threading;
using UnityEngine;
public class SerialCommunication
{
public static string portName;//串口名
private static readonly int baudRate = 38400;//波特率
private static readonly Parity parity = Parity.None;//校验位
private static readonly int dataBits = 8;//数据位
private static readonly StopBits stopBits = StopBits.One;//停止位
public static SerialPort sp = null;
public static Thread dataReceiveThread;//接收数据进程
//void Start()
//{
// dataReceiveThread = new Thread(new ThreadStart(DataReceiveFunction));
//}
/// <summary>
/// 打开端口
/// </summary>
public static void OpenPort()
{
sp = new SerialPort(portName, baudRate, parity, dataBits, stopBits);
sp.ReadTimeout = 400;
try
{
sp.Open();
Debug.Log("打开端口:" + portName + "成功!");
}
catch (Exception ex)
{
Debug.Log(ex.Message);
}
}
/// <summary>
/// 关闭端口
/// </summary>
public static void ClosePort()
{
try
{
sp.Close();
sp.Dispose();
//dataReceiveThread.Abort();//关闭接收数据进程
Debug.Log("关闭端口");
}
catch (Exception ex)
{
Debug.Log(ex.Message);
}
}
/// <summary>
/// 发送数据
/// </summary>
/// <param name="dataStr"></param>
public static void SendData(byte[] dataStr)
{
if (sp.IsOpen)
{
sp.Write(dataStr, 0, dataStr.Length);
Debug.Log("发送成功");
}
}
static int num = 0;
/// <summary>
/// 接收数据
/// </summary>
public static void DataReceiveFunction()
{
byte[] buffer = new byte[8];
int bytes = 0;
string[] d = new string[buffer.Length];
while (true)
{
if (sp != null && sp.IsOpen)
{
try
{
bytes = sp.Read(buffer, 0, buffer.Length);
sp.DiscardOutBuffer();
string s = "";
for (int i = 0; i < buffer.Length; i++)
{
if (bytes == 0)
continue;
else
{
d[i] = Convert.ToString(buffer[i], 8);
}
}
num++;
for (int x = 0; x < d.Length; x++)
s += d[x];
Debug.Log(s + ";" + num);//打印接收的数据
}
catch (Exception ex)
{
if (ex.GetType() != typeof(ThreadAbortException))
{
//Debug.Log(ex.Message);
}
}
}
Thread.Sleep(10);
}
}
/// <summary>
/// 字符串转字节流
/// </summary>
/// <param name="str">字符串</param>
/// <returns></returns>
public static byte[] StringToBytes(string str)
{
if (string.IsNullOrEmpty(str))
{
return new byte[0];
}
string s = str.Replace(" ", "");
int count = s.Length / 2;
var result = new byte[count];
for (int i = 0; i < count; i++)
{
var tempBytes = Byte.Parse(s.Substring(2 * i, 2), System.Globalization.NumberStyles.HexNumber);
result[i] = tempBytes;
}
return result;
}
}
|