.NET Framework
Serielle Ports
Suche…
Grundbetrieb
var serialPort = new SerialPort("COM1", 9600, Parity.Even, 8, StopBits.One);
serialPort.Open();
serialPort.WriteLine("Test data");
string response = serialPort.ReadLine();
Console.WriteLine(response);
serialPort.Close();
Listet die verfügbaren Portnamen auf
string[] portNames = SerialPort.GetPortNames();
Asynchrones Lesen
void SetupAsyncRead(SerialPort serialPort)
{
serialPort.DataReceived += (sender, e) => {
byte[] buffer = new byte[4096];
switch (e.EventType)
{
case SerialData.Chars:
var port = (SerialPort)sender;
int bytesToRead = port.BytesToRead;
if (bytesToRead > buffer.Length)
Array.Resize(ref buffer, bytesToRead);
int bytesRead = port.Read(buffer, 0, bytesToRead);
// Process the read buffer here
// ...
break;
case SerialData.Eof:
// Terminate the service here
// ...
break;
}
};
Synchrone Echo-Service
using System.IO.Ports;
namespace TextEchoService
{
class Program
{
static void Main(string[] args)
{
var serialPort = new SerialPort("COM1", 9600, Parity.Even, 8, StopBits.One);
serialPort.Open();
string message = "";
while (message != "quit")
{
message = serialPort.ReadLine();
serialPort.WriteLine(message);
}
serialPort.Close();
}
}
}
Asynchroner Nachrichtenempfänger
using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Text;
using System.Threading;
namespace AsyncReceiver
{
class Program
{
const byte STX = 0x02;
const byte ETX = 0x03;
const byte ACK = 0x06;
const byte NAK = 0x15;
static ManualResetEvent terminateService = new ManualResetEvent(false);
static readonly object eventLock = new object();
static List<byte> unprocessedBuffer = null;
static void Main(string[] args)
{
try
{
var serialPort = new SerialPort("COM11", 9600, Parity.Even, 8, StopBits.One);
serialPort.DataReceived += DataReceivedHandler;
serialPort.ErrorReceived += ErrorReceivedHandler;
serialPort.Open();
terminateService.WaitOne();
serialPort.Close();
}
catch (Exception e)
{
Console.WriteLine("Exception occurred: {0}", e.Message);
}
Console.ReadKey();
}
static void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
lock (eventLock)
{
byte[] buffer = new byte[4096];
switch (e.EventType)
{
case SerialData.Chars:
var port = (SerialPort)sender;
int bytesToRead = port.BytesToRead;
if (bytesToRead > buffer.Length)
Array.Resize(ref buffer, bytesToRead);
int bytesRead = port.Read(buffer, 0, bytesToRead);
ProcessBuffer(buffer, bytesRead);
break;
case SerialData.Eof:
terminateService.Set();
break;
}
}
}
static void ErrorReceivedHandler(object sender, SerialErrorReceivedEventArgs e)
{
lock (eventLock)
if (e.EventType == SerialError.TXFull)
{
Console.WriteLine("Error: TXFull. Can't handle this!");
terminateService.Set();
}
else
{
Console.WriteLine("Error: {0}. Resetting everything", e.EventType);
var port = (SerialPort)sender;
port.DiscardInBuffer();
port.DiscardOutBuffer();
unprocessedBuffer = null;
port.Write(new byte[] { NAK }, 0, 1);
}
}
static void ProcessBuffer(byte[] buffer, int length)
{
List<byte> message = unprocessedBuffer;
for (int i = 0; i < length; i++)
if (buffer[i] == ETX)
{
if (message != null)
{
Console.WriteLine("MessageReceived: {0}",
Encoding.ASCII.GetString(message.ToArray()));
message = null;
}
}
else if (buffer[i] == STX)
message = null;
else if (message != null)
message.Add(buffer[i]);
unprocessedBuffer = message;
}
}
}
Dieses Programm wartet auf Nachrichten, die in STX
und ETX
Bytes eingeschlossen sind, und gibt den dazwischen befindlichen Text aus. Alles andere wird weggeworfen. Bei Schreibpufferüberlauf wird es angehalten. Bei anderen Fehlern werden die Eingangs- und Ausgangspuffer zurückgesetzt und auf weitere Meldungen gewartet.
Der Code veranschaulicht:
- Asynchrones Lesen der seriellen Schnittstelle (siehe Verwendung von
SerialPort.DataReceived
). - Fehlerbehandlung beim seriellen Port (siehe Verwendung von
SerialPort.ErrorReceived
). - Nicht-textnachrichtenbasierte Protokollimplementierung
- Teilweises Lesen der Nachricht.
- Das
SerialPort.DataReceived
Ereignis kann früher auftreten, als die gesamte Nachricht (bis zuETX
) kommt. Möglicherweise ist auch nicht die gesamte Nachricht im Eingabepuffer verfügbar (SerialPort.Read (..., ..., port.BytesToRead) liest nur einen Teil der Nachricht. In diesem Fall speichern wir den empfangenen Teil (unprocessedBuffer
) und warten weiter auf weitere Daten.
- Das
- Umgang mit mehreren Nachrichten auf einmal.
- Das
SerialPort.DataReceived
Ereignis kann nur auftreten, nachdem vom anderen Ende mehrere Nachrichten gesendet wurden.
- Das
Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow