yanjinhui
2025-02-26 f3c2bc390da81d90b444ed48061cdf8b285e0567
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
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秒发送一次命令
                }
            });
        }
    }
}