指紋スキャナーモジュール　GT-521F52をM5stackで動くようにしてみる　コマンドパケット編

# はじめに
これは[GTF-521指紋センサーのプログラミングガイド](https://cdn.sparkfun.com/assets/learn_tutorials/7/2/3/GT-521F52_Programming_guide_V10_20161001.pdf)と[ArduinoUNO用ライブラリ](https://github.com/sparkfun/Fingerprint_Scanner-TTL/tree/master/examples)で用いられているパケット構造体について個人的に翻訳して備忘録として記載したものとなっています。

翻訳及び内容の正確性等は保障しませんので御了承下さい。

# パケット構造体
このセンサとマイコンの間でやりとりされるパケットは3種類あります。
* コマンドパケット
* レスポンスパケット
* データパケット

コマンドパケットはマイコンからセンサに対して送信されるパケット  
レスポンスパケットはセンサからマイコンに対して送信されるパケット  
データパケットはセンサとマイコンの双方が指紋テンプレートや画像等の大量のデータをやりとりする際のパケットです。  
**尚、このライブラリにはデータパケットと、データパケットを使用するコマンドは実装されていません。  ArduinoUnoの容量の関係と、センサ内部のデータベースだけで運用しても実用に問題ないという理由で見送られています。**
# コマンドパケット

これはPCやマイコンから、センサに送信されるパケットです。

## コマンドパケット構造体
|オフセット  |アイテム |タイプ |説明 |
|---|---|---|---|
|0|0x55|BYTE|スタートコード1|
|1|0xAA|BYTE|スタートコード2|
|2|デバイスのID|WORD|デバイスID 標準では0x0001|
|4|パラメータ|DWORD|入力パラメータ|
|8|コマンド|WORD|コマンドコード|
|10|チェックサム|WORD|チェックサム|

まず0x55を送信してさらに0xAAを送信することでセンサに認識させます。
さらに2バイトのデバイスID、4バイトの入力パラメータ（これはコマンドによっては必要としなかったりします。必要ない場合は0x00,0x00,0x00,0x00が入ります。詳細はコマンドごとに異なります）、2バイトのコマンドコード、2バイトのチェックサムの合計12バイトがパケットとして1バイトずつ送信されます。  

## コマンドコード一覧
コマンドコードは以下のいずれかになります。
表で使われている指紋テンプレートとは、センサが指紋の画像から生成する識別用データです。256×256の画像が498バイトのデータに変換されます。
この表ではライブラリ上での実装状況と、コマンドコードに対応するFPS_GT511C3オブジェクトのメソッド名を示します。一部コマンドコードとメソッド名が一致していませんが仕様です。

|HEX(16進数)|Alias(別名)|説明|実装状況（メソッド）|
|---|---|---|---|
|01|Open|初期化|Open()|
|02|Close|終了|Close()|
|03|USBInternalCheck|接続されたUSBが有効かをチェック||
|04|ChangeBaudrate|UARTボーレートを変更|ChangeBaudRate(unsigned long baud)|
|12|cmosLED|CmosLED 指紋読み取り部に内臓されたLEDの制御|SetLED(bool on)|
|20|GetEnrollCount|登録済みの指紋数を取得|GetEnrollCount()|
|21|CheckEnrolled|指定したIDが既に使用されているかをチェック|CheckEnrolled(int id)|
|22|EnrollStart|指紋の登録を開始|EnrollStart(int id)|
|23|Enroll1|登録用の最初の指紋テンプレートを作成|Enroll1()|
|24|Enroll2|登録用の２番目の指紋テンプレートを作成|Enroll2()|
|25|Enroll3|登録用の３番目の指紋テンプレートを作成し、マージしてセンサ内部のデータベースに登録|Enroll3()|
|26|IsPressFinger|指紋読み取り部に指が置かれているかのチェック|IsPressFinger()|
|40|DeleteID|センサ内部のデータベースから指定されたIDの指紋テンプレートを削除|DeleteID(int ID)|
|41|DeleteALL|センサ内部のデータベースから全ての指紋テンプレートを削除|DeleteAll()|
|50|Verify|センサで読み取った指紋が、センサ内部データベースの指定されたIDのものと同じかを検証|Verify1_1(int id)|
|51|Identify|センサで読み取った指紋が、センサ内部データベースに記録されているかを検証|Identify1_N()|
|52|Verify Template|マイコンからセンサに指紋テンプレートのデータパケットを送信し、それがセンサ内部データベースの指定されたIDのものと同じかを検証||
|53|Identify Template|マイコンからセンサに指紋テンプレートのデータパケットを送信し、それがセンサ内部データベースに記録されているかを検証||
|60|Capture Finger|センサで256×256のイメージを読み取り、読み取りの成否でAck又はNackのレスポンスパケットを送信する。指がセンサ読み取り部に押し付けられている場合はAck、指が離れている場合はNackを返す|CaptureFinger(bool highquality)|
|61|Make Template|Capture Fingerで読み取った画像から送信用のテンプレートを作成する。このコマンドはCaptureFingerの後に実行されなければならない||
|62|GetImage|キャプチャされた指紋画像をセンサーからマイコンに送信する。画像は258×202||
|63|GetRawImage|生のキャプチャ画像をセンサーからマイコンに送信する。画像は160×120のQVGA||
|70|GetTemplate|指定されたIDのテンプレートをマイコンからダウンロード||
|71|SetTemplate|指定されたIDのテンプレートをマイコンへアップロード||
|72|GetDatabaseStart|指紋データーベースのダウンロードを開始 **廃止**||
|73|GetDatabaseEnd|指紋データーベースのダウンロードを終了 **廃止**||
|F0|SetSecurityLevel|セキュリティレベルを設定||
|F1|GetSecurityLevel|セキュリティレベルを取得||
|F4|Identity_Template2|マイコンからテンプレートファイルをセンサーに送信し、キャプチャした指紋画像と照合する。センサからAckが送信されれば照合に成功。Nackなら照合に失敗||
|F9|EnterStandbyMode|省電力モード||
|30|Ack|AcknowLedge 了解応答||
|31|Nack|Non-AcknowLedge　否定応答||



# レスポンスパケット
これはセンサからマイコンやPCに対して、コマンドパケットに対する応答として送信されるパケットです。

## レスポンスパケット構造体
|オフセット  |アイテム |タイプ |説明 |
|---|---|---|---|
|0|0x55|BYTE|スタートコード1|
|1|0xAA|BYTE|スタートコード2|
|2|デバイスのID|WORD|デバイスID 標準では0x0001|
|4|パラメータ|DWORD|レスポンスが**0x30**の場合：コマンド毎の出力パラメータ<br>レスポンスが**0x31**の場合：エラーコード|
|8|レスポンス|WORD|**0x30** 了解応答:Acknowledge(Ack)<br>**0x31** 否定応答:Non-Acknowledge(Nack)|
|10|チェックサム|WORD|チェックサム|

## エラーコード一覧
エラーコードは以下のいずれかになります。

|パラメーター|値|説明|
|---|---|---|
|NACK_TIMEOUT|0x1001|**廃止** 指紋キャプチャー時のタイムアウト|
|NACK_INVALID_BAUDRATE|0x1002|**廃止** 無効なボーレート|
|NACK_INVALID_POS|0x1003|指定されたIDが0~999の間にありません(これは恐らく記述ミスです。センサの構造上0~199又は0~2999の間にありませんというのが正しいと思われます。)|
|NACK_IS_NOT_USED|0x1004|指定されたIDは使われていません。|
|NACK_IS_ALREADY_USED|0x1005|指定されたIDは使われています。|
|NACK_COMM_ERR|0x1006|コミュニケーションエラー|
|NACK_VERIFY_FAILED|0x1007|1:1検証失敗|
|NACK_IDENTIFY_FAILED|0x1008|1:N識別失敗|
|NACK_DB_IS_EMPTY|0x1009|データベースが空|
|NACK_DB_IS_FULL|0x100A|データベースが満杯|
|NACK_TURN_ERR|0x100B|**廃止** 発行順が無効<br>指紋登録時にEnrollStart→Enroll1→Enroll2→Enroll3の順番でコマンドが送信されたかった場合|
|NACK_BAD_FINGER|0x100C|指紋データ不良|
|NACK_ENROLL_FAILED|0x100D|登録失敗|
|NACK_IS_NOT_SUPPORTED|0x100E|指定されたコマンドはサポートされていません|
|NACK_DEV_ERR|0x100F|デバイスエラー。特に暗号チップのトラブル|
|NACK_CAPTURE_CANCELED|0x1010|**廃止** 指紋キャプチャがキャンセルされました|
|NACK_INVALID_PARAM|0x1011|無効なパラメータ|
|NACK_FINGER_IS_NOT_PRESSED|0x1012|指がセンサに触れていません|
|Duplicated ID|0-2999|指紋が重複している（登録又はテンプレート設定中のみのエラー）このIDはIDの重複を示している。|

# データパケット 
データパケットは以下のものになります。
このパケットのサイズはコマンド毎に異なります。

**ArduinoUNO用ライブラリには定義されていません。**

|オフセット  |アイテム |タイプ |説明 |
|---|---|---|---|
|0|0x5A|BYTE|データスタートコード1|
|1|0xA5|BYTE|データスタートコード2|
|2|デバイスのID|WORD|デバイスID 標準では0x0001|
|4|Data|N BYTES|Nバイトのコード<br>データのサイズはプロトコルごとに定義|
|4+N|チェックサム|WORD|チェックサム|

# おわりに
マイコンとセンサの間でやりとりされるコマンドパケットについての記述はこれで終わりです。
コマンドパケット自体に関する解説は後日行おうと思います。