-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSerialPortManager.cs
171 lines (153 loc) · 6.01 KB
/
SerialPortManager.cs
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
160
161
162
163
164
165
166
167
168
169
170
171
using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Threading;
using System.Windows.Threading;
using System.Windows;
using System.Timers;
namespace DataViewer_1._0._0._0
{
public class SerialPortManager
{
//Neuen SerialPort anlegen
private SerialPort serialPort;
//String für das Abspeichern des Empfangspuffers
private string receivedData = "";
//Variable für Anzahl der zu erwartenden Datenpakete
private int expectedPacketCount=0;
//Timer für Timeout bei Datenempfang
private System.Timers.Timer dataReceiveTimer;
//Verlinkung zum DataReceived Event der Instanz des SerialPorts im Main Code mit Übergabe der complete Message
public event Action<string[]> DataReceived;
//Initialisiere SerialPort
public SerialPortManager(string portName)
{
serialPort = new SerialPort(portName, 38400, Parity.None, 8, StopBits.One);
serialPort.DataReceived += new SerialDataReceivedEventHandler(SerialPort_DataReceived);
//Timer für Timeout anlegen
dataReceiveTimer = new System.Timers.Timer(5000); // 5000 Millisekunden (5 Sekunden)
dataReceiveTimer.Elapsed += DataReceiveTimer_Elapsed;
}
//Get COM-Port Name
public string GetPortName()
{
return serialPort.PortName;
}
//SerialPort öffnen
public void OpenPort()
{
try
{
serialPort.Open();
}
catch
{
MessageBox.Show("An error has occurred: " + serialPort.PortName + " not found", "COM-Port Error", MessageBoxButton.OKCancel, MessageBoxImage.Error);
}
}
//Abfrage ob Port offen
public bool IsOpen()
{
return serialPort.IsOpen;
}
//COM-Port schließen
public void ClosePort()
{
if (serialPort.IsOpen)
{
serialPort.Close();
}
}
//Befehl senden
public void SendCommand(string command)
{
try
{
serialPort.Write(command);
StartDataReception();
}
catch
{
MessageBox.Show("An error has occurred: " + serialPort.PortName + " not open", "COM-Port Error", MessageBoxButton.OKCancel, MessageBoxImage.Error);
}
}
//Event wenn Daten vollständig empfangen wurden
private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
try
{
// Daten vom COM-Port lesen und an den empfangenen Datenstring anhängen
receivedData += serialPort.ReadExisting();
// Timeout Stoppen
StopDataReception();
// Timeout wieder starten für nächsten Datenblock
StartDataReception();
// Bestimmen des Echo-Befehls und Setzen der erwarteten Paketzahl
if (receivedData.Length > 0 && expectedPacketCount == 0)
{
char echoCommand = receivedData[0];
switch (echoCommand)
{
case 'I':
expectedPacketCount = 2;
break;
case 'S':
expectedPacketCount = 4;
break;
case 'G':
expectedPacketCount = 4;
break;
default:
// Umgang mit unbekanntem Echo-Befehl
break;
}
}
// Überprüfen, ob die Daten mit CR LF enden
if (receivedData.EndsWith("\r\n"))
{
var packets = receivedData.ToString().Split(new[] { "\r\n" }, StringSplitOptions.None);
foreach (var packet in packets)
{
Debug.WriteLine(packet);
}
if (packets.Length >= expectedPacketCount) // -1, weil das letzte Element leer sein könnte
{
// Stoppe Timeout Timer bei komplettem Datenempfang
StopDataReception();
// Zurücksetzen des empfangenen Datenstrings
receivedData = "";
// Zurücksetzen für den nächsten Empfang
expectedPacketCount = 0;
// Verlinke das komplette Datenpaket an das Data Received Event der jeweiligen Instanz des SerialPorts
DataReceived?.Invoke(packets);
}
}
}
catch (Exception ex)
{
MessageBox.Show("An error has occurred: " + serialPort.PortName + ": " + ex.Message, "COM-Port Error", MessageBoxButton.OKCancel, MessageBoxImage.Error);
}
}
// Starten Sie den Timer, wenn Sie auf Daten warten
private void StartDataReception()
{
dataReceiveTimer.Start(); //Info: Der Timer fängt immer wieder bei der usprünglich festgelegten Zeit an
}
// Stoppen Sie den Timer, wenn Daten empfangen wurden oder ein Timeout erreicht wurde
private void StopDataReception()
{
dataReceiveTimer.Stop();
}
// Event wenn Timeout Timer abgelaufen
private void DataReceiveTimer_Elapsed(object sender, ElapsedEventArgs e)
{
MessageBox.Show("Timeout: " + serialPort.PortName + " not responding.", "COM-Port Error", MessageBoxButton.OKCancel, MessageBoxImage.Error);
// Timeout Timer anhalten
StopDataReception();
}
}
}