FTDIのUSBシリアル変換ICへ接続する時に、COM番号ではなくシリアルナンバーを使って接続する方法

# 記事の条件

WindowsFormsアプリケーション（C#）のSerialPortクラスを使用している。

FTDIのUSBシリアル変換IC(FT232RLなど)へ接続している。

# 問題点

COMポートの番号をデバイスマネージャーで調べてから、ドロップダウンリストで選ばせて接続しているが、毎回COMポートの番号を選ぶのがめんどくさい、または、ユーザーへ説明がめんどくさい。

PCが変わったり、USBポートを差し替えると、COM番号も変わってしまいめんどくさい。

1PCで2台以上のFTDIに接続している場合に、こっちのUSBシリアルはこっちの機器に、あっちのUSBシリアルはあっちの機器に、毎回決まった機器と接続させたい。

などの困りごとはありませんか？

今回は、FTDIのUSBシリアル変換IC内に、出荷時にメーカーで書き込まれているシリアルナンバーを使って、接続する方法を紹介します。

# 方法

## 1.シリアルナンバーを調べる

FTDIの「FT Prog」を起動します。

DEVICES→SCANを選ぶか、虫眼鏡アイコンをクリックします。

![picture_pc_b38323aef8e6a471d136b9bbecca8ba1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165589/5302f504-a7fd-4b6c-8f1f-24a9d91557b0.png)

![picture_pc_b38323aef8e6a471d136b9bbecca8ba1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165589/3c8d3166-7593-4c3c-8154-895f8dc8a3bc.png)

PCに接続されているFTDIチップの一覧と、それぞれのシリアルナンバーがわかります。

## 2.WindowsFormsアプリケーション（C#）のプロジェクトを作成します。

SerialPortを2つ用意します。

![picture_pc_b38323aef8e6a471d136b9bbecca8ba1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165589/4769b68e-fa1a-474e-983f-81bc63af5690.png)

![picture_pc_b38323aef8e6a471d136b9bbecca8ba1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165589/51dd679a-5dde-4e1c-aadc-95e06ee462ef.png)

PortNameのプロパティに、先ほど調べたシリアルナンバーを入力します。

このままではエラーになります。

## 3.シリアルナンバーと一致するデバイスを検索し、COM番号を取り出す

PortNameのプロパティに設定した文字列と一致するデバイスを探し、そのデバイスの接続されているCOM番号を取り出します。


```csharp
using System;
using System.Windows.Forms;
using System.Management;

namespace WindowsFormsApp1
{
   public partial class Form1 : Form
   {
       public Form1()
       {
           InitializeComponent();
       }

        private void Form1_Load(object sender, EventArgs e)
       {
           textBox1.Text = serialPort1.PortName;
           serialPort1.PortName = getComNumber(serialPort1.PortName);
           textBox2.Text = serialPort1.PortName;

           textBox3.Text = serialPort2.PortName;
           serialPort2.PortName = getComNumber(serialPort2.PortName);
           textBox4.Text = serialPort2.PortName;
       }

       // FTDI SerialNumberからCOM番号を取得
       private string getComNumber(string serialNumber)
       {
           var devices = new ManagementClass("Win32_PnPEntity").GetInstances();
           foreach (var device in devices)
           {
               // DeviceIDプロパティにFTDIシリアルナンバーと一致する文字列があるデバイスを探す
               if (device.GetPropertyValue("DeviceID") == null) continue;
               if (device.GetPropertyValue("DeviceID").ToString().Contains(serialNumber))
               {
                   // Nameプロパティに(COMという文字列があるか確認
                   if (device.GetPropertyValue("Name") == null) continue;
                   if (device.GetPropertyValue("Name").ToString().Contains("(COM"))
                   {
                       // COM番号を取り出す
                       var portName = device.GetPropertyValue("Name").ToString();
                       portName = portName.Remove(portName.IndexOf(")"));
                       portName = portName.Remove(0, portName.IndexOf("(") + 1);
                       return portName;
                   }
               }
           }
           return serialNumber;
       }
   }
}
```

Form1_Load()でgetComNumber()を呼び出し、戻り値をserialPort1.PortNameに格納し直しています。

getComNumber()では、シリアルナンバーと一致するデバイスを検索し、そのデバイスのCOM番号を取り出しています。

![picture_pc_b38323aef8e6a471d136b9bbecca8ba1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165589/c322486a-ce4a-49d7-b20a-6c7a9849294c.png)

実行するとCOM番号を取り出せているのがわかります。

接続するのはあくまでも普通のSerialPortクラスですので、取得したCOM番号を使用して接続します。

この後、任意のタイミングでserialPort1.Open()などとして、接続してください。

---

本記事は以上となります。