Lesen und Schreiben von der seriellen Schnittstelle in C#

Aimen Fatima 15 Februar 2024
  1. Serielle Schnittstelle
  2. Chat-Anwendung für serielle Schnittstelle mit C#
Lesen und Schreiben von der seriellen Schnittstelle in C#

Dieses Tutorial hilft Ihnen, das Konzept der seriellen Schnittstelle in der Sprache C# und ihre Verwendung zum Lesen und Schreiben von Daten zu verstehen. Anhand eines Beispielprojekts demonstrieren wir die in C# implementierte Klasse SerialPort.

Serielle Schnittstelle

Unsere Computersysteme verfügen über mehrere Ports, um Daten für verschiedene Zwecke zu übertragen. Der serielle Port ist eine Schnittstelle zum sequenziellen Übertragen von Daten, indem Daten mit einem Bit gleichzeitig übertragen werden, anstatt mehrere Bits parallel zu teilen.

Serielle Schnittstelle in C#

C# stellt eine integrierte Klasse bereit, um die Funktionalität der seriellen Schnittstelle in Ihrem Programm zu implementieren. Sie können Daten empfangen und an das an die serielle Schnittstelle Ihres Systems angeschlossene Gerät senden.

Der Namespace, der die Klasse der seriellen Ports implementiert, ist System.IO.Ports.

Sie müssen den Namensraum System.IO.Ports in Ihr Programm importieren und ein Objekt der statischen Klasse SerialPort erstellen.

Die Klasse SerialPort stellt einen Standardkonstruktor bereit, und Konstruktoren sind überladen und erfordern andere Parameter. Im Folgenden sehen Sie ein Beispiel für die Initialisierung des Objekts mit default und einem der überladenen Konstruktoren.

Die zweite Zeile im folgenden Code verwendet den überladenen Konstruktor, um PortName, BaudRate, Parity, DataBits und StopBits zu initialisieren.

static SerialPort _serialPort = new SerialPort();
SerialPort _serialPort = new SerialPort("COM3", 9600, Parity.One, 8, StopBits.Two);

Die SerialPort-Klasse enthält Eigenschaften wie BaudRate, BytesToWrite, BytesToRead, DataBits, Encoding, PortName, Parity usw. Zahlreiche öffentliche Methoden wurden implementiert, um die vollständige Funktionalität für die Kommunikation bereitzustellen. B. Close(), GetPortNames(), Open(), Read(), Write() usw.

Eigenschaften wie ReadTimeOut und WriteTimeOut können auch wie folgt gesetzt werden:

_serialPort.ReadTimeout = 1000;
_serialPort.WriteTimeout = 1000;

Nachdem wir alle erforderlichen Parameterwerte eingestellt haben, müssen wir den Compiler benachrichtigen, den Port für die Kommunikation mit der Methode Open() zu öffnen.

_serialPort.Open();

Die Methode ReadLine() kann die über die serielle Schnittstelle empfangene Nachricht lesen.

string message = _serialPort.ReadLine();

Chat-Anwendung für serielle Schnittstelle mit C#

Dieser Abschnitt stellt ein vollständiges C#-Programm für eine Chatanwendung vor, die den seriellen Anschluss für die Kommunikation verwendet. Dieses Code-Snippet sollte auf beiden verbundenen Systemen ausgeführt werden, um Daten zu senden und zu empfangen.

Hinweis: Verwenden Sie zum Verbinden der Systeme ein null-Modemkabel.

Erstellen Sie ein C#-Projekt in Visual Studio, fügen Sie das Code-Snippet in die Datei Program.cs ein und führen Sie es aus.

using System;
using System.IO.Ports;
using System.Threading;

public class MyChatBot {
  static bool _resume;

  // Create a new SerialPort object
  static SerialPort _serialPortObj = new SerialPort();

  public static void Main() {
    string userName;
    string inputMessage;
    Thread read_Thread = new Thread(Read);
    StringComparer string_Comparer = StringComparer.OrdinalIgnoreCase;

    // Set the required attributes.
    _serialPortObj.PortName = SetPort(_serialPortObj.PortName);
    _serialPortObj.Parity = SetParity(_serialPortObj.Parity);

    _serialPortObj.StopBits = SetStopBits(_serialPortObj.StopBits);
    _serialPortObj.Handshake = SetHandshake(_serialPortObj.Handshake);

    // Set the read/write timeouts
    _serialPortObj.ReadTimeout = 1000;
    _serialPortObj.WriteTimeout = 1000;

    _serialPortObj.Open();
    _resume = true;
    read_Thread.Start();

    Console.Write("Enter Your Name: ");
    userName = Console.ReadLine();

    Console.WriteLine("Type Exit to exit");

    while (_resume) {
      inputMessage = Console.ReadLine();

      if (string_Comparer.Equals("exit", inputMessage)) {
        _resume = false;
      } else {
        _serialPortObj.WriteLine(String.Format("<{0}>: {1}", userName, inputMessage));
      }
    }

    read_Thread.Join();

    // Close the serial port
    _serialPortObj.Close();
  }

  public static void Read() {
    while (_resume) {
      try {
        // read the received message
        string _recerivedMessage = _serialPortObj.ReadLine();
        Console.WriteLine(_recerivedMessage);
      }

      catch (TimeoutException) {
      }
    }
  }

  // setters for attributes
  public static string SetPort(string defaultPortName) {
    string newPortName;

    Console.WriteLine("Available Ports:");
    foreach (string a in SerialPort.GetPortNames()) {
      Console.WriteLine("   {0}", a);
    }

    Console.Write("Enter COM port value (Default: {0}): ", defaultPortName);
    newPortName = Console.ReadLine();

    if (newPortName == "" || !(newPortName.ToLower()).StartsWith("com")) {
      newPortName = defaultPortName;
    }
    return newPortName;
  }

  public static Parity SetParity(Parity defaultParity) {
    string parityValue;

    Console.WriteLine("Available Parity Values:");
    foreach (string a in Enum.GetNames(typeof(Parity))) {
      Console.WriteLine("   {0}", a);
    }

    Console.Write("Enter Parity value (Default: {0}):", defaultParity.ToString(), true);
    parityValue = Console.ReadLine();

    if (parityValue == "") {
      parityValue = defaultParity.ToString();
    }

    return (Parity)Enum.Parse(typeof(Parity), parityValue, true);
  }

  public static StopBits SetStopBits(StopBits defaultStopBits) {
    string stopBitValue;

    Console.WriteLine("Available StopBits Values:");
    foreach (string a in Enum.GetNames(typeof(StopBits))) {
      Console.WriteLine("   {0}", a);
    }

    Console.Write(
        "Enter a StopBits value (ArgumentOutOfRangeException occurs for None value. Select another. \n (Default Value: {0}):",
        defaultStopBits.ToString());
    stopBitValue = Console.ReadLine();

    if (stopBitValue == "") {
      stopBitValue = defaultStopBits.ToString();
    }

    return (StopBits)Enum.Parse(typeof(StopBits), stopBitValue, true);
  }

  public static Handshake SetHandshake(Handshake defaultHandshake) {
    string handshakeValue;

    Console.WriteLine("Available Handshake Values:");
    foreach (string a in Enum.GetNames(typeof(Handshake))) {
      Console.WriteLine("   {0}", a);
    }

    Console.Write("Enter Handshake value (Default: {0}):", defaultHandshake.ToString());
    handshakeValue = Console.ReadLine();

    if (handshakeValue == "") {
      handshakeValue = defaultHandshake.ToString();
    }

    return (Handshake)Enum.Parse(typeof(Handshake), handshakeValue, true);
  }
}

Das obige Code-Snippet erstellt zuerst ein SerialPort-Objekt und implementiert die Setter, um optionale Attribute zu setzen. Die Standardwerte für BaudRate und DataBits sind üblich, müssen also nicht vom Benutzer eingestellt werden.

Die Funktion Read() liest die Eingabe von der seriellen Schnittstelle. Das Programm fordert den Benutzer auf, den eingegebenen Text einzugeben, und sendet ihn an die serielle Schnittstelle, bis der Benutzer als Eingabe exit eingibt.

SetPort(), SetParity(), SetStopBits() und SetHandshake() sind Setter zum Festlegen der Attributwerte.

Ausgang:

Der Benutzer wird aufgefordert, die erforderlichen Werte festzulegen, indem er die verfügbaren Optionen auswählt, z. B. haben wir in der folgenden Ausgabe Com3, Parität als Wert Ungerade, StopBits als Zwei ausgewählt, und Handshake-Wert muss None sein.

Nach dem Einstellen der Parameterwerte beginnt die Kommunikation über die serielle Schnittstelle, bis der Benutzer auf exit eintritt, um das Programm zu beenden.

Ausgabe für Chat-App