for WPF developers
Home Profile Tips 全記事一覧

データを受信する

(2016/12/03 0:34:39 created.)

System.IO.Ports.SerialPort クラスは、受信動作自体が .NET Framework の仕組みで動作するため、インスタンス生成後、特にコードを追加する必要がありません。インスタンス生成後、何かデータを受信すると、DataReceived イベントが発生するので、このイベントにイベントハンドラを登録するだけで受信処理をおこなえます。

Program.cs
  1. namespace Tips_Serial
  2. {
  3.     using System;
  4.     using System.IO.Ports;
  5.     using System.Text;
  6.  
  7.     class Program
  8.     {
  9.         static void Main(string[] args)
  10.         {
  11.             using (var serial = new SerialPort()
  12.             {
  13.                 PortName = "COM11",
  14.                 BaudRate = 9600,
  15.                 DataBits = 8,
  16.                 Parity = Parity.None,
  17.                 StopBits = StopBits.One,
  18.                 DtrEnable = false,
  19.                 RtsEnable = false,
  20.                 ReadBufferSize = 256,
  21.                 WriteBufferSize = 256,
  22.                 Encoding = Encoding.GetEncoding("Shift_JIS"),
  23.             })
  24.             {
  25.                 try
  26.                 {
  27.                     // 受信イベントを購読する
  28.                     serial.DataReceived += OnReceived;
  29.  
  30.                     // ポートオープン
  31.                     serial.Open();
  32.                 }
  33.                 catch (Exception ex)
  34.                 {
  35.                     Console.WriteLine(ex);
  36.                 }
  37.                 finally
  38.                 {
  39.                     Console.WriteLine("{0} ポートを" + (serial.IsOpen ? "開きました。" : "開けませんでした。"), serial.PortName);
  40.                 }
  41.  
  42.                 Console.ReadKey();
  43.             }
  44.         }
  45.  
  46.         /// <summary>
  47.         /// データ受信イベントハンドラ
  48.         /// </summary>
  49.         /// <param name="sender">イベント発行元</param>
  50.         /// <param name="e">イベント引数</param>
  51.         private static void OnReceived(object sender, SerialDataReceivedEventArgs e)
  52.         {
  53.             var serial = sender as SerialPort;
  54.             var data = serial.ReadExisting();
  55.             Console.WriteLine(data);
  56.         }
  57.     }
  58. }

受信動作自体が非同期的に裏で動くことになるため、上記のプログラムでは、ポートオープン後、42 行目のキー入力待ちで停止することになります。

受信イベントに OnReceived() メソッドを登録しておいたので、受信データを出力できるようになりました。エンコードとして Shift_JIS を指定して SerialPort クラスのインスタンスを生成しているので、日本語を受信すると自動的に変換されている様子がわかります。
ただし、受信イベントは非同期処理されているため、元のスレッドとは異なるスレッドで実行されています。したがって、WPF と連携する場合、UI の操作と絡むようなことをする場合は UI スレッドに切り替える必要があることを注意しなければいけません。スレッドの固有 ID は System.Threading.Thread.CurrentThread.ManagedThreadId プロパティで取得できるので、確認してみてください。