C# でのシリアル ポートからの読み取りと書き込み

Aimen Fatima 2023年10月12日
  1. シリアルポート
  2. C# を使用したシリアル ポート チャット アプリケーション
C# でのシリアル ポートからの読み取りと書き込み

このチュートリアルは、C# 言語でのシリアル ポートの概念と、データの読み取りと書き込みでのその使用法を理解するのに役立ちます。 サンプル プロジェクトを通じて、C# で実装された SerialPort クラスのデモを行います。

シリアルポート

当社のコンピュータ システムには、さまざまな目的でデータを転送するためのポートがいくつかあります。 シリアルポートは、複数のビットを並列に共有するのではなく、一度に 1 ビットのデータを転送することによって、データを順次転送するインターフェイスです。

C# のシリアルポート

C# には、プログラムにシリアル ポート機能を実装するための組み込みクラスが用意されています。 システムのシリアル ポートに接続されたデバイスとの間でデータを送受信できます。

シリアル ポート クラスを実装する名前空間は、System.IO.Ports です。

プログラムに System.IO.Ports 名前空間をインポートし、静的クラス SerialPort のオブジェクトを作成する必要があります。

SerialPort クラスはデフォルトのコンストラクターを提供し、コンストラクターはオーバーロードされ、異なるパラメーターを必要とします。 以下は、デフォルトとオーバーロードされたコンストラクターの 1つを使用してオブジェクトを初期化する例です。

次のコードの 2 行目は、オーバーロードされたコンストラクターを使用して、PortNameBaudRateParityDataBits、および StopBits を初期化します。

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

SerialPort クラスには、BaudRateBytesToWriteBytesToReadDataBitsEncodingPortNameParity などのプロパティが含まれています。通信のための完全な機能を提供するために、多数のパブリック メソッドが実装されています。 例: Close()GetPortNames()Open()Read()Write()など。

次のように、ReadTimeOutWriteTimeOut などのプロパティも設定できます。

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

必要なすべてのパラメーター値を設定したら、Open() メソッドを使用して通信用のポートを開くようにコンパイラーに通知する必要があります。

_serialPort.Open();

ReadLine() メソッドは、シリアル ポート経由で受信したメッセージを読み取ることができます。

string message = _serialPort.ReadLine();

C# を使用したシリアル ポート チャット アプリケーション

このセクションでは、通信にシリアル ポートを使用するチャット アプリケーション用の完全な C# プログラムを示します。 このコード スニペットは、接続されている両方のシステムで実行して、データを送受信する必要があります。

注意: システムの接続には、null モデム ケーブルを使用してください。

Visual Studio で C# プロジェクトを作成し、コード スニペットを Program.cs ファイルに貼り付けて実行します。

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);
  }
}

上記のコード スニペットは、最初に SerialPort オブジェクトを作成し、セッターを実装してオプションの属性を設定します。 BaudRateDataBits のデフォルト値は共通であるため、ユーザーが設定する必要はありません。

Read() 関数は、シリアル ポートから入力を読み取ります。 プログラムはユーザーに入力テキストを入力するように促し、ユーザーが入力として exit を入力するまで、それをシリアル ポートに送信します。

SetPort()SetParity()SetStopBits()、および SetHandshake() は、属性値を設定するセッターです。

出力:

ユーザーは、利用可能なオプションを選択して必要な値を設定するよう求められます。たとえば、次の出力では、Com3Parity の値を Odd に、StopBitsTwo に、そして Handshake の値を None にします。

パラメータ値を設定した後、ユーザーがプログラムを終了するために exit を入力するまで、通信はシリアル ポートを使用して開始されます。

チャットアプリの出力