using System;
using System.Collections;
using System.Collections.Generic;
using System.IO.Ports;
using UnityEngine;
using UnityEngine.UI;
public class ComPortControl : MonoBehaviour {
//COM串口
[Header("------COM串口------")]
public Image imgComStatus;
public Dropdown dropdownComList;
public Button bntOpenCom;
SerialPort sp = null;
bool isAlive = true;
// Use this for initialization
void Start()
{
//打开串口
bntOpenCom.onClick.AddListener(new UnityEngine.Events.UnityAction(delegate ()
{
ClosePort();
OpenPort(dropdownComList.options[dropdownComList.value].text);
}));
string[] portNames = System.IO.Ports.SerialPort.GetPortNames();
dropdownComList.AddOptions(new List(portNames));
if (portNames.Length > 0)
{
OpenPort(portNames[0]);
}
}
IEnumerator WriteCOMData()
{
if (sp != null)
{
for (int i = 0; i < 15; i++)
{
Byte[] TxData = { 0xF3, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x3F };
sp.Write(TxData, 0, 8);
Debug.Log(i + "次发串口指令成功");
yield return new WaitForSeconds(0.1f);
}
}
else
{
Debug.Log("发串口指令失败");
}
}
#region 创建串口,并打开串口
public void OpenPort(string portName)
{
string openPortName = portName;
//创建串口
int comNum = int.Parse(portName.Substring(3));
if (comNum > 9)
{
openPortName = "\\\\.\\" + portName;
}
try
{
sp = new SerialPort(openPortName, 9600, Parity.None, 8, StopBits.One);
sp.ReadTimeout = 50;
sp.Open();
if (sp != null && sp.IsOpen)
{
Debug.Log(portName + "串口已打开");
PlayerPrefs.SetString("IceBreakerComPort", portName);
imgComStatus.sprite = Resources.Load("Texture/greencircle");
StartCoroutine(DataReceiveFunction());
}
else
{
imgComStatus.sprite = Resources.Load("Texture/redcircle");
Debug.Log(portName + "串口未打开");
}
}
catch (Exception ex)
{
Debug.Log(ex.Message);
}
}
#endregion
IEnumerator DataReceiveFunction()
{
//应该读取的字节长度,可能多次读取才能成功
const int BYTE_ARRAY_SIZE = 36;
byte[] buffer = new byte[BYTE_ARRAY_SIZE];
int len = 0;
int previouseLen = 0;
while (isAlive)
{
if (sp != null && sp.IsOpen)
{
try
{
//接收字节
byte[] recData = new byte[BYTE_ARRAY_SIZE];
len = sp.Read(recData, 0, recData.Length);
if (previouseLen + len > BYTE_ARRAY_SIZE)
{
for (int i = 0; i < buffer.Length; i++)
{
buffer[i] = 0x00;
}
previouseLen = 0;
}
//和之前的字节拼接
for (int i = 0; i < len; i++)
{
buffer[previouseLen + i] = recData[i];
}
//拼接后的长度
int newLen = previouseLen + len;
string dataFromComPort = byteToHexStr(buffer, newLen);
if (!string.IsNullOrEmpty(dataFromComPort) && newLen == BYTE_ARRAY_SIZE)
{
Debug.Log(DateTime.Now.ToShortDateString()+ "串口消息:" + dataFromComPort);
}
//从后往前搜
int endIndex = ByteArrayReverseIndex(buffer, 0x3f);
int firstValueIndex = endIndex - 5;
//如果不满足要求继续接收
if (endIndex == -1 || firstValueIndex < 0)
{
previouseLen = newLen;
continue;
}
if (buffer[firstValueIndex] == 0x01)
{
Debug.Log("串口调试:识别到 0x01 运行");
}
else if (buffer[firstValueIndex] == 0x02)
{
Debug.Log("串口调试:识别到 0x02 急停");
}
else if (buffer[firstValueIndex] == 0x03)
{
Debug.Log("串口调试:识别到 0x03 复位");
}
//复制3f后面的数据作为下次起点
if (endIndex > 0)
{
//截取3f后面的字符串
byte[] tmpBuffer = new byte[newLen - (endIndex + 1)];
for (int j = endIndex + 1; j < newLen; j++)
{
tmpBuffer[j - (endIndex + 1)] = buffer[j];
}
//前移
for (int i = 0; i < buffer.Length; i++)
{
if (i < newLen - (endIndex + 1))
{
buffer[i] = tmpBuffer[i];
}
else
{
buffer[i] = 0x00;
}
}
//下次起点
previouseLen = newLen - (endIndex + 1);
}
}
catch (Exception ex)
{
//Debug.Log(ex.Message);
}
}
yield return null;
}
}
#region 程序退出时关闭串口
public void ClosePort()
{
if (sp == null)
return;
try
{
sp.Close();
isAlive = false;
//dataReceiveThread.Abort();
}
catch (Exception ex)
{
Debug.Log(ex.Message);
}
}
#endregion
/// 查找最后一个字符出现的索引
///
///
///
///
private int ByteArrayReverseIndex(byte[] buffer, byte b)
{
int index = -1;
for (int i = 0; i < buffer.Length; i++)
{
if (buffer[i] == b)
{
index = i;
}
}
return index;
}
void OnDestroy()
{
ClosePort();
}
///
/// 获取下拉列表某项的索上
///
/// 下拉列表
/// 某项文字
/// 索引
public static int GetDropdownIndex(Dropdown dd, string str)
{
int i = 0;
int index = 0;
foreach (var op in dd.options)
{
if (op.text.Equals(str))
{
index = i;
break;
}
i++;
}
return index;
}
private static string byteToHexStr(byte[] bytes, int length)
{
string returnStr = "";
if (bytes != null)
{
for (int i = 0; i < length; i++)
{
returnStr += bytes[i].ToString("X2");
}
}
return returnStr;
}
}
Unity3d读写COM串口
关注
打赏