using System;
|
using System.Collections.Generic;
|
using System.Linq;
|
using System.Text;
|
using System.Threading.Tasks;
|
using RJCP.IO.Ports;
|
|
namespace WIDESEA_SerialPortService
|
{
|
public class SerialPortTestService
|
{
|
|
private readonly SerialPortStream _serialPortStream;
|
private CancellationTokenSource _cancellationTokenSource;
|
private Task _sendTask;
|
private int commandType = 2;
|
|
//// 事件 - 用于通知数据接收到
|
//public event Action<string> DataReceivedEvent;
|
|
// 命令字符串
|
private string command0 = ""; // 不发送命令
|
private string command1 = "824070241JNT\r"; //发送信号
|
private string command2 = "824070241JNT,0004000,+0001000[+TOL],-0001000[-TOL]\r"; //设值
|
|
// 用于存储接收到的数据
|
private List<string> receivedDataList = new List<string>();
|
|
// 构造函数
|
public SerialPortTestService(string port)
|
{
|
_serialPortStream = new SerialPortStream(port)
|
{
|
BaudRate = 9600,
|
Parity = Parity.None,
|
DataBits = 8,
|
StopBits = StopBits.One,
|
DtrEnable = true,
|
RtsEnable = true
|
};
|
//串口接收到数据时,_serialPortStream 会自动触发 DataReceived 事件
|
_serialPortStream.DataReceived += OnDataReceived; //接收串口发出的数据
|
}
|
|
// 打开串口并开始持续发送信号
|
public void OpenSerialPort()
|
{
|
if (!_serialPortStream.IsOpen)
|
{
|
_serialPortStream.Open();
|
StartSendingData();//开启后台循环
|
}
|
}
|
|
// 关闭串口并停止发送信号
|
public void CloseSerialPort()
|
{
|
if (_serialPortStream.IsOpen)
|
{
|
_serialPortStream.Close();
|
}
|
}
|
|
// 发送数据一次
|
public void SendData(string data)
|
{
|
if (_serialPortStream.IsOpen)
|
{
|
byte[] bytesToSend = Encoding.ASCII.GetBytes(data);
|
_serialPortStream.Write(bytesToSend, 0, bytesToSend.Length);//将数据发送到串口
|
}
|
}
|
|
// 获取串口状态
|
public bool GetSerialPortStatus()
|
{
|
return _serialPortStream.IsOpen;
|
}
|
|
// 获取接收到的所有数据
|
public List<string> GetReceivedData()
|
{
|
return receivedDataList;
|
}
|
|
// 处理接收到的数据
|
//每当串口收到数据时,会触发此方法
|
private void OnDataReceived(object sender, SerialDataReceivedEventArgs e)
|
{
|
//从串口接收数据,并将接收到的数据转换为字符串
|
byte[] buffer = new byte[1024];//一个字节数组 buffer,大小为 1024 字节
|
int bytesRead = _serialPortStream.Read(buffer, 0, buffer.Length);//从串口流 _serialPortStream 中读取数据并将其存入 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(23, 7); // 从第23位开始提取7个字符,得到 "0008000"
|
//if (deviceCodePostfix == "03")
|
//{
|
|
// receivedDataList.Add(receivedData);
|
// // 触发接收到数据事件
|
////DataReceivedEvent?.Invoke(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 (_serialPortStream.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是要发送的字节数,这里表示整个字节数组的长度)
|
_serialPortStream.Write(dataToSend, 0, dataToSend.Length);//最后向串口发送数据
|
|
}
|
|
Thread.Sleep(1000); // 每隔1秒发送一次命令
|
}
|
});
|
}
|
}
|
}
|