// using System; // using System.Collections.Concurrent; // using System.IO.Ports; // using System.Threading; // using UnityEngine; // public class ModbusRTUController : MonoBehaviour // { // public static ModbusRTUController Instance { get; private set; } // public string portName = "COM1"; // public int baudRate = 115200; // private SerialPort serialPort; // private Thread readThread; // private bool keepReading = false; // // 用于线程间传递数据 // private ConcurrentQueue inputQueue = new ConcurrentQueue(); // void Start() // { // Instance = this; // serialPort = new SerialPort(portName, baudRate, Parity.None, 8, StopBits.One); // serialPort.ReadTimeout = 1000; // serialPort.WriteTimeout = 1000; // try // { // serialPort.Open(); // Debug.Log("串口已打开"); // keepReading = true; // readThread = new Thread(ReadInputLoop); // readThread.Start(); // } // catch (Exception e) // { // Debug.LogError("打开串口失败: " + e.Message); // } // // 示例:控制输出Y0打开 // // ControlRelay(0b00000001); // } // void Update() // { // // 周期性读取输入状态 // // if (Time.frameCount % 60 == 0) // // { // // byte inputState = ReadInputStatus(); // // Debug.Log("输入状态: " + Convert.ToString(inputState, 2).PadLeft(8, '0')); // // } // if (inputQueue.TryDequeue(out byte inputStatus)) // { // Debug.Log("输入状态: " + Convert.ToString(inputStatus, 2).PadLeft(8, '0')); // } // } // void OnDisable() // { // keepReading = false; // if (readThread != null && readThread.IsAlive) // { // readThread.Join(); // readThread = null; // } // if (serialPort != null && serialPort.IsOpen) // { // serialPort.Close(); // serialPort = null; // } // } // void OnApplicationQuit() // { // keepReading = false; // if (readThread != null && readThread.IsAlive) // { // readThread.Join(); // readThread = null; // } // if (serialPort != null && serialPort.IsOpen) // { // serialPort.Close(); // serialPort = null; // } // } // /// // /// 读取输入状态(X0-X7) // /// // public byte ReadInputStatus() // { // byte[] request = new byte[] { 0x1F, 0x02, 0x00, 0x00, 0x00, 0x08 }; // AddCRC(ref request); // serialPort.Write(request, 0, request.Length); // byte[] buffer = new byte[5]; // serialPort.Read(buffer, 0, buffer.Length); // // buffer = [0x1F, 0x02, 0x01, XX, CRC16_L, CRC16_H] // return buffer[3]; // } // // 串口读取线程 // private void ReadInputLoop() // { // while (keepReading) // { // try // { // // 构造读取输入状态请求帧 // byte[] request = new byte[] { 0x1F, 0x02, 0x00, 0x00, 0x00, 0x08 }; // AddCRC(ref request); // serialPort.Write(request, 0, request.Length); // Thread.Sleep(50); // 等待设备响应 // byte[] buffer = new byte[5]; // int bytesRead = serialPort.Read(buffer, 0, buffer.Length); // if (bytesRead >= 5) // { // inputQueue.Enqueue(buffer[3]); // 将XX添加到线程安全队列 // } // } // catch (TimeoutException) { } // catch (ThreadAbortException e) { // Debug.LogWarning("线程被强制终止: " + e.Message); // } // catch (Exception e) // { // Debug.LogError("读取线程异常: " + e.Message); // } // Thread.Sleep(200); // 控制读取频率 // } // } // /// // /// 读取输出状态(Y0-Y7) // /// // public byte ReadOutputStatus() // { // byte[] request = new byte[] { 0x1F, 0x01, 0x00, 0x00, 0x00, 0x08 }; // AddCRC(ref request); // serialPort.Write(request, 0, request.Length); // byte[] buffer = new byte[5]; // serialPort.Read(buffer, 0, buffer.Length); // return buffer[3]; // } // /// // /// 控制继电器输出(Y0-Y7),bit1=1表示通电 // /// // public void ControlRelay(byte state) // { // byte[] request = new byte[] { 0x1F, 0x0F, 0x00, 0x00, 0x00, 0x08, 0x01, state }; // AddCRC(ref request); // try // { // serialPort.Write(request, 0, request.Length); // } // catch (Exception e) // { // Debug.LogError("发送失败: " + e.Message); // } // } // /// // /// 添加CRC16到末尾(Modbus标准校验) // /// // private void AddCRC(ref byte[] data) // { // ushort crc = CalculateCRC(data, data.Length); // Array.Resize(ref data, data.Length + 2); // data[data.Length - 2] = (byte)(crc & 0xFF); // CRC Low // data[data.Length - 1] = (byte)((crc >> 8) & 0xFF); // CRC High // } // /// // /// CRC16计算(Modbus标准) // /// // private ushort CalculateCRC(byte[] data, int length) // { // ushort crc = 0xFFFF; // for (int pos = 0; pos < length; pos++) // { // crc ^= data[pos]; // for (int i = 0; i < 8; i++) // { // bool lsb = (crc & 0x0001) != 0; // crc >>= 1; // if (lsb) // crc ^= 0xA001; // } // } // return crc; // } // }