using System.IO.Ports; using System.Text; using WIDESEA_ISerialPortService; using WIDESEAWCS_Model.Models.SerialPort; namespace WIDESEA_SerialPortTestService { public class SerialPortTestService { // 在 SerialPortTestService 类中添加对 ISerialPortService 的引用 private readonly ISerialPortService _serialPortService; // 构造函数 public SerialPortTestService(string port, ISerialPortService _serialPortService) { SerialPort = new SerialPort(port); //串口接收到数据时,SerialPort 会自动触发 DataReceived 事件 SerialPort.DataReceived += OnDataReceived; //接收串口发出的数据 } private CancellationTokenSource _cancellationTokenSource; private Task _sendTask; private int commandType = 2; public SerialPort SerialPort { get; set; } = null!; //表示要打开的串口,可为空 //// 事件 - 用于通知数据接收到 //public event Action DataReceivedEvent; // 命令字符串 private string command0 = ""; // 不发送命令 private string command1 = "824070241JNT\r"; //发送信号 private string command2 = "824070241JNT,0004000,+0001000[+TOL],-0001000[-TOL]\r"; //设值 // 用于存储接收到的数据 private List receivedDataList = new List(); // 打开串口并开始持续发送信号 public void OpenSerialPort() { if (!SerialPort.IsOpen) { SerialPort.Open(); StartSendingData();//开启后台循环 } } // 关闭串口并停止发送信号 public void CloseSerialPort() { if (SerialPort.IsOpen) { SerialPort.Close(); } } // 发送数据一次 public void SendData(string data) { if (SerialPort.IsOpen) { byte[] bytesToSend = Encoding.ASCII.GetBytes(data); SerialPort.Write(bytesToSend, 0, bytesToSend.Length);//将数据发送到串口 } } // 获取串口状态 public bool GetSerialPortStatus() { return SerialPort.IsOpen; } // 获取接收到的所有数据 public List GetReceivedData() { return receivedDataList; } // 处理接收到的数据 //每当串口收到数据时,会触发此方法 private void OnDataReceived(object sender, SerialDataReceivedEventArgs e) { //从串口接收数据,并将接收到的数据转换为字符串 byte[] buffer = new byte[1024];//一个字节数组 buffer,大小为 1024 字节 int bytesRead = SerialPort.Read(buffer, 0, buffer.Length);//从串口流 SerialPort 中读取数据并将其存入 buffer 数组中。 string receivedData = Encoding.ASCII.GetString(buffer, 0, bytesRead);//将接收到的字节数据转换成一个字符串 //这里写一个方法用于判断每次receivedDat是否满足条件 //截取设备编号后的俩为是否为03,03成功就进行下步 string deviceCodePostfix = receivedData.Substring(9, 2); // 索引从 9 开始,长度为 2,即提取 "04" // 提取从第24位后的数据(例如 "0008000") string dataAfter24th = receivedData.Substring(13, 7); // 从第23位开始提取7个字符,得到 "0008000" if (deviceCodePostfix == "03") { //插入数据 Dt_TorqueOp torqueOp = new Dt_TorqueOp { TorqueSize = dataAfter24th }; _serialPortService.AddSerialPort(torqueOp); //receivedDataList.Add(receivedData); } receivedDataList.Add(receivedData); // 处理命令切换逻辑 if (commandType == 2 && receivedData.Contains("ParseOK")) { commandType = 1; } else if (commandType == 1 && (receivedData.Contains("82407024103") || receivedData.Contains("82407024104"))) { commandType = 2; } } // 启动后台任务,每隔一段时间发送信号 private void StartSendingData() { _cancellationTokenSource = new CancellationTokenSource(); _sendTask = Task.Run(() => { while (SerialPort.IsOpen) { string command = command0; //先判断commandType if (commandType == 1) { command = command1; } else if (commandType == 2) { command = command2; } //再检查 command 字符串是否为空或 null if (!string.IsNullOrEmpty(command)) { byte[] dataToSend = Encoding.ASCII.GetBytes(command);//将command转成字节数组 //(三个参数的含义,1数组,2从第0位开始截取,3是要发送的字节数,这里表示整个字节数组的长度) SerialPort.Write(dataToSend, 0, dataToSend.Length);//最后向串口发送数据 } Thread.Sleep(1000); // 每隔1秒发送一次命令 } }); } } }