如何在云主机上建设网站centos wordpress 权限
一、本文介绍在windows环境下unity与usb串口进行通信的代码
web版本的放在下一个文章
注:
1.我的硬件是检测磁阻液位,用到四字节十六进制浮点数,所以这里会直接转换到十进制。
2.我的硬件会返回9字节响应,所以我会限制响应长度,可以进行适当更改
重要:再开始前一定要改为.NET 4.x,或者.NET Framework,因为.NET standard 2.0或者2.1不包括需要用到的using System.IO.Ports;更换路径为File/Build Setting/Player Settings.../Other Settings/Api Compatibility Level
二、脚本
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO.Ports;
using System.Text;
using System.Threading;
using UnityEngine;public class SerialPortCommunicationManager : MonoBehaviour
{private static SerialPortCommunicationManager _instance;public static SerialPortCommunicationManager Instance{get{if (_instance == null){GameObject obj = new GameObject("SerialPortCommunicationManager");_instance = obj.AddComponent<SerialPortCommunicationManager>();DontDestroyOnLoad(obj);}return _instance;}}public string portName;// 串口号public int baudRate;// 波特率public int dataBit;//数据位public Parity parity;//校验位public StopBits stopBit;//停止位private SerialPort sp = new SerialPort();private List<byte> receiveBuffer = new List<byte>(); // 用于存储接收到的字节private const int RESPONSE_LENGTH = 9; // 每组响应的长度(9 个字节)/// <summary>/// 打开端口/// </summary>public void OpenPort(){sp = new SerialPort(portName, baudRate, parity, dataBit, stopBit);sp.ReadTimeout = 20;try{sp.Open();Debug.Log("端口已打开");}catch (Exception e){Debug.LogError("端口未打开: " + e.Message);}}/// <summary>/// 关闭端口/// </summary>public void ClosePort(){try{sp.Close();sp.Dispose();Debug.Log("端口已关闭");}catch (Exception e){Debug.LogError("端口无法关闭: " + e.Message);}}/// <summary>/// 检查串口是否打开/// </summary>public bool IsPortOpen(){return sp != null && sp.IsOpen;}/// <summary>/// 发送数据/// </summary>public void SendData(byte[] dataStr){if (sp != null && sp.IsOpen){sp.Write(dataStr, 0, dataStr.Length);Debug.LogWarning("发送成功: " + BitConverter.ToString(dataStr).Replace("-", " "));}else{Debug.LogError("串口未打开,无法发送数据!");}}/// <summary>/// 接收端口数据/// </summary>public void DataReceiveFun(){while (true){if (sp != null && sp.IsOpen){try{int bytesToRead = sp.BytesToRead;if (bytesToRead > 0){byte[] buffer = new byte[bytesToRead];int bytesRead = sp.Read(buffer, 0, bytesToRead);if (bytesRead > 0){// 将读取到的数据添加到缓冲区receiveBuffer.AddRange(buffer);// 按 9 个字节为单位处理数据while (receiveBuffer.Count >= RESPONSE_LENGTH){byte[] response = receiveBuffer.GetRange(0, RESPONSE_LENGTH).ToArray();receiveBuffer.RemoveRange(0, RESPONSE_LENGTH); // 移除已处理的数据// 打印原始响应数据string responseHex = BitConverter.ToString(response).Replace("-", " ");Debug.Log($"收到响应: {responseHex}");// 解析浮点数数据if (response.Length == RESPONSE_LENGTH && response[0] == 0x01 && response[1] == 0x04){// 假设从第 3 字节起 4 个字节是 IEEE 754 单精度浮点数byte[] floatBytes = new byte[4];Array.Copy(response, 3, floatBytes, 0, 4); // 提取第 3 到第 6 字节// 将字节转换为浮点数float floatValue = ConvertHexToFloat(floatBytes);Debug.Log($"解析得到的浮点数: {floatValue}");}else{Debug.LogWarning("响应格式错误!");}}}}}catch (Exception e){Debug.LogError($"接收数据异常: {e.GetType()} - {e.Message}");}}Thread.Sleep(10); // 降低 CPU 占用,10 毫秒足够快}}/// <summary>/// 将 4 个字节转换为 IEEE 754 单精度浮点数/// </summary>private float ConvertHexToFloat(byte[] bytes){// 确保字节顺序正确(大端或小端取决于你的设备,这里假设是大端)if (BitConverter.IsLittleEndian){Array.Reverse(bytes); // 如果是小端机器,翻转字节顺序}// 直接使用 BitConverter 将字节转换为浮点数float result = BitConverter.ToSingle(bytes, 0);return result;}// 字符串转字节流 推荐public byte[] Convert16(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;}
}
三、使用
using System.Collections;
using System.Collections.Generic;
using System.IO.Ports;
using System.Threading;
using UnityEngine;public class UseSerialPort : MonoBehaviour
{private bool isRunning = true; // 控制发送循环的标志void Start(){SerialPortCommunicationManager.Instance.portName="COM3"; // 串口号SerialPortCommunicationManager.Instance.baudRate=9600; // 波特率SerialPortCommunicationManager.Instance.dataBit=8; // 数据位SerialPortCommunicationManager.Instance.parity=Parity.None; // 校验位SerialPortCommunicationManager.Instance.stopBit=StopBits.One; // 停止位SerialPortCommunicationManager.Instance.OpenPort(); // 打开串口// 启动接收线程new Thread(() =>{SerialPortCommunicationManager control = new SerialPortCommunicationManager();control.DataReceiveFun(); // 持续监听数据}).Start();// 启动发送协程,持续发送命令StartCoroutine(SendCommandRoutine());}/// <summary>/// 持续发送命令/// </summary>/// <returns></returns>IEnumerator SendCommandRoutine(){// 这里是我要发送的命令,并且会接收到9字节响应,所以会限制响应长度string commandHex = "01 04 00 02 00 02 D0 0B"; // 与日志中的命令一致byte[] commandBytes = SerialPortCommunicationManager.Instance.Convert16(commandHex.Replace(" ", ""));while (isRunning){SerialPortCommunicationManager.Instance.SendData(commandBytes);// 等待时间yield return new WaitForSeconds(0.1f); }}
}