using System;
using System.Collections;
using System.Collections.Generic;
using System.IO.Ports;
using System.Text;
using UnityEngine;
public class PortManager : MonoBehaviour
{
#region 参数
string getPortName;
int baudRate = 115200;
private Parity parity = Parity.None;
private int dataBits = 8;
private StopBits stopBits = StopBits.One;
SerialPort sp = null;
private string _data;
string reciveString;
//配置文件类
public ConfigTest thisConfigTest;
private Queue<byte[]> receiveMsg = new Queue<byte[]>(); //接收的消息
private Queue<byte[]> sendMsg = new Queue<byte[]>(); //发送的消息
private bool detection = false; //消息锁
private float overtime = 3f; //判断超时
private float dt_time = 0.02f;
#endregion
#region 常规方法
// Use this for initialization
void Start()
{
//reciveString = thisConfigTest.dic["接收信号"]["receiveString"];
//OpenPort(getPortName);
//StartCoroutine(DataReceiveFunction());
}
private void Update()
{
}
#endregion
#region 串口通信控制
/// <summary>
/// 串口信号控制
/// </summary>
private void PortSignalControl()
{
if (_data == System.Text.Encoding.ASCII.GetBytes(reciveString)[0].ToString())
{
//Debug.Log("收到串口信号" + testString);
}
}
//打开串口
public void OpenPort(string DefaultPortName)
{
sp = new SerialPort(DefaultPortName, baudRate, parity, dataBits, stopBits);
sp.ReadTimeout = 10;//操作超出时间 这个时间越长报错越少,但不能太长
try
{
if (!sp.IsOpen)
{
sp.Open();
}
}
catch (Exception ex)
{
Debug.Log(ex.Message);
}
}
public void OpenPort(string DefaultPortName, int baudRate)
{
sp = new SerialPort(DefaultPortName, baudRate, parity, dataBits, stopBits);
sp.ReadTimeout = 10;//操作超出时间 这个时间越长报错越少,但不能太长
try
{
if (!sp.IsOpen)
{
sp.Open();
}
}
catch (Exception ex)
{
Debug.Log(ex.Message);
}
}
//关闭串口
public void ClosePort()
{
try
{
sp.Close();
}
catch (Exception ex)
{
Debug.Log(ex.Message);
}
}
/// <summary>
/// 开启 发送数据以及接收数据的检测
/// </summary>
public void Detection()
{
StopCoroutine("DataDetectionFunction");
StartCoroutine("DataDetectionFunction");
}
IEnumerator DataDetectionFunction()
{
Debug.Log("检测打开");
while (true)
{
if (detection)
{
byte[] _send = new byte[1024];
byte[] _receive = new byte[1024];
yield return new WaitForSeconds(dt_time);
if (receiveMsg.Count == 0)
{
yield return new WaitForSeconds(overtime);
Debug.Log("检测超时:接收包为:" + receiveMsg.Count + "重新发送");
_send = sendMsg.Dequeue();
SendSerialPortData(_send);
}
else
{
if (sendMsg.Count != 0)
_send = sendMsg.Dequeue();
if (receiveMsg.Count != 0)
_receive = receiveMsg.Dequeue();
if (CompareByte(_send[_send.Length - 1], _receive[_receive.Length - 1]))
{
sendMsg.Clear();
receiveMsg.Clear();
detection = false;
Debug.Log("校验数据一致");
}
else
{
Debug.Log("发送与接收的数据包不一致重新发送");
SendSerialPortData(_send);
yield return new WaitForSeconds(dt_time);
}
}
}
yield return new WaitForEndOfFrame();
}
}
IEnumerator DataReceiveFunction()
{
byte[] dataBytes = new byte[1024];//存储长度
byte[] bytes_read;
int bytesToRead = 0; //记录获取的数据长度
while (true)
{
if (sp != null && sp.IsOpen)
{
try
{
//通过read函数获取串口数据
bytesToRead = sp.Read(dataBytes, 0, dataBytes.Length);
//bytesToRead = sp.BytesToRead;
Debug.Log("数据长度"+ bytesToRead);
//Debug.Log(dataBytes);
//Debug.Log(bytesToRead);
//PortSignalControl();
//串口数据已经被存入dataBytes中
if (bytesToRead > 0)
{
//if (dataBytes[0] != headByte)
//{
bytes_read = new byte[bytesToRead];
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < bytesToRead; i++)
{
stringBuilder.Append(Convert.ToString(dataBytes[i])); //接收的16进制
//Debug.Log(Convert.ToString((int)dataBytes[i], 16) + "\n");
//print("byte:"+i.ToString()+dataBytes[i]);
bytes_read[i] = dataBytes[i];
print("接收到指令 :" + bytes_read[i].ToString("x2") + "\n");
}
if (receiveMsg.Count != 0)
receiveMsg.Dequeue();
receiveMsg.Enqueue(bytes_read);
UIInput.Instacne.DebugLogReceive("接收:" + DebugLogByte(bytes_read));
Debug.Log("接收到的消息" + DebugLogByte(bytes_read) + "接收到消息的长度:" + bytes_read.Length + " receive队列数量:" + receiveMsg.Count);
//Debug.Log();
//str_data = stringBuilder.ToString();
//print("串联" + str_data);
if (PathCurvy.Instance.isBackOff)
{
PathCurvy.Instance.BackOffModeMove();
}
//}
}
else
{
Debug.Log("返回数据长度为0");
}
}
catch (Exception ex)
{
}
}
yield return new WaitForEndOfFrame();
}
}
//发送一个字节
public void SendSerialPortData(string data)
{
if (sp.IsOpen)
{
sp.WriteLine(data);
}
}
//发送byte
public void SendSerialPortData(byte[] data, int length)
{
if (sp.IsOpen)
{
sp.Write(data, 0, length);
}
}
//发送byte
public void SendSerialPortData(byte[] data)
{
if (sp.IsOpen&&HttpLink.httpLink.GetActionState() == ActionState.讲解就绪)
{
sp.Write(data, 0, data.Length);
if (sendMsg.Count != 0)
sendMsg.Dequeue();
detection = true;
sendMsg.Enqueue(data);
Detection();
Debug.Log("发送指令:" + DebugLogByte(data) + "长度:" + data.Length + " sendMsg队列数量:" + sendMsg.Count);
UIInput.Instacne.DebugLogMsg("发送指令:" + DebugLogByte(data));
}
UIInput.Instacne.DebugLogMsg("发送指令:" + DebugLogByte(data));
}
private void OnApplicationQuit()
{
ClosePort();
}
private void OnDisable()
{
ClosePort();
}
public static string byteToHexStr(byte[] bytes)
{
string returnStr = "";
if (bytes != null)
{
for (int i = 0; i < bytes.Length; i++)
{
returnStr += bytes[i].ToString("X2");//ToString("X2") 为C#中的字符串格式控制符
}
}
return returnStr;
}
/// <summary>
/// 对比两个 byte 数组是否相同
/// </summary>
/// <param name="send"></param>
/// <param name="receive"></param>
/// <returns></returns>
public bool Compare(byte[] send, byte[] receive)
{
bool _bool = false;
if (send.Length != receive.Length) //两个数组长度不符合,return bool = false
return _bool = false;
_bool = (send[send.Length - 1] == receive[receive.Length - 1]); //长度符合用最后数据进行判断
Debug.Log("发送send:" + send[send.Length - 1].ToString("x2") + "接收receive:" + receive[receive.Length - 1].ToString("x2") + " 末尾有效数据判断:" + _bool);
return _bool;
}
/// <summary>
/// 对比单个byte是否相同
/// </summary>
/// <param name="send"></param>
/// <param name="receive"></param>
/// <returns></returns>
public bool CompareByte(byte send, byte receive)
{
bool _bool = false;
if (send == receive)
_bool = true;
else
_bool = false;
Debug.Log(_bool + send.ToString("x2")+":"+ receive.ToString("x2"));
return _bool;
}
/// <summary>
/// 打印指令
/// </summary>
/// <param name="m_byte"></param>
/// <returns></returns>
public string DebugLogByte(byte[] m_byte)
{
string _string = "";
for (int i = 0; i < m_byte.Length; i++)
{
_string += ":" + m_byte[i].ToString("x2");
}
return _string;
}
#endregion
#region 信号转16进制方法
public void SendMsg(string s)
{
string msg = s;
byte[] cmd = textWork16(s);
//SendSerialPortData(cmd);
}
/// <summary>
/// 开启数据接收
/// </summary>
public void ReceiveMsg()
{
Debug.Log("开启接收");
StartCoroutine(DataReceiveFunction());
}
private byte[] textWork16(string strText)
{
strText = strText.Replace(" ", "");
byte[] bText = new byte[strText.Length / 2];
for (int i = 0; i < strText.Length / 2; i++)
{
bText[i] = Convert.ToByte(Convert.ToInt32(strText.Substring(i * 2, 2), 16));
}
return bText;
}
#endregion
}
Unity 读取串口操作,打印判断信息数据
©著作权归作者所有,转载或内容合作请联系作者
- 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
- 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
- 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
推荐阅读更多精彩内容
- 数据驱动 数据驱动是软件设计与开发中不可忽视的内容,开发电子游戏更是如此。电子游戏世界是由逻辑与数据构建的。在开发...
- 这里关键的应该是while的使用, <和<<<读文件和读[变量?]的区别, 这块还不是很清楚.., 还有read命...
- 这一道试题,总体来看的话,可以说是非常的简单。 多余的话就不多说了,直接上代码: 下面我们来看一下具体运行的结果吧...