212 lines
6.0 KiB
C#
212 lines
6.0 KiB
C#
|
|
// 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<byte> inputQueue = new ConcurrentQueue<byte>();
|
|||
|
|
|
|||
|
|
// 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;
|
|||
|
|
// }
|
|||
|
|
// }
|
|||
|
|
|
|||
|
|
// /// <summary>
|
|||
|
|
// /// 读取输入状态(X0-X7)
|
|||
|
|
// /// </summary>
|
|||
|
|
// 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); // 控制读取频率
|
|||
|
|
// }
|
|||
|
|
// }
|
|||
|
|
|
|||
|
|
// /// <summary>
|
|||
|
|
// /// 读取输出状态(Y0-Y7)
|
|||
|
|
// /// </summary>
|
|||
|
|
// 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];
|
|||
|
|
// }
|
|||
|
|
|
|||
|
|
// /// <summary>
|
|||
|
|
// /// 控制继电器输出(Y0-Y7),bit1=1表示通电
|
|||
|
|
// /// </summary>
|
|||
|
|
// 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);
|
|||
|
|
// }
|
|||
|
|
// }
|
|||
|
|
|
|||
|
|
// /// <summary>
|
|||
|
|
// /// 添加CRC16到末尾(Modbus标准校验)
|
|||
|
|
// /// </summary>
|
|||
|
|
// 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
|
|||
|
|
// }
|
|||
|
|
|
|||
|
|
// /// <summary>
|
|||
|
|
// /// CRC16计算(Modbus标准)
|
|||
|
|
// /// </summary>
|
|||
|
|
// 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;
|
|||
|
|
// }
|
|||
|
|
// }
|