ThingMagic M6e Nano を使用した UHF 帯 RFID の制御

# ThingMagic M6e Nano
[ThingMagic M6e Nano](https://www.jadaktech.com/products/thingmagic-rfid/thingmagic-m6e-nano-uhf-rain-rfid/ "ThingMagic M6e Nano") を使用した UHF 帯 RFID の読込み方法を記載します.
ThingMagic M6e Nano は Impinj 社や Unitech 社など既製品の UHF 帯 RFID リーダライタと比べるとモジュールであるため比較的安価で入手することができます.
また, 特定小電力のモジュールであるため電波申請をせずに空中線電力とアンテナ利得の合計で最大 27\[dBm\](500\[mW\])まで電力の出力が行えます.
[208-160028](https://www.tele.soumu.go.jp/giteki/SearchServlet?pageID=jg01_01&PC=208&TC=N&PK=1&FN=107sie&SN=%94F%8F%D8&LN=3&R1=*****&R2=*****)


EPC Class1 Gen2 対応 Rain RFID を IC として ST25RU3993 や Impinj E700, E500 などがありますがアンテナや電源なの最小構成の回路を省略するため [ThingMagic M6e Nano Carrier Board](https://www.atlasrfidstore.com/thingmagic-nano-carrier-board/ "") を使用しております.

# システム構成
回路図, 回路構成およびシステム構成について記します.

## 回路図
![回路図](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33399/e7d99e17-7fca-de38-fd31-557c8e6922c7.png)
回路図

## 回路構成
| 全体 | M6e Nano | CH340N |
| :---: | :---: | :---: |
| ![校正](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33399/f9df8eee-2274-b6ec-cceb-ebbd5c10c0c9.jpeg) | ![ThingMagic M6e Namo](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33399/9a9aa532-aebc-1238-3d8e-e4e8d43bfec1.jpeg) | ![CH340N](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33399/a1252b8b-a843-de06-733f-774797992015.jpeg) |

ThingMagic M6e Nano と PC 間は シリアル通信(USART) が用いられるため CH340N を使用しています.
FT230XS でも動作は確認しておりますが在庫の関係とシリアル通信だけ使用できれば良いため, 部品数が少なくて済む CH340N を採用しました. Windows 10 及び Linux 環境下では接続すれば仮想ポート, /dev/ttyUSBn として認識されます. 秋月電子社のホームページからドライバのダウンロードを行えます. Linux であればドライバのビルド, パッケージのインストールが行えます.
CH340N と M6e Nano キャリアボード 間のコネクタは Molex 53261-1571.

[CH340N](https://akizukidenshi.com/catalog/g/gI-16305/ "CH340N")
[FT230XS](https://akizukidenshi.com/catalog/g/gI-13311/ "FT230XS")

## 制御ソフト
ThingMagic 系のモジュールが使用されている製品であれば, Jadak 社が提供している [Universal Reader Assistant](https://www.jadaktech.com/products/thingmagic-rfid/thingmagic-universal-reader-assistant/ "Universal Reader Assistant") で基本的な制御は行えます.
ThingMagic M6e Micro, ThingMagic M6e Nano, Unitech RS200 などが該当.

![UniversalReaderAssistant.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33399/ec24804f-8c58-a81c-01c1-73b205075d74.png)

## システム構成
| 名称 | バージョン |
| :--- | :--- |
| C# | 9.0 |
| MercuryAPI | 1.31.1.36 |
| ThingMagic M6e Nano | (FW)1.09.02.02 |

# Mercury API
Mercury API を使用したプログラム例を記載します. 今回使用するバージョンは, M6e Nano のページでダウンロードできる 1.31.1.36 となります.
このバージョンの他にも 1.35.1.103 がありますがファームウェアがサポートしていない命令が存在するためこの例では使用していません. ただし, 共通の命令のみ使用する場合は問題ありません.

[OEM Embedded ThingMagic UHF/RAIN RFID Module / Nano | JADAK](https://www.jadaktech.com/products/thingmagic-rfid/thingmagic-m6e-nano-uhf-rain-rfid/ "M6e Nano")
## 接続
`ThingMagic.Reader.Create(uriString: string)` で接続するモジュールを特定.
Uri スキームは, 組み込みモジュールであれば `eapi`, リクエストクエリ言語であれば `rql`, 推定する場合は `tmr` になります.

```Program.cs
var connectionRegex = new Regex("(eapi|rql|tmr):\\/\\/\\/?.*", RegexOptions.Compiled);
string uriString = connectionRegex.IsMatch(args[0])
  ? args[0] 
  : $"eapi:///{args[0]}";

Console.Error.Write($"# Connection... {uriString}");

using var reader = ThingMagic.Reader.Create(uriString: uriString);
// 接続
reader.Connect();
// タグイベント
reader.TagRead += OnReaderTagRead;

#if DEBUG
// リーダクラスの確認
Console.Error.WriteLine($" => {reader.GetType().FullName}");
#endif
```

## リーダパラメータの指定
この例では下記のような設定を行っています.

- 使用地域: JP
- セッション: S1
- 読込 / 書込 電力: 21[dBm] \(6\[dBc\] のアンテナを使用しているため最大の値として\)
- アンテナ: 1 \(M6e Nano で使用できるアンテナは 1 のみ\)
- プロトコル: C1G2 GEN2

```Program.cs
// パラメータ設定 //

// 使用周波数
reader.ParamSet("/reader/region/id", ThingMagic.Reader.Region.JP);
// パワーモード
reader.ParamSet("/reader/powerMode", ThingMagic.Reader.PowerMode.FULL);
// セッション
//reader.ParamSet("/reader/gen2/session", ThingMagic.Gen2.Session.S0);
reader.ParamSet("/reader/gen2/session", ThingMagic.Gen2.Session.S1);

// 読込電力 21[dBm]
reader.ParamSet("/reader/radio/writePower", 2100);
// 書込電力 21[dBm]
reader.ParamSet("/reader/radio/readPower", 2100);

reader.ParamSet("/reader/regulatory/mode", ThingMagic.Reader.RegulatoryMode.CONTINOUS);

var readPlan = new ThingMagic.SimpleReadPlan(
    antennaList: new int[] { 1 },
    protocol: ThingMagic.TagProtocol.GEN2);
reader.ParamSet("/reader/read/plan", readPlan);
```

## 読込 開始 / 停止
読み込み開始後 3000[mS] 間遅延した後停止します.

```Program.cs
reader.StartReading();

await Task.Delay(3000);

reader.StopReading();
```

## 受信イベント
受信したタグの EPC, 受信感度, タグ検出角度を出力します.
```Program.cs
/// <summary>受信イベント</summary>
private static void OnReaderTagRead(
    object? source,
    ThingMagic.TagReadDataEventArgs e) {
  Console.Error.WriteLine($"{e.TagReadData.EpcString} {e.TagReadData.Rssi} {e.TagReadData.Phase}");
}
```

## 実行結果
`dotnet run -- COM[n]`
![実行結果](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33399/687468c8-2859-f657-76d9-e9b71babd864.png)


# 備考
## Raspberry PI 及び Linux で使用する場合
Raspberry PI 及び Linux で使用する場合は `.NET` をインストールしてください.
MercuryAPI 自体が `.NET Framework` で提供されているため, `.NET Core` 或いは `.NET Standard` に変換する必要があります.
Windows 環境下で `.NET Standard` に変換すれば共通のソースコードで動作させることができます.