Wio LTEとFeliCa リーダーライター RC-S620/S で FeliCa の IDm を読む

年末進行のハズなのに、手元にFeliCa リーダー・ライター「[RC-S620/S](https://www.sony.co.jp/Products/felica/business/products/RC-S620.html)」が到着したので手を出してしまった [松下(ニックネーム: Max)](https://twitter.com) です。

Wio LTE JP Version に RC-S620/S を取り付けたら、サクッと FeliCa が読めるようになりましたので手順を紹介します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22754/f8eb359e-3945-094d-6ebc-2d3b5028418e.png)
*FeliCa 近づけて IDm（製造 ID) を表示させているところ*

## 手順

* ハードウェア
    * Wio LTE の UART ポートに接続。
* ソフトウェア
    * [Arduino 向け RC-S620/S 制御ライブラリ](http://blog.felicalauncher.com/?p=2677) をダウンロードし、 Arduino IDE のライブラリとして取り込む。
    * 取り込んだライブラリの `RCS620S.cpp` を編集。

### ハードウェア

最終的には以下のようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22754/be9d9cad-9d91-4d83-3be4-d51bfa143fca.png)

#### RC-S620/S

[RC-S620/S](https://www.switch-science.com/catalog/353) は既に完成してます。フラットケーブルを接続するだけです。
このフラットケーブルの接続は「気合」です。ググっと手で押し込む感じになります。表裏は写真で見ている通り、「青」が見えるように挿しこみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22754/7bb812d8-19be-2b07-3dc8-01fb6cb3aeb1.png)

#### FFC-6

フラットケーブルをブレッドボードに落とすことができるモジュールです。
[現行品](https://www.switch-science.com/catalog/1029/)は、はんだ付けが必要となります。

ブレッドボードに挿し、フラットケーブルを接続すると以下のようになります。フラットケーブルは引き出し型なので、RC-S620/S よりは安定して接続できます。

ピンアサインは商品ページに書かれています。
[Grove ケーブル](https://www.sengoku.co.jp/mod/sgk_cart/detail.php?code=EEHD-4K34) の並びと同じになっているので素直に挿すことができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22754/9ed77a91-c290-6cc4-e32d-6be5df0d90d0.png)

#### Wio LTE との接続

ブレッドボードを介して FFC-6 と Wio LTE JP Version の UART に接続します。

## ソフトウェア

[Arduino 向け RC-S620/S 制御ライブラリ](http://blog.felicalauncher.com/sdk_for_air/?page_id=2699) をダウンロードし、 Arduino IDE のライブラリとして取り込み、コードを書けば動きます。

### `RCS620S.cpp` の編集

RC-S620/S ライブラリを取り込んだら `RCS620S.cpp` を探して2点編集します。

1. 新しい Arduino ライブラリを読み込むようにする
2. `Serial` とハードコードされている部分を変更する

```diff
diff -ur --color arduino-RCS620S.origin/RCS620S.cpp arduino-RCS620S/RCS620S.cpp
--- arduino-RCS620S.origin/RCS620S.cpp  2019-12-28 23:17:25.734916000 +0900
+++ arduino-RCS620S/RCS620S.cpp 2019-12-28 23:18:52.932437700 +0900
@@ -7,7 +7,7 @@
 #include <stdio.h>
 #include <string.h>
 #include <inttypes.h>
-#include "Wprogram.h"
+#include "Arduino.h"
 #include "Print.h"
 #include "HardwareSerial.h"

@@ -309,7 +309,7 @@
     const uint8_t* data,
     uint16_t len)
 {
-    Serial.write(data, len);
+    Serial1.write(data, len);
 }

 int RCS620S::readSerial(
@@ -324,8 +324,8 @@
             return 0;
         }

-        if (Serial.available() > 0) {
-            data[nread] = Serial.read();
+        if (Serial1.available() > 0) {
+            data[nread] = Serial1.read();
             nread++;
         }
     }
@@ -335,7 +335,7 @@

 void RCS620S::flushSerial(void)
 {
-    Serial.flush();
+    Serial1.flush();
 }

 int RCS620S::checkTimeout(unsigned long t0)
```

Arduino API は 1.0 から include ファイルが `Wprogram.h` から `Arduino.h` にリネームされています。一方、配布されているライブラリは古い方を参照しているため include を調整します。

RC-S620/S と接続す UART が `Serial` とハードコードされています。
本来ならば `RCS620S` のインスタンス作成時に引数で UART を指定できるようにする修正を入れたいところですが、ちょっと面倒だったので Wio LTE JP Version の UART である Serial1 をハードコードして対応しています。

### スケッチ

```c++:WioLTE_rcs620s.ino
#include <WioLTEforArduino.h>
WioLTE Wio;
#define CONSOLE SerialUSB

#include <RCS620S.h>
RCS620S rcs620s;

void setup() {
  delay(200);
  CONSOLE.println("\n-- START");
  Wio.Init();
  CONSOLE.begin(115200);
  Wio.PowerSupplyGrove(true);
  Serial1.begin(115200); /* for Wio LTE hardware UART */
  while(!rcs620s.initDevice()); /* ret=1 is failed init */
  CONSOLE.println("\n-- Ready");
}

void loop() {
  CONSOLE.println("\n-- loop");
  if (rcs620s.polling()) {
    CONSOLE.println("FeliCa detected!");
    CONSOLE.print("IDm = ");
    for(int i = 0; i < sizeof(rcs620s.idm) ; i++) {
      char buf[2];
      sprintf(buf, "%02X", rcs620s.idm[i]);
      CONSOLE.print(buf);
    }
    CONSOLE.println();
  }
  rcs620s.rfOff();
  delay(1000);
}
```

あとは FeliCa を近づければ以下のように表示してくれます。

```
-- loop
FeliCa detected!
IDm = xxxxxxxxxxxxxx
```

と表示します。

## FeliCa の IDm

FeliCa が持っているユニーク ID が IDm(製造 ID)です。FeliCa を鍵のように使いたい場合はこの情報を使えば OK かと思います。
それ以外の詳細な技術資料は [PDF でダウンロード](https://www.sony.co.jp/Products/felica/business/tech-support/) できます。

## 読み込める FeliCa

FeliCa 規格になっているものであれば何でも読み込み可能です。（書込みは試していません）
https://www.sony.co.jp/Products/felica/business/products/

今回は以下の3つを試して IDm が読み込めることを確認しました。

* ["FeliCa Lite-S" (型番: RC-S966)](https://www.sony.co.jp/Products/felica/business/products/RC-S966.html)
* 市販されている Suica カード
* Google Pixel 4 の NFC

デバッグ用としては IDm がカードに刻印されているものが便利です。

## この後の発展について

Cat.1 モデムがついている Wio LTE で読めるようになったので、 AWS Lambda 等の FaaS を直接呼び出せる [SORACOM Funk](https://soracom.jp/services/funk/) を使って、クラウド上のデータベースとのマッチングをするといった事が簡単にできるでしょう。

**クラウドアダプタ / SORACOM Funk**
![SORACOM Funk](https://soracom.jp/img/fig_funk01.png)

### 余談: SoftwareSerial との相性が悪いみたい

Arduino UNO R3 は HardwareSerial が1つしかないので SoftwareSerial を使うしかないのですが、ちょっと試したところうまく動きません。
2012年にトライされた方の記録: http://www.atelier-nodoka.net/2012/04/arduino-software-serial-problem/
どうしたらいいんだろう。。。 Wio LTE JP Version には HardwareSerial が実装されてて良かった！

## 今回使った機材の費用

ざくっと計算すると、このくらいでした。

* 約 15,840円

※金額は税抜きです。

| 役割 | 機材 | 金額 |
|-----|-----|-----:|
| マイコン＆モデムボード| [Wio LTE JP Version](https://soracom.jp/products/module/wio_lte/) | 9800円 |
| FeliCa リーダー・ライター | [RC-S620/S](https://www.switch-science.com/catalog/353/) | 3350円 |
| RC-S620/S ピッチ変換基板セット | [FFC-6](https://www.switch-science.com/catalog/1029/) | 510円 |
| 検証用 FeliCa カード | [FeliCa Lite-S (RC-S966) 5枚セット](https://www.amazon.co.jp/gp/product/B078FRWVWP/) | 1240円 |
| ブレッドボード | どこのやつだったかな？ | 300~500円くらい |
| ケーブル | [Grove ジャンパーピン変換ケーブル (5本入り)](https://www.sengoku.co.jp/mod/sgk_cart/detail.php?code=EEHD-4K34#) | 500円くらい |

## おわりに

こんなことをしている場合じゃないんだが、、、
すでに持っている FeliCa が読めるようになるのは楽しいし、可能性を感じる。
入退出に使えるよね？

### 参考資料

* [DSAS開発者の部屋 / 電波法適合の NFC モジュールで安価な NFC タグを利用する](http://dsas.blog.klab.org/archives/2018-04/52291765.html)
* [Atelier NODOKA / Arduino+RC-S620/SでFeliCa Push](http://www.atelier-nodoka.net/2012/04/arduino-rcs620s-sample/)

EoT