C#でひとりシリアル通信をした時のメモ

1. com0comのインストール
→2つの仮想COMポートを用意し、一方から他方に通信しているように見せかける事が可能。

    1. http://sourceforge.net/projects/com0com/ よりzipをダウンロードし、適当なディレクトリに解凍。
    2. setup.exeを開き、「next -> I Agree -> install」
    3. ハードウエア検出ウィザード「接続しない -> 自動インストール -> 完了」(2セット)
    4. setup.exe: 「finish」
    5. バイスマネージャよりcom0comが認識されていることを確認。

2. ポート名の変更
→初期設定ではポート名が CNCA0 と CNCB0 になっているので、これを COM8 と COM9 に変更。

    1. スタート -> すべてのプログラム -> com0com -> SetupCommandPrompt
    2. 「change CNCA0 PortName=COM8」
    3. 「change CNCB0 PortName=COM9」にて名前変更。
    4. 「list」にてポート名を確認

完成図

以上の手順はWin7ないしvistaの場合テストモードでの起動が必要になったりと色々面倒なようです。

3. C#のソースの用意

送信用

using System;
using System.Collections.Generic;
using System.Linq;
using System.IO.Ports;
using System.Text;

namespace ComWrite
{
    class Program
    {
        static void Main(string[] args)
        {
            while (true)
            {
                Console.Write("sending message -> ");
                string req = Console.ReadLine();
                SerialPort port = new SerialPort("COM8", 9600, Parity.None, 8, StopBits.One);
                try
                {
                    port.Open();

                    // フロー制御はしません。
                    port.DtrEnable = false;
                    port.RtsEnable = false;

                    port.WriteLine(req);

                    Console.WriteLine("send   :" + req);
                    Console.WriteLine("received:" + port.ReadLine());
                }
                catch (Exception e)
                {
                    Console.WriteLine("Unexpected exception: ", e.ToString());
                }
                port.Close();
                port.Dispose();
            }
        }
    }
}

受信用

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Ports;

namespace ComRead
{
    class Program
    {
        static void Main(string[] args)
        {
            SerialPort port = new SerialPort("COM9", 9600, Parity.None, 8, StopBits.One);
            port.DataReceived += new SerialDataReceivedEventHandler(SerialPort_DataReceived);
            try
            {
                port.Open();
                port.DtrEnable = false;
                port.RtsEnable = false;
            }
            catch (Exception e)
            {
                Console.WriteLine("Unexpected exception: ", e.ToString());
            }
            Console.ReadLine();
            port.Close();
            port.Dispose();
        }

        private static void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            SerialPort port = (SerialPort)sender;
            byte[] buf = new byte[1024];
            int len = port.Read(buf, 0, 1024);
            string s = Encoding.GetEncoding("Shift_JIS").GetString(buf, 0, len);
            port.WriteLine(s);
            Console.Write("received: " + s);
        }
    }
}

意外とシンプル。
初めてのC#だったけど、なんとかなるものです。

動作環境
Windows XP pro sp3
Microsoft Visual Studio 2008 Professional

参考
http://homepage2.nifty.com/nonnon/Link/Null-Modem-Win7.html
http://msdn.microsoft.com/ja-jp/library/cc825644.aspx
浅草ギ研 Visual C# 2005 のシリアル通信機能を使ってみる