using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Data.SqlTypes; using System.IO.Ports; using System.Text; using System.Threading; //using UnityEditor.PackageManager.UI; using UnityEngine; using UnityThreadingUtils; using ZXKFramework; public class SensorManager : MonoBehaviour /*MonoSingleton*/ { public enum DataType { 字符串, 字节流, } #region 串口参数,主要修改串口名与波特率 [Header("串口名")] public string portName = "COM10"; [Header("波特率")] public int baudRate = 115200; [Header("奇偶校验")] private Parity parity = Parity.None; [Header("数据位")] private int dataBits = 8; [Header("停止位")] private StopBits stopBits = StopBits.One; SerialPort sp = null; Thread dataReceiveThread; [Header("接收数据格式")] public DataType dataType; #endregion private Dictionary allSensor = new Dictionary(); StringBuilder sb = new StringBuilder(); private void Start() { sp = new SerialPort(portName, baudRate, parity, dataBits, stopBits); foreach (Sensor s in GetComponentsInChildren()) { allSensor.TryAdd(s.GetType().Name, s); } switch (dataType) { case DataType.字节流: dataReceiveThread = new Thread(new ThreadStart(DataReceiveBytesThread)); break; case DataType.字符串: dataReceiveThread = new Thread(new ThreadStart(DataReceiveStrThread)); break; } OpenPort(); } /// /// 接收字节流 /// private void DataReceiveBytesThread() { while (true) { if (sp != null && sp.IsOpen) { try { if (sp.BytesToRead > 0) { byte[] buffer = new byte[sp.BytesToRead]; sp.Read(buffer, 0, sp.BytesToRead); string receivedData = Encoding.Default.GetString(buffer); //Debug.Log(receivedData); UnityMainThreadDispatcher.Instance().Enqueue(() => { foreach (var s in allSensor) { s.Value.ReceiveData(receivedData); } }); } } catch (Exception) { Debug.Log("消息接收失败"); } } Thread.Sleep(20); } } /// /// 接收字符串 /// private void DataReceiveStrThread() { while (true) { if (sp != null && sp.IsOpen) { try { if (sp.BytesToRead > 0) { sb.Append(sp.ReadExisting()); //this.ColorLog(GDLog.LogColorState.Blue, sp.ReadLine()); UnityMainThreadDispatcher.Instance().Enqueue(() => { foreach (var s in allSensor) { s.Value.ReceiveData(sb.ToString()); } sb.Clear(); }); } } catch (Exception) { Debug.Log("消息接收失败"); } } Thread.Sleep(20); } } /// /// 发送消息 /// /// public void SendFunction(string str) { try { byte[] dataSend = Encoding.ASCII.GetBytes(str); if (sp != null && sp.IsOpen) { if (dataSend != null && dataSend.Length > 0) { sp.Write(dataSend, 0, dataSend.Length); Debug.Log("发送消息成功:" + str); } } } catch (Exception) { Debug.Log("发送消息失败:" + str); } } //获取指定传感器 public T GetSensor() where T : Sensor { try { string name = typeof(T).Name; if (!allSensor.ContainsKey(name)) { allSensor.TryAdd(name, GetComponentInChildren()); allSensor[name].Init(this); } //Debug.Log("传感器获取成功"); return allSensor[name] as T; } catch (Exception) { Debug.Log("传感器获取失败"); return null; } } #region 串口开启关闭相关 //打开串口 public void OpenPort() { try { if (!sp.IsOpen) { sp.Open(); dataReceiveThread.Start(); Debug.Log("串口打开成功"); } } catch (Exception) { Debug.Log("串口打开失败"); } } //关闭串口 public void ClosePort() { try { sp.Close(); dataReceiveThread.Abort(); Debug.Log("串口关闭"); } catch (Exception) { Debug.Log("串口关闭失败"); } } #endregion #region Unity 退出相关 private void OnApplicationQuit() { ClosePort(); } private void OnDisable() { this.Log("为什么关闭了:" + gameObject.name); ClosePort(); } #endregion }