ArduinoでRFID-RC522　サンプル"ReadAndWrite"がエラーになる件

#はじめに
2018/03/09現在、RFID-RC522はamazonで最安値258円とかで売られています。これは中国発送なので時間が掛かりますが、国内発送でも1000円までで買えてしまいます。MIFAERカードとキーfobも1ヶずつと、ストレートとL型のピンヘッダ―もついてます。すごい時代ですね～。
<img src="https://qiita-image-store.s3.amazonaws.com/0/241992/58af08a5-423a-49c0-a996-d31fb5b331a9.jpeg" width=70%>
で、このRFID-RC522をArduinoで試してみました。接続方法とかサンプル"DumpInfo"は多くの方が解説されていますので検索してみてください。
今回はサンプル"ReadAndWrite"を使用します。他の方も試されて書き込みできなかったという事を書かれていますが、解決方法を日本語で書かれているのは見つからなかったので記載します。
たぶん、使用用途がUIDの読み込みだけで事足りるからなのでしょうか？
#Arduinoのライブラリ
使用するライブラリはArduino IDEのメニューで、

1. スケッチ＞ライブラリーをインクルード＞"ライブラリを管理..."を選択して
2. ライブラリマネージャーの右上の入力欄に「MFRC」で検索すると出てくるものをインストールします。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/241992/ec4f18d3-c977-f62f-c877-82e47e77bfe6.png)
#スケッチの例
Arduino IDEのメニューで、

1. ファイル＞スケッチの例＞MFRC522＞"ReadAndWrite"を選択
2. あとは普通にArduinoに書き込んでください。
3. シリアルモニターを開いて試してみると以下のメッセージが出ます。

```
Scan a MIFARE Classic PICC to demonstrate read and write.
Using key (for A and B): FF FF FF FF FF FF
BEWARE: Data will be written to the PICC, in sector #1
```

ここでカードをかざすと、

```
Card UID: ** ** ** **　←通常はUIDが表示されます
PICC type: MIFARE 1KB
Authenticating using key A...
Current data in sector:
   1      7   00 00 00 00  00 00 FF 07  80 69 FF FF  FF FF FF FF  [ 0 0 1 ] 
          6   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
          5   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
          4   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 

Reading data from block 4 ...
Data in block 4:
 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

Authenticating again using key B...
Writing data into block 4 ...
 01 02 03 04 05 06 07 08 08 09 FF 0B 0C 0D 0E 0F
MIFARE_Write() failed: A MIFARE PICC responded with NAK.

Reading data from block 4 ...
MIFARE_Read() failed: Timeout in communication.
Data in block 4:
 30 04 26 EE 00 00 00 00 00 00 00 00 00 00 00 00
Checking result...
Number of bytes that match = 0
Failure, no match :-(
  perhaps the write didn't work properly...

Current data in sector:
   1      7  PCD_Authenticate() failed: Timeout in communication.
```

こんな感じで延々とメッセージが返ってくると思います。17行目に"MIFARE_Write() failed:"と出て書き込みに失敗しています。

スケッチのどこを修正すれば良いのか？先に結論から

スケッチ"ReadAndWrite.ino"の134行目

```php
status = (MFRC522::StatusCode) mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_B, trailerBlock, &key, &(mfrc522.uid));
```

```c
AUTH_KEY_B
↓
AUTH_KEY_A
```
BをAに修正すると書き込みが出来るようになります。

```
Scan a MIFARE Classic PICC to demonstrate read and write.
Using key (for A and B): FF FF FF FF FF FF
BEWARE: Data will be written to the PICC, in sector #1
Card UID: ** ** ** ** ←通常はUIDが表示されます
PICC type: MIFARE 1KB
Authenticating using key A...
Current data in sector:
   1      7   00 00 00 00  00 00 FF 07  80 69 FF FF  FF FF FF FF  [ 0 0 1 ] 
          6   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
          5   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
          4   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 

Reading data from block 4 ...
Data in block 4:
 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

Authenticating again using key B...
Writing data into block 4 ...
 01 02 03 04 05 06 07 08 08 09 FF 0B 0C 0D 0E 0F

Reading data from block 4 ...
Data in block 4:
 01 02 03 04 05 06 07 08 08 09 FF 0B 0C 0D 0E 0F
Checking result...
Number of bytes that match = 16
Success :-)

Current data in sector:
   1      7   00 00 00 00  00 00 FF 07  80 69 FF FF  FF FF FF FF  [ 0 0 1 ] 
          6   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
          5   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
          4   01 02 03 04  05 06 07 08  08 09 FF 0B  0C 0D 0E 0F  [ 0 0 0 ] 
```

ちゃんと書き込みが出来ています。

#少しだけ解説
読み込みや書き込みをするには、先に認証が必要で、このスケッチではKEY_AやKEY_Bを使用して認証をおこなっています。出荷状態のMIFARE ClassicカードのKEYはA、Bともに"FF FF FF FF FF FF"になっています。そして出荷状態ではKEY_Aしか使用できません。ということらしいです。なので読み込み時はKEY_Aで認証をおこない、認証が成功したので読み込めています。書き込み前にKEY_Bで認証をおこなった後に認証を失敗しているので書き込みが出来ていないのです。

そして、MIFARE Classicカード(1K)は1セクター(64バイト)のセクターが16個あり、1セクターには1ブロック(16バイト)のブロックが4個あります。更に4ブロックのうち4番目のブロックはトレーラーブロックというKEY_AやKEY_Bを格納するブロックです。

```
Current data in sector:
   1      7   00 00 00 00  00 00 FF 07  80 69 FF FF  FF FF FF FF  [ 0 0 1 ] 
          6   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
          5   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
          4   01 02 03 04  05 06 07 08  08 09 FF 0B  0C 0D 0E 0F  [ 0 0 0 ] 
```
これはセクター1(4～7ブロック)を読み込んだ物ですが、ブロックの番号が4から始まっています。セクター0(0～3ブロック)なのでブロックはセクター0から63までの連番になっています。そして各ブロックの右端[ 0 0 1 ]や[ 0 0 0 ]はAccess bitsというもので、各ブロックの読み書きの認証方法に関する情報が格納されている場所です。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/241992/3809c332-6fe0-7f83-b41a-120a23ea16d8.png)


上記のテーブルはトレーラーブロックのAccess Bitsに対応するAccess conditionの対応表。これを見ると、7ブロック(トレーラーブロック)の[ 0 0 1 ]はKEY_Aでのみ読み書き可能(ただし、KEY_Aは読めない)。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/241992/c83e840c-a61d-8b8a-0f62-d392431f309f.png)

上記はデータブロックのAccess Bitsに対応するAccess conditionの対応表。これを見ると4～6ブロックの[ 0 0 0 ]はKEY_A/Bの両方で読み書き可能となっています。しかし先のトレーラーブロックのAccess Bitsが[ 0 0 1 ]なので、KEY_Aでしか認証できないようになっているので、KEY_Aでしか読み書きができません。という事なんだと解釈しています。

※間違っていたらすみません・・・。