Fingerprint2 Unit

This library is the driver for Unit Fingerprint2.

Support the following products:

Unit Fingerprint2

UiFlow2 Example

Enroll and recognize

Open the m5cores3_fp2_basic_example.m5f2 project in UiFlow2.

This example demonstrates how to use a fingerprint recognition module to perform the complete process of fingerprint enrollment, identification, and deletion.

UiFlow2 Code Block:

m5cores3_fp2_basic_example.png

Example output:

None

Upload and download template

Open the m5cores3_fp2_template_upload_download_example.m5f2 project in UiFlow2.

This example demonstrates how to use a fingerprint recognition module to perform the complete process of fingerprint enrollment, identification, deletion, and template upload/download.(The upload and download functions enable cross-device fingerprint recognition — a fingerprint enrolled on one module can be verified on another. The fingerprint template transfer method can be customized according to user requirements, such as via serial communication, network, or cloud synchronization.)

UiFlow2 Code Block:

m5cores3_fp2_template_upload_download_example.png

Example output:

None

Upload adn display fingerprint image

Open the m5cores3_fp2_upload_image_example.m5f2 project in UiFlow2.

This example demonstrates how to upload and display the fingerprint image.

UiFlow2 Code Block:

m5cores3_fp2_upload_image_example.png

Example output:

None

MicroPython Example

Enroll and recognize

This example demonstrates how to use a fingerprint recognition module to perform the complete process of fingerprint enrollment, identification, and deletion.

MicroPython Code Block:

  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")

Example output:

None

Upload and download template

This example demonstrates how to use a fingerprint recognition module to perform the complete process of fingerprint enrollment, identification, deletion, and template upload/download.(The upload and download functions enable cross-device fingerprint recognition — a fingerprint enrolled on one module can be verified on another. The fingerprint template transfer method can be customized according to user requirements, such as via serial communication, network, or cloud synchronization.)

MicroPython Code Block:

  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")

Example output:

None

Upload adn display fingerprint image

This example demonstrates how to upload and display the fingerprint image.

MicroPython Code Block:

  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")

Example output:

None

API

Fingerprint2Unit

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

Bases: object

Parameters:
get_verify_image()

Capture fingerprint image for verification.

Returns:

True if the fingerprint image was successfully captured, False otherwise.

Return type:

bool

UiFlow2 Code Block:

get_verify_image.png

MicroPython Code Block:

unit_fp2_0.get_verify_image()
get_enroll_image()

Capture fingerprint image for enrollment.

Returns:

True if the fingerprint image was successfully captured, False otherwise.

Return type:

bool

UiFlow2 Code Block:

get_enroll_image.png

MicroPython Code Block:

unit_fp2_0.get_enroll_image()
gen_feature()

Generate fingerprint feature.

Converts the original fingerprint image stored in the image buffer into a feature file, which is then stored in the template buffer.

Returns:

True if the fingerprint feature was successfully generate, False otherwise.

Return type:

bool

UiFlow2 Code Block:

gen_feature.png

MicroPython Code Block:

unit_fp2_0.gen_feature()
gen_template()

Merge fingerprint features to generate a template.

Combines two fingerprint feature files into one fingerprint template.

Returns:

True if the fingerprint template was successfully generate, False otherwise.

Return type:

bool

UiFlow2 Code Block:

gen_template.png

MicroPython Code Block:

unit_fp2_0.gen_template()
store_template(id)

Store fingerprint template into flash memory.

Stores the generated fingerprint template into flash memory at the specified ID.

Parameters:

id (int) – Storage location ID (range: 0 ~ 99)

Returns:

True if storage successful False otherwise.

Return type:

bool

UiFlow2 Code Block:

store_template.png

MicroPython Code Block:

unit_fp2_0.store_template(id)
load_template(id)

Load fingerprint template from flash memory.

Loads the fingerprint template with the specified ID from flash memory into the template buffer.

Parameters:

id (int) – ID of the fingerprint template to load

Returns:

True if load template succcessful.

Return type:

bool

UiFlow2 Code Block:

load_template.png

MicroPython Code Block:

unit_fp2_0.load_template(id)
delete_template(id)

Delete fingerprint template from flash memory.

Deletes the fingerprint template with the specified ID from the flash storage.

Parameters:

id (int) – ID of the fingerprint template to delete

Returns:

True if deletion successful, False otherwise

Return type:

bool

UiFlow2 Code Block:

delete_template.png

MicroPython Code Block:

unit_fp2_0.delete_template(id)
delete_all_template()

Clear the fingerprint database.

Deletes all fingerprint templates stored in the fingerprint database.

Returns:

True if deletion successful, False otherwise

Return type:

bool

UiFlow2 Code Block:

delete_all_template.png

MicroPython Code Block:

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

Upload fingerprint template and save to specified path

Uploads the template stored in the template buffer to the host controller.

Parameters:

path (str) – File path to save the uploaded template

Returns:

True if upload template successful.

Return type:

bool

UiFlow2 Code Block:

upload_template.png

MicroPython Code Block:

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

Download template.

Reads the fingerprint template from the file system and downloads it to the fingerprint module.

Parameters:

path (str) – Path to the fingerprint template file

Returns:

True if download template successful.

Return type:

bool

UiFlow2 Code Block:

download_template.png

MicroPython Code Block:

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

Upload fingerprint image from module.

Uploads the 4-bit grayscale fingerprint image from the module (size: 80x208). Optionally, converts the raw image to RGB565 format suitable for display.

Parameters:
  • to_rgb565 (bool) – Whether to convert raw image to RGB565 (default True)

  • byte_order (bool) – If converting to RGB565, set True for little-endian byte order, or False for big-endian. Default is True.

Returns:

Fingerprint image data as bytearray. Returns None on failure.

Return type:

bytearray | None

UiFlow2 Code Block:

upload_image.png

MicroPython Code Block:

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

Get the number of valid fingerprint templates.

Returns the count of fingerprint templates currently stored in the fingerprint database.

Returns:

Number of valid fingerprint templates

Return type:

int

UiFlow2 Code Block:

get_valid_template_num.png

MicroPython Code Block:

unit_fp2_0.get_valid_template_num()
get_stored_template_id()

Get the list of stored fingerprint template IDs from the fingerprint sensor.

This function queries the fingerprint sensor for its template index map, which represents the occupied (used) template slots in the database, and returns the list of those occupied IDs.

Returns:

A list of occupied fingerprint template IDs, or None if retrieval fails.

Return type:

list[int] | None

UiFlow2 Code Block:

get_stored_template_id.png

MicroPython Code Block:

stored_ids = get_stored_template_id(sensor)
find_match()

Search for a matching fingerprint in the database.

Compares the fingerprint features stored in the template buffer with the stored templates in the database.

Returns:

  • (id, score): A tuple of the matched fingerprint ID and match score.

  • None: If no matching fingerprint is found.

UiFlow2 Code Block:

find_match.png

MicroPython Code Block:

unit_fp2_0.find_match()
match()

Precisely match two fingerprint features.

Compares two fingerprint feature files and returns the result and score.

Returns:

Similarity score of the match

Return type:

int

UiFlow2 Code Block:

match.png

MicroPython Code Block:

unit_fp2_0.match()
is_connected()

Check whether the fingerprint module is connected.

Returns:

True if the module is connected, False otherwise.

Return type:

bool

UiFlow2 Code Block:

is_connected.png

MicroPython Code Block:

unit_fp2_0.is_connected()
activate_module()

Activate the module.

UiFlow2 Code Block:

activate_module.png

MicroPython Code Block:

unit_fp2_0.activate_module()
Return type:

None

set_work_mode(mode=0, save=False)

Set the working mode.

Parameters:
  • mode (int) – Working mode (0: Auto sleep, 1: Always-on).

  • save (bool) – Whether to save the setting to the device. Default is False.

Return type:

None

UiFlow2 Code Block:

set_work_mode.png

MicroPython Code Block:

unit_fp2_0.set_work_mode(mode, save)
get_work_mode()

Get the current working mode.

Returns the module’s current working mode:
  • 0: Auto sleep mode

  • 1: Always-on mode

Returns:

Current working mode

Return type:

int

UiFlow2 Code Block:

get_work_mode.png

MicroPython Code Block:

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

Set the sleep timeout.

This parameter is only effective in “Auto Sleep Mode”. It determines how long the fingerprint module waits without receiving any command before it enters sleep mode and starts monitoring for fingerprint press.

Parameters:
  • time_s (int) – Auto sleep timeout in seconds. Range: 10~254.

  • save (bool) – Whether to save this configuration to flash.

Return type:

None

UiFlow2 Code Block:

set_auto_sleep_time.png

MicroPython Code Block:

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

Get auto sleep time.

This value is only valid in “Timed Sleep Mode”. It indicates how long the module will wait without receiving commands before entering sleep state.

Returns:

Auto sleep time in seconds

Return type:

int

UiFlow2 Code Block:

get_auto_sleep_time.png

MicroPython Code Block:

sleep_time = unit_fp2_0.get_auto_sleep_time()
get_work_status()

Get fingerprint module work status.

Returns:

True if active, False otherwise

Return type:

bool

UiFlow2 Code Block:

get_work_status.png

MicroPython Code Block:

status = unit_fp2_0.get_work_status()
get_firmware_version()

Get firmware version.

Returns:

Firmware version number

Return type:

int

UiFlow2 Code Block:

get_firmware_version.png

MicroPython Code Block:

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

Set LED breathing mode.

Parameters:
  • start_color (int) – Start color (bit0: blue, bit1: green, bit2: red)

  • end_color (int) – End color (bit0: blue, bit1: green, bit2: red)

  • repeat (int) – Number of cycles (0=infinite)

Returns:

True if command successful, False otherwise

Return type:

bool

Color codes:
  • 0x00: All off

  • 0x01: Blue

  • 0x02: Green

  • 0x03: Cyan (blue + green)

  • 0x04: Red

  • 0x05: Magenta (red + blue)

  • 0x06: Yellow (red + green)

  • 0x07: White (red + green + blue)

UiFlow2 Code Block:

set_led_breath.png

MicroPython Code Block:

# 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)

Set LED color.

Parameters:

color (int) – LED color (0: always off, other values: always on with specified color)

Returns:

True if command successful, False otherwise

Return type:

bool

Color codes:
  • 0x00: Always off

  • 0x01: Blue

  • 0x02: Green

  • 0x03: Cyan (blue + green)

  • 0x04: Red

  • 0x05: Magenta (red + blue)

  • 0x06: Yellow (red + green)

  • 0x07: White (red + green + blue)

UiFlow2 Code Block:

set_led_color.png

MicroPython Code Block:

# 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)