Fingerprint2 Unit

该库是 Unit Fingerprint2 的驱动程序。

支持以下产品:

Unit Fingerprint2

UiFlow2 应用示例

注册并识别

在 UiFlow2 中打开 m5cores3_fp2_basic_example.m5f2 项目。

该示例演示如何使用指纹识别模块完成指纹录入、识别和删除的完整流程。

UiFlow2 代码块:

m5cores3_fp2_basic_example.png

示例输出:

None

上传和下载模板

在 UiFlow2 中打开 m5cores3_fp2_template_upload_download_example.m5f2 项目。

该示例演示如何使用指纹识别模块完成指纹录入、识别、删除以及模板上传/下载的完整流程。(上传和下载功能支持跨设备指纹识别 —— 在一个模块上录入的指纹可在另一个模块上进行验证。指纹模板传输方式可根据用户需求自定义,例如通过串口通信、网络或云端同步。)

UiFlow2 代码块:

m5cores3_fp2_template_upload_download_example.png

示例输出:

None

上传并显示指纹图像

在 UiFlow2 中打开 m5cores3_fp2_upload_image_example.m5f2 项目。

该示例演示如何上传并显示指纹图像。

UiFlow2 代码块:

m5cores3_fp2_upload_image_example.png

示例输出:

None

MicroPython 应用示例

注册并识别

该示例演示如何使用指纹识别模块完成指纹录入、识别和删除的完整流程。

MicroPython 代码块:

  1# SPDX-FileCopyrightText: 2025 M5Stack Technology CO LTD
  2#
  3# SPDX-License-Identifier: MIT
  4
  5import os, sys, io
  6import M5
  7from M5 import *
  8import m5ui
  9import lvgl as lv
 10import time
 11from unit import Fingerprint2Unit
 12
 13
 14page0 = None
 15btn_enroll = None
 16btn_recognize = None
 17btn_delete = None
 18label0 = None
 19label_tip = None
 20label_res = None
 21fingerprint2_0 = None
 22id2 = None
 23count = None
 24operation = None
 25i = None
 26g_id = None
 27res = None
 28
 29
 30def wait_for_finger_press():
 31    global \
 32        id2, \
 33        count, \
 34        operation, \
 35        i, \
 36        g_id, \
 37        res, \
 38        page0, \
 39        btn_enroll, \
 40        btn_recognize, \
 41        btn_delete, \
 42        label0, \
 43        label_tip, \
 44        label_res, \
 45        fingerprint2_0
 46    label_tip.set_text(str("Please place your finger"))
 47    while not (fingerprint2_0.get_enroll_image()):
 48        time.sleep_ms(100)
 49    Speaker.tone(888, 100)
 50
 51
 52def wait_for_finger_left():
 53    global \
 54        id2, \
 55        count, \
 56        operation, \
 57        i, \
 58        g_id, \
 59        res, \
 60        page0, \
 61        btn_enroll, \
 62        btn_recognize, \
 63        btn_delete, \
 64        label0, \
 65        label_tip, \
 66        label_res, \
 67        fingerprint2_0
 68    label_tip.set_text(str("Please remove your finger"))
 69    while fingerprint2_0.get_enroll_image():
 70        time.sleep_ms(100)
 71
 72
 73def enroll(id2, count):
 74    global \
 75        operation, \
 76        i, \
 77        g_id, \
 78        res, \
 79        page0, \
 80        btn_enroll, \
 81        btn_recognize, \
 82        btn_delete, \
 83        label0, \
 84        label_tip, \
 85        label_res, \
 86        fingerprint2_0
 87    label_res.set_text(str(""))
 88    i = 0
 89    while i < count:
 90        wait_for_finger_press()
 91        if fingerprint2_0.gen_feature():
 92            i = (i if isinstance(i, (int, float)) else 0) + 1
 93            print(i)
 94        wait_for_finger_left()
 95    if fingerprint2_0.gen_template():
 96        if fingerprint2_0.store_template(g_id):
 97            label_res.set_text(str((str((str("Enroll ID: ") + str(g_id))) + str(" success!"))))
 98            operation = 0
 99            label_tip.set_text(str(""))
100            if g_id < 98:
101                g_id = (g_id if isinstance(g_id, (int, float)) else 0) + 1
102            Speaker.tone(666, 100)
103
104
105def recognize():
106    global \
107        id2, \
108        count, \
109        operation, \
110        i, \
111        g_id, \
112        res, \
113        page0, \
114        btn_enroll, \
115        btn_recognize, \
116        btn_delete, \
117        label0, \
118        label_tip, \
119        label_res, \
120        fingerprint2_0
121    label_res.set_text(str(""))
122    label_tip.set_text(str("Please place your finger"))
123    while not (fingerprint2_0.get_verify_image()):
124        time.sleep_ms(100)
125    label_tip.set_text(str(""))
126    if fingerprint2_0.gen_feature():
127        res = fingerprint2_0.find_match()
128        if res:
129            id2 = res[0]
130            label_res.set_text(str((str("Recognize ID: ") + str(id2))))
131            Speaker.tone(666, 100)
132            operation = 0
133    if operation != 0:
134        operation = 0
135        label_res.set_text(str("Recognize failed! "))
136        Speaker.tone(999, 200)
137
138
139def delete(id2):
140    global \
141        count, \
142        operation, \
143        i, \
144        g_id, \
145        res, \
146        page0, \
147        btn_enroll, \
148        btn_recognize, \
149        btn_delete, \
150        label0, \
151        label_tip, \
152        label_res, \
153        fingerprint2_0
154    label_res.set_text(str(""))
155    if g_id > 0:
156        g_id = (g_id if isinstance(g_id, (int, float)) else 0) + -1
157    if fingerprint2_0.delete_template(g_id):
158        label_res.set_text(str((str("Delete ID: ") + str(g_id))))
159    else:
160        label_res.set_text(str("Delete failed!"))
161        Speaker.tone(999, 200)
162    operation = 0
163
164
165def btn_enroll_clicked_event(event_struct):
166    global \
167        page0, \
168        btn_enroll, \
169        btn_recognize, \
170        btn_delete, \
171        label0, \
172        label_tip, \
173        label_res, \
174        fingerprint2_0, \
175        operation, \
176        i, \
177        g_id, \
178        count, \
179        res, \
180        id2
181    operation = 1
182    Speaker.tone(888, 100)
183
184
185def btn_recognize_clicked_event(event_struct):
186    global \
187        page0, \
188        btn_enroll, \
189        btn_recognize, \
190        btn_delete, \
191        label0, \
192        label_tip, \
193        label_res, \
194        fingerprint2_0, \
195        operation, \
196        i, \
197        g_id, \
198        count, \
199        res, \
200        id2
201    operation = 2
202    Speaker.tone(888, 100)
203
204
205def btn_delete_clicked_event(event_struct):
206    global \
207        page0, \
208        btn_enroll, \
209        btn_recognize, \
210        btn_delete, \
211        label0, \
212        label_tip, \
213        label_res, \
214        fingerprint2_0, \
215        operation, \
216        i, \
217        g_id, \
218        count, \
219        res, \
220        id2
221    Speaker.tone(888, 100)
222    operation = 3
223
224
225def btn_enroll_event_handler(event_struct):
226    global \
227        page0, \
228        btn_enroll, \
229        btn_recognize, \
230        btn_delete, \
231        label0, \
232        label_tip, \
233        label_res, \
234        fingerprint2_0, \
235        operation, \
236        i, \
237        g_id, \
238        count, \
239        res, \
240        id2
241    event = event_struct.code
242    if event == lv.EVENT.CLICKED and True:
243        btn_enroll_clicked_event(event_struct)
244    return
245
246
247def btn_recognize_event_handler(event_struct):
248    global \
249        page0, \
250        btn_enroll, \
251        btn_recognize, \
252        btn_delete, \
253        label0, \
254        label_tip, \
255        label_res, \
256        fingerprint2_0, \
257        operation, \
258        i, \
259        g_id, \
260        count, \
261        res, \
262        id2
263    event = event_struct.code
264    if event == lv.EVENT.CLICKED and True:
265        btn_recognize_clicked_event(event_struct)
266    return
267
268
269def btn_delete_event_handler(event_struct):
270    global \
271        page0, \
272        btn_enroll, \
273        btn_recognize, \
274        btn_delete, \
275        label0, \
276        label_tip, \
277        label_res, \
278        fingerprint2_0, \
279        operation, \
280        i, \
281        g_id, \
282        count, \
283        res, \
284        id2
285    event = event_struct.code
286    if event == lv.EVENT.CLICKED and True:
287        btn_delete_clicked_event(event_struct)
288    return
289
290
291def setup():
292    global \
293        page0, \
294        btn_enroll, \
295        btn_recognize, \
296        btn_delete, \
297        label0, \
298        label_tip, \
299        label_res, \
300        fingerprint2_0, \
301        operation, \
302        i, \
303        g_id, \
304        count, \
305        res, \
306        id2
307
308    M5.begin()
309    Widgets.setRotation(1)
310    m5ui.init()
311    page0 = m5ui.M5Page(bg_c=0xFFFFFF)
312    btn_enroll = m5ui.M5Button(
313        text="enroll",
314        x=14,
315        y=165,
316        bg_c=0x2196F3,
317        text_c=0xFFFFFF,
318        font=lv.font_montserrat_14,
319        parent=page0,
320    )
321    btn_recognize = m5ui.M5Button(
322        text="recognize",
323        x=109,
324        y=165,
325        bg_c=0x2196F3,
326        text_c=0xFFFFFF,
327        font=lv.font_montserrat_14,
328        parent=page0,
329    )
330    btn_delete = m5ui.M5Button(
331        text="delete",
332        x=229,
333        y=165,
334        bg_c=0x2196F3,
335        text_c=0xFFFFFF,
336        font=lv.font_montserrat_14,
337        parent=page0,
338    )
339    label0 = m5ui.M5Label(
340        "Fingerprint enroll, recognize, delete",
341        x=14,
342        y=9,
343        text_c=0x0F6DD1,
344        bg_c=0xFFFFFF,
345        bg_opa=0,
346        font=lv.font_montserrat_16,
347        parent=page0,
348    )
349    label_tip = m5ui.M5Label(
350        "Tip:",
351        x=46,
352        y=61,
353        text_c=0x000000,
354        bg_c=0xFFFFFF,
355        bg_opa=0,
356        font=lv.font_montserrat_16,
357        parent=page0,
358    )
359    label_res = m5ui.M5Label(
360        "Result:",
361        x=20,
362        y=95,
363        text_c=0x000000,
364        bg_c=0xFFFFFF,
365        bg_opa=0,
366        font=lv.font_montserrat_16,
367        parent=page0,
368    )
369
370    btn_enroll.add_event_cb(btn_enroll_event_handler, lv.EVENT.ALL, None)
371    btn_recognize.add_event_cb(btn_recognize_event_handler, lv.EVENT.ALL, None)
372    btn_delete.add_event_cb(btn_delete_event_handler, lv.EVENT.ALL, None)
373
374    page0.screen_load()
375    Speaker.begin()
376    Speaker.setVolumePercentage(0.5)
377    fingerprint2_0 = Fingerprint2Unit(2, port=(1, 2))
378    fingerprint2_0.activate_module()
379    fingerprint2_0.set_work_mode(1, save=False)
380    btn_enroll.set_size(80, 60)
381    btn_enroll.align_to(page0, lv.ALIGN.CENTER, -105, 60)
382    btn_recognize.set_size(100, 60)
383    btn_recognize.align_to(page0, lv.ALIGN.CENTER, 0, 60)
384    btn_delete.set_size(80, 60)
385    btn_delete.align_to(page0, lv.ALIGN.CENTER, 105, 60)
386    operation = 0
387    g_id = 0
388
389
390def loop():
391    global \
392        page0, \
393        btn_enroll, \
394        btn_recognize, \
395        btn_delete, \
396        label0, \
397        label_tip, \
398        label_res, \
399        fingerprint2_0, \
400        operation, \
401        i, \
402        g_id, \
403        count, \
404        res, \
405        id2
406    M5.update()
407    if operation == 1:
408        enroll(1, 5)
409    elif operation == 2:
410        recognize()
411    elif operation == 3:
412        delete(1)
413    else:
414        pass
415
416
417if __name__ == "__main__":
418    try:
419        setup()
420        while True:
421            loop()
422    except (Exception, KeyboardInterrupt) as e:
423        try:
424            m5ui.deinit()
425            from utility import print_error_msg
426
427            print_error_msg(e)
428        except ImportError:
429            print("please update to latest firmware")

示例输出:

None

上传和下载模板

该示例演示如何使用指纹识别模块完成指纹录入、识别、删除以及模板上传/下载的完整流程。(上传和下载功能支持跨设备指纹识别 —— 在一个模块上录入的指纹可在另一个模块上进行验证。指纹模板传输方式可根据用户需求自定义,例如通过串口通信、网络或云端同步。)

MicroPython 代码块:

  1# SPDX-FileCopyrightText: 2025 M5Stack Technology CO LTD
  2#
  3# SPDX-License-Identifier: MIT
  4
  5import os, sys, io
  6import M5
  7from M5 import *
  8import m5ui
  9import lvgl as lv
 10import time
 11from unit import Fingerprint2Unit
 12
 13
 14page0 = None
 15btn_enroll = None
 16btn_upload = None
 17btn_recognize = None
 18btn_download = None
 19btn_delete = None
 20label0 = None
 21label_tip = None
 22label_res = None
 23fingerprint2_0 = None
 24id2 = None
 25count = None
 26operation = None
 27i = None
 28g_id = None
 29res = None
 30
 31
 32def wait_for_finger_press():
 33    global \
 34        id2, \
 35        count, \
 36        operation, \
 37        i, \
 38        g_id, \
 39        res, \
 40        page0, \
 41        btn_enroll, \
 42        btn_upload, \
 43        btn_recognize, \
 44        btn_download, \
 45        btn_delete, \
 46        label0, \
 47        label_tip, \
 48        label_res, \
 49        fingerprint2_0
 50    label_tip.set_text(str("Please place your finger"))
 51    while not (fingerprint2_0.get_enroll_image()):
 52        time.sleep_ms(100)
 53    Speaker.tone(888, 100)
 54
 55
 56def wait_for_finger_left():
 57    global \
 58        id2, \
 59        count, \
 60        operation, \
 61        i, \
 62        g_id, \
 63        res, \
 64        page0, \
 65        btn_enroll, \
 66        btn_upload, \
 67        btn_recognize, \
 68        btn_download, \
 69        btn_delete, \
 70        label0, \
 71        label_tip, \
 72        label_res, \
 73        fingerprint2_0
 74    label_tip.set_text(str("Please remove your finger"))
 75    while fingerprint2_0.get_enroll_image():
 76        time.sleep_ms(100)
 77
 78
 79def enroll(id2, count):
 80    global \
 81        operation, \
 82        i, \
 83        g_id, \
 84        res, \
 85        page0, \
 86        btn_enroll, \
 87        btn_upload, \
 88        btn_recognize, \
 89        btn_download, \
 90        btn_delete, \
 91        label0, \
 92        label_tip, \
 93        label_res, \
 94        fingerprint2_0
 95    label_res.set_text(str(""))
 96    i = 0
 97    while i < count:
 98        wait_for_finger_press()
 99        if fingerprint2_0.gen_feature():
100            i = (i if isinstance(i, (int, float)) else 0) + 1
101            print(i)
102        wait_for_finger_left()
103    if fingerprint2_0.gen_template():
104        if fingerprint2_0.store_template(g_id):
105            label_res.set_text(str((str((str("Enroll ID: ") + str(g_id))) + str(" success!"))))
106            operation = 0
107            label_tip.set_text(str(""))
108            if g_id < 98:
109                g_id = (g_id if isinstance(g_id, (int, float)) else 0) + 1
110            Speaker.tone(666, 100)
111
112
113def upload():
114    global \
115        id2, \
116        count, \
117        operation, \
118        i, \
119        g_id, \
120        res, \
121        page0, \
122        btn_enroll, \
123        btn_upload, \
124        btn_recognize, \
125        btn_download, \
126        btn_delete, \
127        label0, \
128        label_tip, \
129        label_res, \
130        fingerprint2_0
131    label_res.set_text(str(""))
132    if fingerprint2_0.load_template(0):
133        label_tip.set_text(str("template uploading..."))
134        if fingerprint2_0.upload_template("/flash/res/tp1.tzh"):
135            label_tip.set_text(str(""))
136            label_res.set_text(str((str((str("Upload ID: ") + str(0))) + str(" success!"))))
137            Speaker.tone(666, 100)
138        else:
139            label_res.set_text(str((str((str("Upload ID: ") + str(0))) + str("failed!"))))
140            Speaker.tone(999, 200)
141    else:
142        label_res.set_text(str("load template failed!"))
143        Speaker.tone(999, 200)
144    operation = 0
145
146
147def recognize():
148    global \
149        id2, \
150        count, \
151        operation, \
152        i, \
153        g_id, \
154        res, \
155        page0, \
156        btn_enroll, \
157        btn_upload, \
158        btn_recognize, \
159        btn_download, \
160        btn_delete, \
161        label0, \
162        label_tip, \
163        label_res, \
164        fingerprint2_0
165    label_res.set_text(str(""))
166    label_tip.set_text(str("Please place your finger"))
167    while not (fingerprint2_0.get_verify_image()):
168        time.sleep_ms(100)
169    label_tip.set_text(str(""))
170    if fingerprint2_0.gen_feature():
171        res = fingerprint2_0.find_match()
172        if res:
173            id2 = res[0]
174            label_res.set_text(str((str("Recognize ID: ") + str(id2))))
175            Speaker.tone(666, 100)
176            operation = 0
177    if operation != 0:
178        operation = 0
179        label_res.set_text(str("Recognize failed! "))
180        Speaker.tone(999, 200)
181
182
183def download():
184    global \
185        id2, \
186        count, \
187        operation, \
188        i, \
189        g_id, \
190        res, \
191        page0, \
192        btn_enroll, \
193        btn_upload, \
194        btn_recognize, \
195        btn_download, \
196        btn_delete, \
197        label0, \
198        label_tip, \
199        label_res, \
200        fingerprint2_0
201    label_res.set_text(str(""))
202    label_tip.set_text(str("download template"))
203    if fingerprint2_0.download_template("/flash/res/tp1.tzh"):
204        label_res.set_text(str("Download template success!"))
205        if fingerprint2_0.store_template(66):
206            operation = 0
207            label_tip.set_text(str("store template"))
208            label_res.set_text(str("Store template success!"))
209            Speaker.tone(666, 100)
210        else:
211            label_res.set_text(str("Store template failed!"))
212            Speaker.tone(999, 200)
213    else:
214        label_res.set_text(str("download template failed!"))
215        Speaker.tone(999, 200)
216    operation = 0
217
218
219def delete(id2):
220    global \
221        count, \
222        operation, \
223        i, \
224        g_id, \
225        res, \
226        page0, \
227        btn_enroll, \
228        btn_upload, \
229        btn_recognize, \
230        btn_download, \
231        btn_delete, \
232        label0, \
233        label_tip, \
234        label_res, \
235        fingerprint2_0
236    label_res.set_text(str(""))
237    if g_id > 0:
238        g_id = (g_id if isinstance(g_id, (int, float)) else 0) + -1
239    if fingerprint2_0.delete_template(g_id):
240        label_res.set_text(str((str("Delete ID: ") + str(g_id))))
241    else:
242        label_res.set_text(str("Delete failed!"))
243        Speaker.tone(999, 200)
244    operation = 0
245
246
247def btn_enroll_clicked_event(event_struct):
248    global \
249        page0, \
250        btn_enroll, \
251        btn_upload, \
252        btn_recognize, \
253        btn_download, \
254        btn_delete, \
255        label0, \
256        label_tip, \
257        label_res, \
258        fingerprint2_0, \
259        operation, \
260        i, \
261        g_id, \
262        count, \
263        res, \
264        id2
265    operation = 1
266    Speaker.tone(888, 100)
267
268
269def btn_recognize_clicked_event(event_struct):
270    global \
271        page0, \
272        btn_enroll, \
273        btn_upload, \
274        btn_recognize, \
275        btn_download, \
276        btn_delete, \
277        label0, \
278        label_tip, \
279        label_res, \
280        fingerprint2_0, \
281        operation, \
282        i, \
283        g_id, \
284        count, \
285        res, \
286        id2
287    operation = 2
288    Speaker.tone(888, 100)
289
290
291def btn_delete_clicked_event(event_struct):
292    global \
293        page0, \
294        btn_enroll, \
295        btn_upload, \
296        btn_recognize, \
297        btn_download, \
298        btn_delete, \
299        label0, \
300        label_tip, \
301        label_res, \
302        fingerprint2_0, \
303        operation, \
304        i, \
305        g_id, \
306        count, \
307        res, \
308        id2
309    Speaker.tone(888, 100)
310    operation = 3
311
312
313def btn_upload_clicked_event(event_struct):
314    global \
315        page0, \
316        btn_enroll, \
317        btn_upload, \
318        btn_recognize, \
319        btn_download, \
320        btn_delete, \
321        label0, \
322        label_tip, \
323        label_res, \
324        fingerprint2_0, \
325        operation, \
326        i, \
327        g_id, \
328        count, \
329        res, \
330        id2
331    operation = 4
332    Speaker.tone(888, 100)
333
334
335def btn_download_clicked_event(event_struct):
336    global \
337        page0, \
338        btn_enroll, \
339        btn_upload, \
340        btn_recognize, \
341        btn_download, \
342        btn_delete, \
343        label0, \
344        label_tip, \
345        label_res, \
346        fingerprint2_0, \
347        operation, \
348        i, \
349        g_id, \
350        count, \
351        res, \
352        id2
353    operation = 5
354    Speaker.tone(888, 100)
355
356
357def btn_enroll_event_handler(event_struct):
358    global \
359        page0, \
360        btn_enroll, \
361        btn_upload, \
362        btn_recognize, \
363        btn_download, \
364        btn_delete, \
365        label0, \
366        label_tip, \
367        label_res, \
368        fingerprint2_0, \
369        operation, \
370        i, \
371        g_id, \
372        count, \
373        res, \
374        id2
375    event = event_struct.code
376    if event == lv.EVENT.CLICKED and True:
377        btn_enroll_clicked_event(event_struct)
378    return
379
380
381def btn_recognize_event_handler(event_struct):
382    global \
383        page0, \
384        btn_enroll, \
385        btn_upload, \
386        btn_recognize, \
387        btn_download, \
388        btn_delete, \
389        label0, \
390        label_tip, \
391        label_res, \
392        fingerprint2_0, \
393        operation, \
394        i, \
395        g_id, \
396        count, \
397        res, \
398        id2
399    event = event_struct.code
400    if event == lv.EVENT.CLICKED and True:
401        btn_recognize_clicked_event(event_struct)
402    return
403
404
405def btn_delete_event_handler(event_struct):
406    global \
407        page0, \
408        btn_enroll, \
409        btn_upload, \
410        btn_recognize, \
411        btn_download, \
412        btn_delete, \
413        label0, \
414        label_tip, \
415        label_res, \
416        fingerprint2_0, \
417        operation, \
418        i, \
419        g_id, \
420        count, \
421        res, \
422        id2
423    event = event_struct.code
424    if event == lv.EVENT.CLICKED and True:
425        btn_delete_clicked_event(event_struct)
426    return
427
428
429def btn_upload_event_handler(event_struct):
430    global \
431        page0, \
432        btn_enroll, \
433        btn_upload, \
434        btn_recognize, \
435        btn_download, \
436        btn_delete, \
437        label0, \
438        label_tip, \
439        label_res, \
440        fingerprint2_0, \
441        operation, \
442        i, \
443        g_id, \
444        count, \
445        res, \
446        id2
447    event = event_struct.code
448    if event == lv.EVENT.CLICKED and True:
449        btn_upload_clicked_event(event_struct)
450    return
451
452
453def btn_download_event_handler(event_struct):
454    global \
455        page0, \
456        btn_enroll, \
457        btn_upload, \
458        btn_recognize, \
459        btn_download, \
460        btn_delete, \
461        label0, \
462        label_tip, \
463        label_res, \
464        fingerprint2_0, \
465        operation, \
466        i, \
467        g_id, \
468        count, \
469        res, \
470        id2
471    event = event_struct.code
472    if event == lv.EVENT.CLICKED and True:
473        btn_download_clicked_event(event_struct)
474    return
475
476
477def setup():
478    global \
479        page0, \
480        btn_enroll, \
481        btn_upload, \
482        btn_recognize, \
483        btn_download, \
484        btn_delete, \
485        label0, \
486        label_tip, \
487        label_res, \
488        fingerprint2_0, \
489        operation, \
490        i, \
491        g_id, \
492        count, \
493        res, \
494        id2
495
496    M5.begin()
497    Widgets.setRotation(1)
498    m5ui.init()
499    page0 = m5ui.M5Page(bg_c=0xFFFFFF)
500    btn_enroll = m5ui.M5Button(
501        text="enroll",
502        x=14,
503        y=165,
504        bg_c=0x2196F3,
505        text_c=0xFFFFFF,
506        font=lv.font_montserrat_14,
507        parent=page0,
508    )
509    btn_upload = m5ui.M5Button(
510        text="upload",
511        x=45,
512        y=106,
513        bg_c=0x2196F3,
514        text_c=0xFFFFFF,
515        font=lv.font_montserrat_14,
516        parent=page0,
517    )
518    btn_recognize = m5ui.M5Button(
519        text="recognize",
520        x=109,
521        y=165,
522        bg_c=0x2196F3,
523        text_c=0xFFFFFF,
524        font=lv.font_montserrat_14,
525        parent=page0,
526    )
527    btn_download = m5ui.M5Button(
528        text="download",
529        x=186,
530        y=108,
531        bg_c=0x2196F3,
532        text_c=0xFFFFFF,
533        font=lv.font_montserrat_14,
534        parent=page0,
535    )
536    btn_delete = m5ui.M5Button(
537        text="delete",
538        x=229,
539        y=165,
540        bg_c=0x2196F3,
541        text_c=0xFFFFFF,
542        font=lv.font_montserrat_14,
543        parent=page0,
544    )
545    label0 = m5ui.M5Label(
546        "Fingerprint enroll, recognize, delete",
547        x=14,
548        y=9,
549        text_c=0x0F6DD1,
550        bg_c=0xFFFFFF,
551        bg_opa=0,
552        font=lv.font_montserrat_16,
553        parent=page0,
554    )
555    label_tip = m5ui.M5Label(
556        "Tip:",
557        x=38,
558        y=35,
559        text_c=0x000000,
560        bg_c=0xFFFFFF,
561        bg_opa=0,
562        font=lv.font_montserrat_16,
563        parent=page0,
564    )
565    label_res = m5ui.M5Label(
566        "Result:",
567        x=12,
568        y=56,
569        text_c=0x000000,
570        bg_c=0xFFFFFF,
571        bg_opa=0,
572        font=lv.font_montserrat_16,
573        parent=page0,
574    )
575
576    btn_enroll.add_event_cb(btn_enroll_event_handler, lv.EVENT.ALL, None)
577    btn_recognize.add_event_cb(btn_recognize_event_handler, lv.EVENT.ALL, None)
578    btn_delete.add_event_cb(btn_delete_event_handler, lv.EVENT.ALL, None)
579    btn_upload.add_event_cb(btn_upload_event_handler, lv.EVENT.ALL, None)
580    btn_download.add_event_cb(btn_download_event_handler, lv.EVENT.ALL, None)
581
582    page0.screen_load()
583    Speaker.begin()
584    Speaker.setVolumePercentage(0.5)
585    fingerprint2_0 = Fingerprint2Unit(2, port=(1, 2))
586    while not (fingerprint2_0.is_connected()):
587        time.sleep_ms(500)
588        print(".")
589    fingerprint2_0.activate_module()
590    fingerprint2_0.set_work_mode(1, save=False)
591    print(fingerprint2_0.get_firmware_version())
592    btn_upload.set_size(80, 60)
593    btn_upload.align_to(page0, lv.ALIGN.CENTER, -60, 0)
594    btn_download.set_size(80, 60)
595    btn_download.align_to(page0, lv.ALIGN.CENTER, 60, 0)
596    btn_enroll.set_size(80, 60)
597    btn_enroll.align_to(page0, lv.ALIGN.CENTER, -105, 70)
598    btn_recognize.set_size(100, 60)
599    btn_recognize.align_to(page0, lv.ALIGN.CENTER, 0, 70)
600    btn_delete.set_size(80, 60)
601    btn_delete.align_to(page0, lv.ALIGN.CENTER, 105, 70)
602    operation = 0
603    g_id = 0
604
605
606def loop():
607    global \
608        page0, \
609        btn_enroll, \
610        btn_upload, \
611        btn_recognize, \
612        btn_download, \
613        btn_delete, \
614        label0, \
615        label_tip, \
616        label_res, \
617        fingerprint2_0, \
618        operation, \
619        i, \
620        g_id, \
621        count, \
622        res, \
623        id2
624    M5.update()
625    if operation == 1:
626        enroll(1, 5)
627    elif operation == 2:
628        recognize()
629    elif operation == 3:
630        delete(1)
631    elif operation == 4:
632        upload()
633    elif operation == 5:
634        download()
635    else:
636        pass
637
638
639if __name__ == "__main__":
640    try:
641        setup()
642        while True:
643            loop()
644    except (Exception, KeyboardInterrupt) as e:
645        try:
646            m5ui.deinit()
647            from utility import print_error_msg
648
649            print_error_msg(e)
650        except ImportError:
651            print("please update to latest firmware")

示例输出:

None

上传并显示指纹图像

该示例演示如何上传并显示指纹图像。

MicroPython 代码块:

  1# SPDX-FileCopyrightText: 2025 M5Stack Technology CO LTD
  2#
  3# SPDX-License-Identifier: MIT
  4
  5import os, sys, io
  6import M5
  7from M5 import *
  8import m5ui
  9import lvgl as lv
 10from unit import Fingerprint2Unit
 11import time
 12
 13
 14page0 = None
 15canvas0 = None
 16btn_upload = None
 17label0 = None
 18fingerprint2_0 = None
 19upload = None
 20fpimg = None
 21
 22
 23# Describe this function...
 24def upload_image():
 25    global upload, fpimg, page0, canvas0, btn_upload, label0, fingerprint2_0
 26    Speaker.tone(666, 100)
 27    label0.set_text(str("Please press finger"))
 28    while not (fingerprint2_0.get_enroll_image()):
 29        print(".")
 30        time.sleep_ms(1000)
 31    label0.set_text(str("Uploading..."))
 32    fpimg = fingerprint2_0.upload_image(to_rgb565=True, byte_order=True)
 33    if fpimg:
 34        Speaker.tone(666, 100)
 35        label0.set_text(str("Upload image finished!"))
 36        canvas0.set_buffer(fpimg, 80, 208, lv.COLOR_FORMAT.RGB565)
 37        upload = False
 38    else:
 39        Speaker.tone(888, 200)
 40        label0.set_text(str("Upload image failed!"))
 41    upload = False
 42
 43
 44def btn_upload_clicked_event(event_struct):
 45    global page0, canvas0, btn_upload, label0, fingerprint2_0, upload, fpimg
 46    upload = True
 47
 48
 49def btn_upload_event_handler(event_struct):
 50    global page0, canvas0, btn_upload, label0, fingerprint2_0, upload, fpimg
 51    event = event_struct.code
 52    if event == lv.EVENT.CLICKED and True:
 53        btn_upload_clicked_event(event_struct)
 54    return
 55
 56
 57def setup():
 58    global page0, canvas0, btn_upload, label0, fingerprint2_0, upload, fpimg
 59    M5.begin()
 60    Widgets.setRotation(1)
 61    m5ui.init()
 62    page0 = m5ui.M5Page(bg_c=0xFFFFFF)
 63    canvas0 = m5ui.M5Canvas(
 64        x=115,
 65        y=25,
 66        w=80,
 67        h=208,
 68        color_format=lv.COLOR_FORMAT.ARGB8888,
 69        bg_c=0xC9C9C9,
 70        bg_opa=255,
 71        parent=page0,
 72    )
 73    btn_upload = m5ui.M5Button(
 74        text="upload",
 75        x=216,
 76        y=144,
 77        bg_c=0x2196F3,
 78        text_c=0xFFFFFF,
 79        font=lv.font_montserrat_14,
 80        parent=page0,
 81    )
 82    label0 = m5ui.M5Label(
 83        "tip",
 84        x=6,
 85        y=3,
 86        text_c=0x000000,
 87        bg_c=0xFFFFFF,
 88        bg_opa=0,
 89        font=lv.font_montserrat_16,
 90        parent=page0,
 91    )
 92    btn_upload.add_event_cb(btn_upload_event_handler, lv.EVENT.ALL, None)
 93    fingerprint2_0 = Fingerprint2Unit(2, port=(1, 2))
 94    page0.screen_load()
 95    Speaker.begin()
 96    Speaker.setVolumePercentage(0.8)
 97    btn_upload.set_size(80, 60)
 98    upload = True
 99    upload_image()
100
101
102def loop():
103    global page0, canvas0, btn_upload, label0, fingerprint2_0, upload, fpimg
104    M5.update()
105    if upload:
106        upload_image()
107
108
109if __name__ == "__main__":
110    try:
111        setup()
112        while True:
113            loop()
114    except (Exception, KeyboardInterrupt) as e:
115        try:
116            m5ui.deinit()
117            from utility import print_error_msg
118
119            print_error_msg(e)
120        except ImportError:
121            print("please update to latest firmware")

示例输出:

None

API参考

Fingerprint2Unit

class unit.fingerprint2.Fingerprint2Unit(id=2, port=None, debug=False)

基类:object

参数:
get_verify_image()

采集指纹图像用于验证。

返回:

如果指纹图像已成功采集,则返回 True,否则返回 False。

返回类型:

bool

UiFlow2 代码块:

get_verify_image.png

MicroPython 代码块:

unit_fp2_0.get_verify_image()
get_enroll_image()

采集用于注册的指纹图像。

返回:

如果指纹图像已成功采集,则返回 True,否则返回 False。

返回类型:

bool

UiFlow2 代码块:

get_enroll_image.png

MicroPython 代码块:

unit_fp2_0.get_enroll_image()
gen_feature()

生成人脸指纹特征。

将存储在图像缓冲区中的原始指纹图像转换为特征文件,然后将其存储在模板缓冲区中。

返回:

如果指纹特征生成成功则返回 True,否则返回 False。

返回类型:

bool

UiFlow2 代码块:

gen_feature.png

MicroPython 代码块:

unit_fp2_0.gen_feature()
gen_template()

合并指纹特征以生成模板。

将两个指纹特征文件合并为一个指纹模板。

返回:

如果指纹模板生成成功则返回 True,否则返回 False。

返回类型:

bool

UiFlow2 代码块:

gen_template.png

MicroPython 代码块:

unit_fp2_0.gen_template()
store_template(id)

将指纹模板存储到 Flash 内存中。

将生成的指纹模板存储到 flash 内存中指定的 ID。

参数:

id (int) – 存储位置 ID(范围:0 ~ 99)

返回:

如果存储成功则为 True,否则为 False。

返回类型:

bool

UiFlow2 代码块:

store_template.png

MicroPython 代码块:

unit_fp2_0.store_template(id)
load_template(id)

从 flash 内存加载指纹模板。

从 flash 存储器中将指定 ID 的指纹模板加载到模板缓冲区中。

参数:

id (int) – 要加载的指纹模板 ID

返回:

如果加载模板成功,则为 True。

返回类型:

bool

UiFlow2 代码块:

load_template.png

MicroPython 代码块:

unit_fp2_0.load_template(id)
delete_template(id)

从 flash 内存中删除指纹模板。

从 flash 存储中删除指定 ID 的指纹模板。

参数:

id (int) – 要删除的指纹模板 ID

返回:

如果删除成功则为 True,否则为 False

返回类型:

bool

UiFlow2 代码块:

delete_template.png

MicroPython 代码块:

unit_fp2_0.delete_template(id)
delete_all_template()

清除指纹数据库。

删除指纹数据库中存储的所有指纹模板。

返回:

如果删除成功则为 True,否则为 False

返回类型:

bool

UiFlow2 代码块:

delete_all_template.png

MicroPython 代码块:

unit_fp2_0.delete_all_template()
upload_template(save_path='template.tzh', log=False)

上传指纹模板并保存到指定路径

将存储在模板缓冲区中的模板上传到主控制器。

参数:

path (str) – 保存上传模板的文件路径

返回:

如果上传模板成功,则为 True。

返回类型:

bool

UiFlow2 代码块:

upload_template.png

MicroPython 代码块:

unit_fp2_0.upload_template(path)
download_template(filepath='template.tzh')

下载模板。

从文件系统读取指纹模板并将其下载到指纹模块。

参数:

path (str) – 指纹模板文件的路径

返回:

如果下载模板成功,则为 True。

返回类型:

bool

UiFlow2 代码块:

download_template.png

MicroPython 代码块:

unit_fp2_0.download_template(path)
upload_image(to_rgb565=True, byte_order=True)

从模块上传指纹图像。

从模块上传 4 位灰度指纹图像(尺寸:80x208)。可选地,将原始图像转换为适合显示的 RGB565 格式。

参数:
  • to_rgb565 (bool) – 是否将原始图像转换为 RGB565(默认 True)

  • byte_order (bool) – 如果转换为 RGB565,请将 little-endian 字节序设置为 True,或将 big-endian 设置为 False。默认值为 True。

返回:

指纹图像数据,类型为 bytearray。失败时返回 None。

返回类型:

bytearray | None

UiFlow2 代码块:

upload_image.png

MicroPython 代码块:

img_buf = unit_fp2_0.upload_image(to_rgb565=True, byte_order=True)
get_valid_template_num()

获取有效指纹模板的数量。

返回当前存储在指纹数据库中的指纹模板数量。

返回:

有效指纹模板数量

返回类型:

int

UiFlow2 代码块:

get_valid_template_num.png

MicroPython 代码块:

unit_fp2_0.get_valid_template_num()
get_stored_template_id()

从指纹传感器获取已存储的指纹模板 ID 列表。

该函数向指纹传感器查询其模板索引映射(用于表示数据库中已占用(已使用)的模板槽位),并返回这些已占用 ID 的列表。

返回:

已占用的指纹模板 ID 列表;如果获取失败,则返回 None。

返回类型:

list[int] | None

UiFlow2 代码块:

get_stored_template_id.png

MicroPython 代码块:

stored_ids = get_stored_template_id(sensor)
find_match()

在数据库中搜索匹配的指纹。

将模板缓冲区中存储的指纹特征与数据库中存储的模板进行比较。

返回:

  • (id, score):包含匹配到的指纹 ID 和匹配得分的元组。

  • None:如果未找到匹配的指纹。

UiFlow2 代码块:

find_match.png

MicroPython 代码块:

unit_fp2_0.find_match()
match()

精确匹配两个指纹特征。

比较两个指纹特征文件,并返回结果和分数。

返回:

匹配的相似度得分

返回类型:

int

UiFlow2 代码块:

match.png

MicroPython 代码块:

unit_fp2_0.match()
is_connected()

检查指纹模块是否已连接。

返回:

如果模块已连接则为 True,否则为 False。

返回类型:

bool

UiFlow2 代码块:

is_connected.png

MicroPython 代码块:

unit_fp2_0.is_connected()
activate_module()

激活该模块。

UiFlow2 代码块:

activate_module.png

MicroPython 代码块:

unit_fp2_0.activate_module()
返回类型:

None

set_work_mode(mode=0, save=False)

设置工作模式。

参数:
  • mode (int) – 工作模式(0:自动休眠,1:始终开启)。

  • save (bool) – 是否将设置保存到设备。默认值为 False。

返回类型:

None

UiFlow2 代码块:

set_work_mode.png

MicroPython 代码块:

unit_fp2_0.set_work_mode(mode, save)
get_work_mode()

获取当前工作模式。

返回模块当前的工作模式:
  • 0:自动睡眠模式

  • 1:常亮模式

返回:

当前工作模式

返回类型:

int

UiFlow2 代码块:

get_work_mode.png

MicroPython 代码块:

mode = unit_fp2_0.get_work_mode()
set_auto_sleep_time(time_s=10, save=False)

设置休眠超时时间。

该参数仅在 “Auto Sleep Mode” 中生效。它用于确定指纹模块在未接收到任何命令时的等待时长,超过该时长后将进入睡眠模式,并开始监测指纹按压。

参数:
  • time_s (int) – 自动休眠超时时间,单位为秒。范围:10~254。

  • save (bool) – 是否将此配置保存到 flash。

返回类型:

None

UiFlow2 代码块:

set_auto_sleep_time.png

MicroPython 代码块:

unit_fp2_0.set_auto_sleep_time(30, save=True)
get_auto_sleep_time()

获取自动休眠时间。

该值仅在 “Timed Sleep Mode” 中有效。它表示模块在未接收到命令的情况下,进入休眠状态前将等待多长时间。

返回:

自动睡眠时间(秒)

返回类型:

int

UiFlow2 代码块:

get_auto_sleep_time.png

MicroPython 代码块:

sleep_time = unit_fp2_0.get_auto_sleep_time()
get_work_status()

获取指纹模块工作状态。

返回:

如果处于活动状态则为 True,否则为 False

返回类型:

bool

UiFlow2 代码块:

get_work_status.png

MicroPython 代码块:

status = unit_fp2_0.get_work_status()
get_firmware_version()

获取固件版本。

返回:

固件版本号

返回类型:

int

UiFlow2 代码块:

get_firmware_version.png

MicroPython 代码块:

version = unit_fp2_0.get_firmware_version()
set_led_breath(start_color, end_color, repeat)

设置 LED 呼吸模式。

参数:
  • start_color (int) – 起始颜色(bit0:蓝色,bit1:绿色,bit2:红色)

  • end_color (int) – 结束颜色(bit0:蓝色,bit1:绿色,bit2:红色)

  • repeat (int) – 循环次数(0=无限)

返回:

如果命令执行成功则为 True,否则为 False

返回类型:

bool

Color codes:
  • 0x00:全部关闭

  • 0x01:蓝色

  • 0x02:绿色

  • 0x03:青色(蓝色 + 绿色)

  • 0x04:红色

  • 0x05:品红(红 + 蓝)

  • 0x06:黄色(红色 + 绿色)

  • 0x07:白色(红色 + 绿色 + 蓝色)

UiFlow2 代码块:

set_led_breath.png

MicroPython 代码块:

# Blue breathing light, 5 cycles
unit_fp2_0.set_led_breath(0x01, 0x01, 5)

# Red to white breathing light, infinite cycles
unit_fp2_0.set_led_breath(0x04, 0x07, 0)
set_led_color(color)

设置 LED 颜色。

参数:

color (int) – LED 颜色(0:始终关闭,其他值:以指定颜色始终开启)

返回:

如果命令执行成功则为 True,否则为 False

返回类型:

bool

Color codes:
  • 0x00:始终关闭

  • 0x01:蓝色

  • 0x02:绿色

  • 0x03:青色(蓝色 + 绿色)

  • 0x04:红色

  • 0x05:品红(红 + 蓝)

  • 0x06:黄色(红色 + 绿色)

  • 0x07:白色(红色 + 绿色 + 蓝色)

UiFlow2 代码块:

set_led_color.png

MicroPython 代码块:

# Always on white light
unit_fp2_0.set_led_color(0x07)

# Always off (turn off all LEDs)
unit_fp2_0.set_led_color(0x00)

# Always on red light
unit_fp2_0.set_led_color(0x04)