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
using System.Data;
using System.Text;
using RJCP.IO.Ports;
 
 
namespace WIDESEAWCS_SerialPortServices
{
    public class SerialPortService
    {
        private readonly SerialPortStream _serialPortStream;
        private CancellationTokenSource _cancellationTokenSource;
        private Task _sendTask;
        private int commandType = 2;
 
        // 命令字符串
        private string command0 = "";  // 不发送命令
        private string command1 = "824070241JNT\r"; //发送信号
        private string command2 = "824070241JNT,0005000,+0001000[+TOL],-0001000[-TOL]\r"; //设值
 
        // 用于存储接收到的数据
        private List<string> receivedDataList = new List<string>();
 
        // 构造函数
        public SerialPortService(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成功就进行下步
 
            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秒发送一次命令
                }
            });
        }
    }
}