Example Code for Arduino-Registering Face & Palm Print
FP01 Arduino example with DFRduino UNO R3 and Gravity IO Shield lets you enroll face and palm vein users via UART and the DFRobot_Biometric library, using enrollUser.ino and Serial Monitor at 115200 bps for STEM access control projects
Hardware Preparation
- DFRduino UNO R3 x 1
- Gravity: IO Expansion Shield for Arduino V7.1 x 1
- FP01 Offline AI Vision Recognition Sensor (Face & Palm Vein) x 1
- SH1.0-6Pin to 2.54mm DuPont cable x1
Software Preparation
- Arduino IDE
- Download DFRobot_Biometric library
Wiring Diagram
Other Preparation Work
When registering a face or palm print, the AI vision sensor needs to be fixed in place, and attention should be paid to the recognition distance: 30-60cm for faces and 15-20cm for vein and palm prints.
Instruction 1: Register a face user. The same face can only be registered once.
Instruction 2: Register a vein and palm print user. The same palm print can be registered repeatedly, but only once.
Sample Code
/*!
* @file enrollUser.ino
* @brief Example of face or palm user enrollment for SEN0736 and SEN0737
* @details This example performs user enrollment every time you input the command:1 (enroll face),2 (enroll palm)
* @n and prints the enrollment result through the serial port
* @n Enrollment should work normally as long as the connection is correct
* @copyright Copyright (c) 2026 DFRobot Co.Ltd (http://www.dfrobot.com)
* @license The MIT License (MIT)
* @author [Olive]([email protected])
* @version V1.0.0
* @date 2026-06-02
* @url https://github.com/DFRobot/DFRobot_Biometric
*/
#include "DFRobot_Biometric.h"
/* -----------------------------------------------------------------------------------------------------
* board | MCU | Leonardo/Mega2560/M0 | ESP8266 | ESP32 |
* VCC | 3.3V/5V | VCC | VCC | VCC |
* GND | GND | GND | GND | GND |
* RX | TX | Serial1 TX1 | 5/D6 | Serial2 TX1 |
* TX | RX | Serial1 RX1 | 4/D7 | Serial2 RX1 |
* ----------------------------------------------------------------------------------------------------*/
/* Baud rate cannot be changed , it is 115200 */
#if defined(ESP8266) || defined(ARDUINO_AVR_UNO)
#define SOFT_RX_PIN 4
#define SOFT_TX_PIN 5
#include <SoftwareSerial.h>
SoftwareSerial ModuleSerial(SOFT_RX_PIN, SOFT_TX_PIN);
#elif defined(ESP32)
#define RX_PIN 16
#define TX_PIN 17
#define ModuleSerial Serial2
#else
#define ModuleSerial Serial1
#endif
DFRobot_Biometric face(ModuleSerial);
void setup()
{
#if defined(ESP32)
ModuleSerial.begin(115200, SERIAL_8N1, RX_PIN, TX_PIN);
#else
ModuleSerial.begin(115200);
#endif
Serial.begin(115200); //Start serial 1, for information printing
delay(2000); //Wait for module to start
while (face.checkState() == false) { //Determine whether the module is ready
Serial.println("Module not ready!");
delay(200);
}
Serial.println("Module ready!");
Serial.println("----------------------------------------------------");
Serial.println("Enter the command below through the serial port:");
Serial.println("1 # enroll face user");
Serial.println("2 # enroll palm user");
Serial.println("----------------------------------------------------");
}
uint16_t id;
char faceName[] = "face";
char palmName[] = "palm";
char fullName[20] = { 0 };
DFRobot_Biometric::eIsAdmin_t userclass = face.eRoleNormal;
DFRobot_Biometric::eUserKind_t userKind = face.eFaceUser;
uint16_t i = 1, j = 1;
void loop()
{
char data[11] = { 0 };
int8_t result = 0;
while (!Serial.available()) {
;
}
String input = Serial.readStringUntil('\n');
input.trim();
input.toCharArray(data, 10);
Serial.println("-----------------------------------------------------------------------------------------------");
if (strcmp(data, "1") == 0 || strcmp(data, "2") == 0) {
if (strcmp(data, "1") == 0) {
Serial.println("Start face enrollment. Please keep your face directly facing the camera, 30cm~60cm away");
snprintf(fullName, sizeof(fullName), "%s%d", faceName, i);
userKind = face.eFaceUser;
result = face.enrollUser(userKind, fullName, &id, userclass);
} else {
Serial.println("Start palm enrollment. Please keep your palm directly facing the camera, 15cm~20cm away");
snprintf(fullName, sizeof(fullName), "%s%d", palmName, j);
userKind = face.ePalmUser;
result = face.enrollUser(userKind, fullName, &id, userclass);
}
//Determine the execution result
if (result == 1) {
if (strcmp(data, "1") == 0) {
Serial.println("Face enrollment successful!");
} else {
Serial.println("Palm enrollment successful!");
}
Serial.print("the user id is:");
Serial.println(id);
Serial.print("the user name is:");
Serial.println(fullName);
Serial.print("the user kind is:");
if (userKind == face.eFaceUser) {
Serial.println("face user");
} else if (userKind == face.ePalmUser) {
Serial.println("palm user");
}
Serial.print("the userClass is:");
if (userclass == face.eRoleNormal) {
Serial.println("Normal user");
} else if (userclass == face.eRoleAdmin) {
Serial.println("Administrator");
}
if (strcmp(data, "1") == 0) {
i++;
} else {
j++;
}
} else if (result == 2) {
Serial.println("User already exists");
} else if (result == 3) {
Serial.println("Enrollment timeout");
} else if (result == NO_ACK) {
Serial.println("No response from module");
} else if (result == ERROR) {
Serial.println("Parameter range error");
}
} else {
Serial.println("Error command!");
}
Serial.println("-----------------------------------------------------------------------------------------------");
Serial.println("");
Serial.println("please input next command:");
Serial.println("");
delay(2000);
}
Result
Each registration takes 10 seconds. After successful registration, the corresponding information will be printed. If the registration times out, you can re-register by entering the command. IDs 1-500 are for faces, and IDs 501-800 are for veins and palm prints.
Was this article helpful?
