環境構築:Arduino IDE 入門ガイドを参考にIDEをインストールし、使用する開発ボードに応じてボードマネージャと必要なライブラリをインストールしてください。
使用ライブラリ:
使用ハードウェア:

G17 (RX)、G18 (TX) です。指紋センサーにはRGB LEDが内蔵されており、PS_ControlBLN関数を使って色やモードを設定できます。必要に応じて以下の定義を利用してください。
関数プロトタイプ:
fingerprint_status_t PS_ControlBLN(
fingerprint_led_control_mode_t mode,
fingerprint_led_color_t startColor,
fingerprint_led_color_t endColor,
uint8_t loopCount = 0
) const; パラメータ:
mode:LEDモード。下記fingerprint_led_control_mode_t参照。startColor:開始色。下記fingerprint_led_color_t参照。通常のブリージングモードのみ有効。endColor:終了色。下記fingerprint_led_color_t参照。loopCount:ループ回数。0は無限ループ、NはN回ループ。ブリージング・フラッシュモードのみ有効。戻り値:
FINGERPRINT_OK:成功fingerprint_status_tを参照。関連定義:
fingerprint_led_control_mode_ttypedef enum {
FINGERPRINT_LED_BREATHING = 1, // 普通呼吸灯 / Normal breathing light
FINGERPRINT_LED_FLASHING = 2, // 闪烁灯 / Flashing light
FINGERPRINT_LED_ON = 3, // 常开灯 / Always on
FINGERPRINT_LED_OFF = 4, // 常闭灯 / Always off
FINGERPRINT_LED_FADE_IN = 5, // 渐开灯 / Fade in
FINGERPRINT_LED_FADE_OUT = 6 // 渐闭灯 / Fade out
} fingerprint_led_control_mode_t; fingerprint_led_color_ttypedef enum {
FINGERPRINT_LED_COLOR_OFF = 0x00, // 全灭 / All off
FINGERPRINT_LED_COLOR_BLUE = 0x01, // 蓝灯 / Blue
FINGERPRINT_LED_COLOR_GREEN = 0x02, // 绿灯 / Green
FINGERPRINT_LED_COLOR_CYAN = 0x03, // 青色灯 (蓝+绿) / Cyan (Blue + Green)
FINGERPRINT_LED_COLOR_RED = 0x04, // 红灯 / Red
FINGERPRINT_LED_COLOR_PURPLE = 0x05, // 紫色灯 (蓝+红) / Purple (Blue + Red)
FINGERPRINT_LED_COLOR_YELLOW = 0x06, // 黄色灯 (绿+红) / Yellow (Green + Red)
FINGERPRINT_LED_COLOR_WHITE = 0x07 // 白色灯 (蓝+绿+红) / White (Blue + Green + Red)
} fingerprint_led_color_t; PS_ControlBLNで設定した内容は電源OFFで保存されません。#include <Arduino.h>
#include <M5UnitFingerprint2.hpp>
#include <M5Unified.hpp>
M5Canvas canvas(&M5.Lcd);
M5UnitFingerprint2 fp2(&Serial1, 17, 18); // Initialize fingerprint sensor
void setup() {
Serial.begin(115200);
M5.begin();
fp2.begin();// Hardware Interface Init
canvas.createSprite(320, 240);
canvas.fillScreen(TFT_BLACK);
canvas.setTextColor(TFT_WHITE);
canvas.setFont(&fonts::FreeMonoBold9pt7b);
// Activate the fingerprint module (prepares it to accept commands; must required)
if (fp2.PS_ActivateFingerprintModule() == FINGERPRINT_OK) { // Software-based activation, ready to receive commands
canvas.drawString("Fingerprint2 Ready", 2, 45);
Serial.printf("Fingerprint2 Ready\n");
} else {
canvas.drawString("Fingerprint2 Init Failed", 2, 45);
Serial.printf("Fingerprint2 Init Failed\n");
}
canvas.pushSprite(0, 0);
}
void loop() {
fp2.PS_ControlBLN(FINGERPRINT_LED_BREATHING, FINGERPRINT_LED_COLOR_GREEN, FINGERPRINT_LED_COLOR_BLUE, 0); /// 0-endless loop, N-loop N times
delay(2000);
fp2.PS_ControlBLN(FINGERPRINT_LED_FLASHING, FINGERPRINT_LED_COLOR_RED, FINGERPRINT_LED_COLOR_RED, 0); /// 0-endless loop, N-loop N times
delay(2000);
fp2.PS_ControlBLN(FINGERPRINT_LED_FADE_IN, FINGERPRINT_LED_COLOR_CYAN, FINGERPRINT_LED_COLOR_CYAN, 0);
delay(2000);
fp2.PS_ControlBLN(FINGERPRINT_LED_FADE_OUT, FINGERPRINT_LED_COLOR_YELLOW, FINGERPRINT_LED_COLOR_YELLOW, 0);
delay(2000);
fp2.PS_ControlBLN(FINGERPRINT_LED_ON, FINGERPRINT_LED_COLOR_PURPLE, FINGERPRINT_LED_COLOR_PURPLE, 0);
delay(2000);
} #include <Arduino.h>
#include <M5UnitFingerprint2.hpp>
#include <M5Unified.hpp>
M5Canvas canvas(&M5.Lcd);
int fingerPresentCount = 0; // Counter for consecutive finger detection
M5UnitFingerprint2 fp2(&Serial1, 17, 18); // Fingerprint sensor
bool displayFingerprintImage(M5UnitFingerprint2& fp2, uint32_t maxBufferSize, M5Canvas& canvas,
int displayX, int displayY, uint8_t rotation);
void setup() {
Serial.begin(115200);
M5.begin();
fp2.begin();
canvas.createSprite(320, 240);
canvas.fillScreen(TFT_BLACK);
canvas.setTextColor(TFT_WHITE, TFT_BLACK);
canvas.setFont(&fonts::FreeMonoBold9pt7b);
canvas.drawString("Unit Fingerprint2 Image", 2, 0);
Serial.println("<-------Unit Fingerprint2 Image------->");
canvas.drawLine(0, 20, 320, 20, TFT_WHITE);
// Activate fingerprint sensor module
if (fp2.PS_ActivateFingerprintModule() == FINGERPRINT_OK) {
canvas.drawString("Fingerprint2 Ready", 2, 45);
canvas.drawString("Please place finger......", 2, 75);
Serial.printf("Fingerprint2 Ready\n");
} else {
canvas.drawString("Fingerprint2 Init Failed", 2, 45);
Serial.printf("Fingerprint2 Init Failed\n");
}
canvas.pushSprite(0, 0);
}
void loop() {
M5.update();
delay(200); // Light delay to reduce CPU usage
fingerprint_status_t result = fp2.PS_GetImage();
// PS_GetImage can be replaced by PS_GetImageInfo to further verify the quality of the fingerprint image.
if (result == FINGERPRINT_OK) {
fingerPresentCount++;
Serial.printf("Finger detected! Count: %d/3\n", fingerPresentCount);
canvas.fillRect(0, 41, 320, 240, TFT_BLACK);
canvas.setCursor(2, 60);
canvas.printf("Finger detected! Count: %d/3\n", fingerPresentCount);
canvas.pushSprite(0, 0);
// Show fingerprint image after 3 consecutive detections
if (fingerPresentCount >= 3) {
Serial.println("Entering displayFingerprintImage.");
if (displayFingerprintImage(fp2, 1024 * 16, canvas, 56, 100, 1)) {
Serial.println("Fingerprint image displayed successfully.");
delay(1000);
} else {
Serial.println("Failed to display fingerprint image.");
}
canvas.pushSprite(0, 0);
fingerPresentCount = 0; // Reset count
}
} else {
// No finger detected, reset count
if (fingerPresentCount > 0) {
Serial.println("Finger removed, resetting count.");
fingerPresentCount = 0;
}
}
}
bool displayFingerprintImage(M5UnitFingerprint2& fp2, uint32_t maxBufferSize, M5Canvas& canvas,
int displayX, int displayY, uint8_t rotation) {
// Allocate buffer for image
uint8_t* imageBuffer = (uint8_t*)malloc(maxBufferSize);
if (imageBuffer == nullptr) {
Serial.println("Failed to allocate memory for image buffer.");
canvas.setCursor(2, 60);
canvas.printf("Memory allocation failed");
return false;
}
// Upload image data from sensor
uint32_t actualImageSize = 0;
fingerprint_status_t result = fp2.PS_UpImage(imageBuffer, maxBufferSize, actualImageSize);
if (result == FINGERPRINT_OK) {
Serial.printf("Image uploaded successfully, size: %d bytes\r\n", actualImageSize);
// Display image info on canvas
canvas.fillRect(0, 41, 320, 240, TFT_BLACK);
canvas.setCursor(2, 60);
canvas.printf("Image size: %d bytes", actualImageSize);
if (actualImageSize > 0) {
const int imageWidth = 80;
const int imageHeight = 208;
for (int y = 0; y < imageHeight && y < 220; y++) { // Limit height
for (int x = 0; x < imageWidth && x < 200; x++) { // Limit width
int byteIndex = (y * imageWidth + x) / 2;
if (byteIndex < actualImageSize) {
// Extract 4-bit pixel value
uint8_t pixelValue;
if ((y * imageWidth + x) % 2 == 0) {
pixelValue = imageBuffer[byteIndex] & 0x0F;
} else {
pixelValue = (imageBuffer[byteIndex] & 0xF0) >> 4;
}
// Map 4-bit to grayscale RGB565
uint8_t grayValue = pixelValue * 17; // Scale to 0-255
uint16_t rgb565 = ((grayValue >> 3) << 11) | ((grayValue >> 2) << 5) | (grayValue >> 3);
// Compute rotated pixel position
int drawX, drawY;
switch (rotation) {
case 0: // No rotation
drawX = displayX + x; drawY = displayY + y; break;
case 1: // 90 degrees clockwise
drawX = displayX + imageHeight - 1 - y; drawY = displayY + x; break;
case 2: // 180 degrees
drawX = displayX + imageWidth - 1 - x; drawY = displayY + imageHeight - 1 - y; break;
case 3: // 270 degrees (counterclockwise)
drawX = displayX + y; drawY = displayY + imageWidth - 1 - x; break;
default: // Default: 90 degrees clockwise
drawX = displayX + imageHeight - 1 - y; drawY = displayY + x; break;
}
canvas.drawPixel(drawX, drawY, rgb565);
}
}
}
}
free(imageBuffer);
return true;
} else {
Serial.println("Failed to upload image.");
canvas.setCursor(2, 60);
canvas.printf("Failed to upload image");
free(imageBuffer);
return false;
}
}本サンプルは自動登録方式(PS_AutoEnroll関数を使用)を採用しています。ユーザーは指をセンサーに置くだけで、システムが自動的に画像取得・特徴抽出・テンプレート生成を行い、最終的に指紋テンプレートをモジュール内のデータベースに保存します。段階的に登録したい場合は、Fingerprint2 シリアル通信プロトコルを参照し、PS_GetImage、PS_GenChar、PS_RegModel、PS_StoreCharなどの関数を使用してください。
関数プロトタイプ:
fingerprint_status_t PS_AutoEnroll(
uint16_t ID,
uint8_t enrollCount,
fingerprint_auto_enroll_flags_t flags,
uint8_t* param1 = nullptr,
uint8_t* param2= nullptr,
PS_AutoEnrollCallback_t callback = nullptr
) const; パラメータ:
ID:指紋のユニークID(0~99)。enrollCount:登録時に取得する指紋サンプル数。有効値は1~6。値が大きいほどテンプレートの信頼性が高まりますが、登録時間も長くなります。flags:登録オプション。ビットごとに組み合わせ可能。詳細はfingerprint_auto_enroll_flags_tを参照。param1、param2:オプションの出力パラメータ。param1 -- ステージコード、param2 -- ステータス/エラーコード。詳細は下記ps_auto_enroll_param1_t/fingerprint_auto_enroll_stage_t、ps_auto_enroll_param2_tを参照。callback:コールバック関数(オプション)。各ステージ完了時に呼び出されます(PS_AutoEnroll使用時は複数回呼び出されます)。詳細はライブラリ内のPS_AutoEnroll定義を参照。戻り値:
FINGERPRINT_OK:成功fingerprint_status_tを参照。関数プロトタイプ:
bool PS_AutoEnroll_callback(
uint16_t ID,
fingerprint_status_t confirmationCode,
uint8_t param1,
uint8_t param2,
int packetCount
) const; パラメータ:
ID:現在登録中の指紋ID。confirmationCode:現在のステージのステータスコード。FINGERPRINT_OKは成功。詳細はライブラリのfingerprint_status_tを参照。param1:現在のステージコード。詳細はps_auto_enroll_param1_tを参照。param2:現在のステータス/エラーコード。詳細はps_auto_enroll_param2_tを参照。packetCount:コールバック関数が呼び出された回数(現在までに処理されたデータパケット数)。0からカウント。関連定義:
fingerprint_auto_enroll_flags_t
typedef enum {
FINGERPRINT_AUTO_ENROLL_DEFAULT = 0x0000, // 默认设置 / Default setting
FINGERPRINT_AUTO_ENROLL_NO_STATUS_RETURN = (1 << 2), // 注册过程中不返回当前状态 / Don't return current status during enrollment
FINGERPRINT_AUTO_ENROLL_ALLOW_OVERWRITE_ID = (1 << 3), // 允许覆盖已存在的ID号 / Allow overwriting existing ID
FINGERPRINT_AUTO_ENROLL_FORBID_DUPLICATES = (1 << 4), // 禁止指纹重复注册 / Forbid duplicate fingerprint enrollment
FINGERPRINT_AUTO_ENROLL_NO_LIFT_REQUIRED = (1 << 5), // 采集间不要求手指离开 / No finger lift required between captures
} fingerprint_auto_enroll_flags_t; ps_auto_enroll_param1_t
typedef enum : uint8_t {
PS_AUTO_ENROLL_PARAM1_LEGAL_CHECK = 0x00, // 指纹合法性检测 / Fingerprint legality check
PS_AUTO_ENROLL_PARAM1_GET_IMAGE = 0x01, // 获取图像 / Get image
PS_AUTO_ENROLL_PARAM1_GEN_CHAR = 0x02, // 生成特征 / Generate characteristics
PS_AUTO_ENROLL_PARAM1_LIFT_FINGER = 0x03, // 判断手指离开 / Check finger lift
PS_AUTO_ENROLL_PARAM1_MERGE_TEMPLATE= 0x04, // 合并模板 / Merge template
PS_AUTO_ENROLL_PARAM1_VERIFY = 0x05, // 注册验证 / Enrollment verification
PS_AUTO_ENROLL_PARAM1_STORE = 0x06 // 存储模板 / Store template
} ps_auto_enroll_param1_t; ps_auto_enroll_param2_t
typedef enum : uint8_t {
PS_AUTO_ENROLL_PARAM2_OK = 0x00, // 指纹合法性检测 / Fingerprint legality check
PS_AUTO_ENROLL_PARAM2_MERGE_TEMPLATE = 0xF0, // 合并模板 / Merge template
PS_AUTO_ENROLL_PARAM2_FINGER_DUPLICATED = 0xF1, // 检验该手指是否已注册 / Check if finger is already registered
PS_AUTO_ENROLL_PARAM2_STORE_TEMPLATE = 0xF2, // 存储模板 / Store template
} ps_auto_enroll_param2_t; 下記サンプルではコールバック関数を使って現在の登録プロセスの状態を取得し、情報をフィードバックします。
#include <Arduino.h>
#include <M5UnitFingerprint2.hpp>
#include <M5Unified.hpp>
M5Canvas canvas(&M5.Lcd);
M5UnitFingerprint2 fp2(&Serial1, 17, 18); // Initialize fingerprint sensor
uint16_t enrollID = 0; // Unique ID for the fingerprint being enrolled (range: 0~99, cycles after 99)
const uint8_t enrollCount = 3; // Number of fingerprint samples needed to create a reliable template (3 = standard)
bool waitingForTouch = true; // Flag to track if the system is waiting for a screen touch to start enrollment
void setup() {
Serial.begin(115200);
M5.begin();
fp2.begin();
canvas.createSprite(320, 240);
canvas.fillScreen(TFT_BLACK);
canvas.setTextColor(TFT_WHITE);
canvas.setFont(&fonts::FreeMonoBold9pt7b);
canvas.drawString("Unit Fingerprint2 Enroll", 2, 0);
Serial.println("<-------Unit Fingerprint2 Enroll------->");
canvas.drawLine(0, 20, 320, 20, TFT_WHITE);
// Activate the fingerprint module (prepares it to accept commands; required before enrollment/verification)
if (fp2.PS_ActivateFingerprintModule() == FINGERPRINT_OK) { // Software-based activation
canvas.drawString("Fingerprint2 Ready", 2, 45);
Serial.printf("Fingerprint2 Ready\n");
} else {
canvas.drawString("Fingerprint2 Init Failed", 2, 45);
Serial.printf("Fingerprint2 Init Failed\n");
}
// Set sensor work mode: 1 = Always-on (sensor stays active), 0 = Timed sleep (auto-sleeps to save power)
fp2.PS_SetWorkMode(1);
fp2.PS_Empty();// Clear all fingerprint database
// Prompt user to touch the screen to start fingerprint enrollment
canvas.drawString("Touch screen to enroll", 2, 70);
canvas.pushSprite(0, 0); // Update LCD with all canvas content (renders drawn elements)
Serial.println("Waiting for touch to start enrollment..."); // Debug message for user action
}
void loop() {
M5.update();
if (waitingForTouch) {
if (M5.Touch.getCount() && M5.Touch.getDetail().wasPressed()) {
waitingForTouch = false;
canvas.fillRect(0, 70, 320, 170, TFT_BLACK);
canvas.setCursor(2, 70);
canvas.printf("Enrolling Fingerprint ID: %d", enrollID);
canvas.drawString("Place finger to enroll...", 10, 90);
canvas.pushSprite(0, 0);
Serial.printf("Start enrolling fingerprint, ID=%d. Please place your finger...\n", enrollID);
uint8_t param1 = 0, param2 = 0;
// Start automatic enrollment:
// Parameters: ID, sample count, flags (overwrite existing ID + no finger lift needed), output params, callback
fingerprint_status_t result = fp2.PS_AutoEnroll(
enrollID, enrollCount,
(fingerprint_auto_enroll_flags_t)(FINGERPRINT_AUTO_ENROLL_ALLOW_OVERWRITE_ID |
FINGERPRINT_AUTO_ENROLL_NO_LIFT_REQUIRED),
¶m1, ¶m2, PS_AutoEnroll_callback);
canvas.fillRect(0, 90, 320, 150, TFT_BLACK);
if (result == FINGERPRINT_OK) {
canvas.setCursor(2, 100);
canvas.printf("ID:%d Enroll Success!", enrollID);
Serial.printf("Fingerprint enrolled successfully! ID=%d\n", enrollID);
enrollID = (enrollID + 1) % 100;
} else {
canvas.drawString("Enroll Failed!", 2, 100);
Serial.println("Fingerprint enrollment failed!");
}
canvas.drawString("Touch screen to enroll next", 10, 130);
canvas.pushSprite(0, 0);
waitingForTouch = true;
delay(200);
}
}
delay(20);
}
// Callback function for PS_AutoEnroll: updates status during each enrollment stage (runs automatically)
// Returns true to continue enrollment, false to abort (based on success of current stage)
bool PS_AutoEnroll_callback(uint16_t ID, fingerprint_status_t confirmationCode, uint8_t param1, uint8_t param2, int packetCount) {
static int enrollStep = 0; // Static variable: tracks current sample step (persists between callback calls)
switch (param1) {
// Stage 1: Capture fingerprint image from sensor
case FINGERPRINT_AUTO_ENROLL_GET_IMAGE:
if (confirmationCode == FINGERPRINT_OK) {
enrollStep++; // Increment step after successful image capture
canvas.setCursor(10, 90);
canvas.fillRect(0, 90, 320, 150, TFT_BLACK); // Clear previous status
canvas.printf("#%d:Image acquired success", enrollStep); // Show step success
Serial.printf("#%d:Image acquired success\n", enrollStep); // Debug step success
}
break;
// Stage 2: Extract fingerprint features (converts image to digital template data)
case FINGERPRINT_AUTO_ENROLL_GEN_CHAR:
if (confirmationCode == FINGERPRINT_OK) {
canvas.setCursor(10, 110);
canvas.printf("#%d:Feature generated success", enrollStep); // Show feature success
Serial.printf("#%d:Feature generated success\n", enrollStep); // Debug feature success
}
break;
// Stage 3: Merge multiple feature samples into a single, reliable template
case FINGERPRINT_AUTO_ENROLL_MERGE_TEMPLATE:
if (confirmationCode == FINGERPRINT_OK) {
canvas.setCursor(10, 130);
canvas.printf("Template merged success"); // Show merge success
Serial.println("Template merged success"); // Debug merge success
}
break;
// Stage 4: Verify merged template (ensures template is valid for future recognition)
case FINGERPRINT_AUTO_ENROLL_VERIFY:
if (confirmationCode == FINGERPRINT_OK) {
canvas.setCursor(10, 150);
canvas.printf("Template verified success"); // Show verification success
Serial.println("Template verified success"); // Debug verification success
}
break;
// Stage 5: Save verified template to sensor memory (links to enrollment ID)
case FINGERPRINT_AUTO_ENROLL_STORE_TEMPLATE:
if (confirmationCode == FINGERPRINT_OK) {
canvas.setCursor(10, 170);
canvas.printf("Template stored success,ID=%d", ID); // Show storage success + ID
Serial.printf("Template stored success,ID=%d\n", ID); // Debug storage success
enrollStep = 0; // Reset step counter for next enrollment
}
break;
default:
break; // Ignore unrecognized stages
}
canvas.pushSprite(0, 0);
return (confirmationCode == FINGERPRINT_OK); // Continue enrollment only if current stage succeeded
} 本サンプルは自動認証方式(PS_AutoIdentify関数を使用)を採用しています。ユーザーは指をセンサーに置くだけで、システムが自動的に画像取得・特徴抽出・テンプレート照合を行い、最終的にマッチング結果を返します。段階的に認証したい場合は、Fingerprint2 シリアル通信プロトコルを参照し、PS_GetImage、PS_GenChar、PS_Searchなどの関数を使用してください。
関数プロトタイプ:
fingerprint_status_t PS_AutoIdentify(
uint8_t securityLevel,
uint16_t ID,
fingerprint_auto_verify_flags_t flags,
uint16_t& matchedID,
PS_AutoIdentifyCallback_t callback = nullptr
) const; パラメータ:
securityLevel:セキュリティレベル。0または1。値が大きいほどマッチングが厳しくなります。ID:認証対象の指紋ID範囲。0xFFFFは全登録指紋を対象、他の値は指定IDのみ比較。flags:認証オプション。ビットごとに組み合わせ可能。詳細は下記fingerprint_auto_verify_flags_tを参照。matchedID:出力パラメータ。マッチした指紋IDを返します。callback:コールバック関数(オプション)。各ステージ完了時に複数回呼び出され、認証進捗のリアルタイムフィードバックに利用できます。戻り値:
FINGERPRINT_OK:認証成功fingerprint_status_tを参照。bool PS_AutoIdentify_callback(
uint8_t securityLevel,
fingerprint_status_t confirmationCode,
uint8_t param,
uint16_t matchedID,
uint16_t matchScore,
int packetCount
); パラメータ:
securityLevel:PS_AutoIdentifyに渡したパラメータと同じ。confirmationCode:現在のステージのステータスコード。FINGERPRINT_OKは成功。詳細はライブラリのfingerprint_status_tを参照。param:現在のステージコード。詳細は下記ps_auto_identify_param_tを参照。matchedID:出力パラメータ。マッチした指紋IDを返します。matchScore:出力パラメータ。マッチスコアを返します。値が大きいほど一致度が高いです。packetCount:コールバック関数が呼び出された回数(現在までに処理されたデータパケット数)。0からカウント。関連定義:
fingerprint_auto_verify_flags_ttypedef enum {
FINGERPRINT_AUTO_VERIFY_DEFAULT = 0x0000, // 默认设置 / Default setting
FINGERPRINT_AUTO_VERIFY_NO_STATUS_RETURN = (1 << 2), // 验证过程中不返回当前状态 / Don't return current status during verification
} fingerprint_auto_verify_flags_t; ps_auto_identify_param_ttypedef enum {
PS_AUTO_IDENTIFY_PARAM_LEGAL_CHECK = 0x00, // 指纹合法性检测 / Fingerprint legality check
PS_AUTO_IDENTIFY_PARAM_GET_IMAGE = 0x01, // 获取图像 / Get image
PS_AUTO_IDENTIFY_PARAM_VERIFY = 0x05, // 已注册指纹比对 / Registered fingerprint matching
} ps_auto_identify_param_t; 下記サンプルではコールバック関数を使って現在の認証状態を取得し、情報をフィードバックします。
#include <Arduino.h>
#include <M5UnitFingerprint2.hpp>
#include <M5Unified.hpp>
M5Canvas canvas(&M5.Lcd);
M5UnitFingerprint2 fp2(&Serial1, 17, 18); // Initialize fingerprint sensor
void setup() {
Serial.begin(115200);
M5.begin();
fp2.begin();
canvas.createSprite(320, 240);
canvas.fillScreen(TFT_BLACK);
canvas.setTextColor(TFT_WHITE);
canvas.setFont(&fonts::FreeMonoBold9pt7b);
canvas.drawString("Unit Fingerprint2 Identify", 2, 0);
Serial.println("<-------Unit Fingerprint2 Identify------->");
canvas.drawLine(0, 20, 320, 20, TFT_WHITE);
if (fp2.PS_ActivateFingerprintModule() == FINGERPRINT_OK) {
canvas.drawString("Fingerprint2 Ready", 2, 45);
Serial.printf("Fingerprint2 Ready\n");
} else {
canvas.drawString("Fingerprint2 Init Failed", 2, 45);
Serial.printf("Fingerprint2 Init Failed\n");
}
fp2.PS_SetWorkMode(1);
canvas.pushSprite(0, 0);
}
void loop() {
M5.update();
canvas.fillRect(0, 70, 320, 170, TFT_BLACK);
canvas.setCursor(2, 70);
canvas.drawString("Place finger to identify...", 10, 90);
canvas.pushSprite(0, 0);
Serial.println("Start identifying fingerprint. Please place your finger...");
uint16_t matchedID = 0;
// Start automatic identification:
// Parameters: security level(0 or 1), ID, flags, output matchedID, callback
fingerprint_status_t result = fp2.PS_AutoIdentify(
0, 0xFFFF, FINGERPRINT_AUTO_VERIFY_DEFAULT,
matchedID, PS_AutoIdentify_callback);
canvas.fillRect(0, 90, 320, 150, TFT_BLACK);
if (result == FINGERPRINT_OK) {
canvas.setCursor(2, 100);
canvas.printf("Identify Success! ID:%d", matchedID);
Serial.printf("Fingerprint identified! ID=%d\n", matchedID);
delay(1000);
} else {
canvas.drawString("Identify Failed!", 2, 100);
Serial.println("Fingerprint identification failed!");
}
canvas.pushSprite(0, 0);
delay(20);
}
// Callback function for PS_AutoIdentify: updates status during each identification stage
bool PS_AutoIdentify_callback(uint8_t securityLevel, fingerprint_status_t confirmationCode, uint8_t param, uint16_t matchedID, uint16_t matchScore, int packetCount) {
switch (param) {
// Stage 1: Capture fingerprint image
case PS_AUTO_IDENTIFY_PARAM_GET_IMAGE:
if (confirmationCode == FINGERPRINT_OK) {
canvas.setCursor(10, 90);
canvas.fillRect(0, 90, 320, 150, TFT_BLACK);
canvas.printf("Image acquired success");
Serial.println("Image acquired success");
}
break;
// Stage 2: Matching fingerprint
case PS_AUTO_IDENTIFY_PARAM_VERIFY:
if (confirmationCode == FINGERPRINT_OK) {
canvas.setCursor(10, 110);
canvas.printf("Match ID:%d Score:%d", matchedID, matchScore);
Serial.printf("Match ID:%d Score:%d\n", matchedID, matchScore);
} else {
canvas.setCursor(10, 110);
canvas.printf("No Fingerprint Matched");
Serial.println("No Fingerprint Matched");
}
break;
default:
break;
}
canvas.pushSprite(0, 0);
delay(500);
return (confirmationCode == FINGERPRINT_OK);
} 本指紋モジュールはID指定による指紋テンプレートの削除のみサポートしています。削除前にIDを認証で取得する必要があります。全ての指紋テンプレートを消去したい場合はPS_Empty関数を使用してください。
#include <Arduino.h>
#include <M5UnitFingerprint2.hpp>
#include <M5Unified.hpp>
M5Canvas canvas(&M5.Lcd);
M5UnitFingerprint2 fp2(&Serial1, 17, 18); // Initialize fingerprint sensor
void setup() {
Serial.begin(115200);
M5.begin();
fp2.begin();
canvas.createSprite(320, 240);
canvas.fillScreen(TFT_BLACK);
canvas.setTextColor(TFT_WHITE);
canvas.setFont(&fonts::FreeMonoBold9pt7b);
canvas.drawString("Unit Fingerprint2 Delete", 2, 0);
Serial.println("<-------Unit Fingerprint2 Delete------->");
canvas.drawLine(0, 20, 320, 20, TFT_WHITE);
if (fp2.PS_ActivateFingerprintModule() == FINGERPRINT_OK) {
canvas.drawString("Fingerprint2 Ready", 2, 45);
Serial.printf("Fingerprint2 Ready\n");
} else {
canvas.drawString("Fingerprint2 Init Failed", 2, 45);
Serial.printf("Fingerprint2 Init Failed\n");
}
fp2.PS_SetWorkMode(1);
fp2.PS_ControlBLN(FINGERPRINT_LED_BREATHING, FINGERPRINT_LED_COLOR_BLUE, FINGERPRINT_LED_COLOR_PURPLE, 0); /// 0-endless loop, N-loop N times
canvas.pushSprite(0, 0);
}
void loop() {
M5.update();
canvas.fillRect(0, 70, 320, 170, TFT_BLACK);
canvas.setCursor(2, 70);
canvas.drawString("Place finger to delete...", 10, 90);
canvas.pushSprite(0, 0);
Serial.println("Please place your finger...");
uint16_t matchedID = 0;
// Start automatic identification:
// Parameters: security level(0 or 1), ID, flags, output matchedID
fingerprint_status_t result = fp2.PS_AutoIdentify(
0, 0xFFFF, FINGERPRINT_AUTO_VERIFY_DEFAULT,
matchedID);
canvas.fillRect(0, 90, 320, 150, TFT_BLACK);
if (result == FINGERPRINT_OK) {
canvas.setCursor(2, 100);
canvas.printf("Identified ID:%d", matchedID);
Serial.printf("Identified ID:%d", matchedID);
// Delete the matched fingerprint
fingerprint_status_t delResult = fp2.PS_DeletChar(matchedID, 1);
if (delResult == FINGERPRINT_OK) {
canvas.setCursor(2, 120);
canvas.printf("Deleted ID:%d Success!", matchedID);
Serial.printf("Deleted fingerprint ID=%d Success!\n", matchedID);
} else {
canvas.setCursor(2, 120);
canvas.printf("Delete ID:%d Failed!", matchedID);
Serial.printf("Delete fingerprint ID=%d Failed!\n", matchedID);
}
} else {
canvas.drawString("Identify Failed!", 2, 100);
Serial.println("Fingerprint identification failed!");
}
canvas.pushSprite(0, 0);
delay(2000);
} ダウンロードモード:デバイスごとに書き込み前にダウンロードモードへ入る必要があります。手順は主制御デバイスによって異なります。詳細はArduino IDE入門ガイドページ下部のデバイス書き込み手順リストを参照してください。
CoreS3の場合、リセットボタンを約2秒長押しし、内部の緑色LEDが点灯したら離します。この状態でデバイスはダウンロードモードに入り、書き込み待機状態となります。

Enroll Successなどのメッセージが表示されます。Identify Successなどのメッセージが表示されます。Deleted ID:X Successなどのメッセージが表示されます。