4,387
社区成员




我想做unity的串口通信,不知道哪里出了问题,在串口打开以后吗就报告串口无法访问
一下是代码和控制台
//using UnityEngine;
//using System.IO.Ports;
//using System.Threading;
//using System;
//using System.IO;
//public class SerialPortController : MonoBehaviour
//{
// [Header("Serial Settings")]
// public string portName = "COM6"; // 固定使用COM6
// public int baudRate = 9600; // 波特率9600
// public Parity parity = Parity.None;
// public int dataBits = 8;
// public StopBits stopBits = StopBits.One;
// [Header("Protocol Settings")]
// public byte frameHeader = 0xAA; // 帧头
// public byte frameFooter = 0x55; // 帧尾
// public float decimalFactor = 100f; // 小数位放大因子
// private SerialPort _serialPort;
// private Thread _readThread;
// private bool _isRunning;
// private Vector2 _receivedPosition;
// private bool _newDataAvailable;
// private readonly object _portLock = new object();
// private readonly object _serialLock = new object();
// void Start()
// {
// _isRunning = true;
// InitializeSerialPort();
// }
// void InitializeSerialPort()
// {
// lock (_portLock) // 添加锁
// try
// {
// _serialPort = new SerialPort(portName, baudRate, parity, dataBits, stopBits)
// {
// ReadTimeout = 100,
// WriteTimeout = 100,
// Handshake = Handshake.None,
// DtrEnable = true, // 某些设备需要
// RtsEnable = true // 某些设备需要
// };
// _serialPort.Open();
// Debug.Log($"串口已连接: {portName} @ {baudRate}bps");
// System.Threading.Thread.Sleep(10000); // 等待设备稳定
// _serialPort.DiscardInBuffer(); // 清空缓冲区
// StartReadingThread();
// }
// catch (Exception e)
// {
// Debug.LogError($"串口连接失败: {e.GetType()} - {e.Message}");
// // 将错误信息写入外部日志文件
// File.AppendAllText("ErrorLog.txt", $"[{DateTime.Now}] SerialPort Initialization Failed: {e.Message}\n");
// _serialPort = null; // 确保为null
// }
// }
// void StartReadingThread()
// {
// _readThread = new Thread(() =>
// {
// try
// {
// while (_isRunning)
// {
// try
// {
// if (_serialPort == null || !_serialPort.IsOpen)
// {
// InitializeSerialPort();
// Thread.Sleep(1000); // 重连间隔
// continue;
// }
// ReadSerialData();
// }
// catch (ThreadInterruptedException)
// {
// break; // 正常退出
// }
// catch (Exception e)
// {
// Debug.LogWarning($"读取线程异常: {e.Message}");
// Thread.Sleep(500);
// }
// }
// }
// finally
// {
// Debug.Log("读取线程已退出");
// }
// })
// { IsBackground = true };
// _readThread.Start();
// }
// void ReadSerialData()
// {
// while (_isRunning)
// {
// try
// {
// lock (_portLock)
// {
// if (_serialPort == null || !_serialPort.IsOpen)
// {
// Thread.Sleep(100);
// continue;
// }
// // 确保读取的数据不超过缓冲区大小
// int bytesToRead = Math.Min(_serialPort.BytesToRead, 1024); // 限制最大读取长度
// if (bytesToRead > 0)
// {
// byte[] received = new byte[bytesToRead];
// int bytesRead = _serialPort.Read(received, 0, bytesToRead); // 安全读取
// ProcessRawData(received);
// }
// }
// }
// catch (Exception e)
// {
// Debug.LogWarning($"串口读取错误: {e.Message}");
// Thread.Sleep(100); // 避免错误时高频重试
// }
// }
// }
// private byte[] _dataBuffer = new byte[1024];
// private int _bufferIndex = 0;
// void ProcessRawData(byte[] data)
// {
// // 先将新数据添加到缓冲区
// Array.Copy(data, 0, _dataBuffer, _bufferIndex, data.Length);
// _bufferIndex += data.Length;
// int i = 0;
// while (i < _bufferIndex)
// {
// // 查找帧头 (0xAA)
// if (_dataBuffer[i] == frameHeader && i + 7 < _bufferIndex) // 最小帧长度检查
// {
// byte dataLength = _dataBuffer[i + 1];
// // 验证帧结构: 帧头(1) + 长度(1) + 数据(4) + 校验(1) + 帧尾(1) = 8字节
// if (dataLength == 0x08 && i + 8 <= _bufferIndex)
// {
// // 检查帧尾 (0x55)
// if (_dataBuffer[i + 7] == frameFooter)
// {
// // 计算校验
// byte calculatedXor = CalculateXOR(_dataBuffer, i + 2, 4); // 校验X+Y数据(4字节)
// if (calculatedXor == _dataBuffer[i + 6])
// {
// ParseDisplacementData(_dataBuffer, i + 2);
// i += 8; // 跳过已处理的数据
// }
// else
// {
// Debug.LogWarning($"校验失败: 预期{_dataBuffer[i + 6]} 实际{calculatedXor}");
// i++;
// }
// }
// else
// {
// // 帧尾错误,可能是数据错误或者帧未完整接收,继续查找
// i++;
// }
// }
// else
// {
// // 帧长度不符合要求,可能是数据错误或者帧未完整接收,继续查找
// i++;
// }
// }
// else
// {
// // 没找到帧头,或者帧不符合要求,继续查找
// i++;
// }
// }
// // 将未处理的数据移动到缓冲区开头,用于后续处理
// if (_bufferIndex > 0)
// {
// Array.Copy(_dataBuffer, _bufferIndex - i, _dataBuffer, 0, _bufferIndex - i);
// _bufferIndex = _bufferIndex - i;
// }
// }
// void ParseDisplacementData(byte[] data, int startIndex)
// {
// // 解析带符号的16位整数 (小端序)
// short xDisplacement = (short)(data[startIndex] | (data[startIndex + 1] << 8));
// short yDisplacement = (short)(data[startIndex + 2] | (data[startIndex + 3] << 8));
// // 还原小数位 (除以100)
// float x = xDisplacement / decimalFactor;
// float y = yDisplacement / decimalFactor;
// Debug.Log($"原始位移: X={xDisplacement}, Y={yDisplacement} | 处理后: X={x:F2}, Y={y:F2}");
// _receivedPosition = new Vector2(x, y);
// _newDataAvailable = true;
// }
// byte CalculateXOR(byte[] data, int start, int length)
// {
// byte xor = 0;
// for (int i = 0; i < length; i++)
// {
// xor ^= data[start + i];
// }
// return xor;
// }
// void Update()
// {
// if (_newDataAvailable)
// {
// ApplyPositionToPlayer();
// _newDataAvailable = false;
// }
// }
// void ApplyPositionToPlayer()
// {
// GameObject player = GameObject.FindGameObjectWithTag("Player");
// if (player != null)
// {
// // 保持Y轴高度不变,更新XZ平面位置
// player.transform.position = new Vector3(
// _receivedPosition.x,
// player.transform.position.y,
// _receivedPosition.y
// );
// }
// }
// void OnDestroy()
// {
// _isRunning = false;
// // 优先中断读取线程
// if (_readThread != null && _readThread.IsAlive)
// {
// try { _readThread.Interrupt(); } catch { }
// _readThread.Join(500);
// }
// lock (_portLock)
// {
// if (_serialPort != null)
// {
// try
// {
// if (_serialPort.IsOpen)
// {
// _serialPort.DiscardInBuffer();
// _serialPort.Close();
// }
// _serialPort.Dispose();
// }
// catch (Exception e)
// {
// Debug.LogWarning($"串口关闭异常: {e.Message}");
// }
// _serialPort = null;
// }
// }
// }
// void OnGUI()
// {
// GUILayout.Label($"当前端口: {portName}");
// GUILayout.Label($"最新坐标: X={_receivedPosition.x:F2}, Y={_receivedPosition.y:F2}");
// }
// private void OnApplicationQuit()
// {
// _isRunning = false;
// // 等待读取线程结束
// if (_readThread != null && _readThread.IsAlive)
// {
// _readThread.Join(500); // 最多等待500ms
// }
// // 安全关闭串口
// if (_serialPort != null)
// {
// try
// {
// if (_serialPort.IsOpen)
// {
// _serialPort.DiscardInBuffer();
// _serialPort.Close();
// }
// _serialPort.Dispose();
// }
// catch { /* 忽略关闭时的异常 */ }
// }
// Debug.Log("串口资源已完全释放");
// }
//}
位移数据可以读取,然后马上就报告串口连接失败求大佬帮忙