A universal Arduino fingerprint library supporting multiple sensor types with full memory utilization.
- Multi-Sensor Support: AS608 (162 templates), R307 (1000 templates), GT-511C3 (200 templates), ZFM series
- Auto-Detection: Automatically identifies connected sensor type
- Full Memory Utilization: Uses all available template slots
- Database Management: Complete database scanning and statistics
- Cross-Platform: Works with Arduino, ESP32, ESP8266, Raspberry Pi Pico
- Advanced Features: LED control, security levels, sleep mode
- Professional API: Clean, object-oriented interface with comprehensive error handling
- Multiple Examples: 5 comprehensive examples included
- Complete Documentation: API reference, getting started guide, sensor compatibility
| Sensor Model | Template Capacity | Default Baud | Flash Size | LED Control | Touch Sensor |
|---|---|---|---|---|---|
| AS608 | 162 templates | 57600 bps | 64 KB | β RGB LED | β No |
| R307 | 1000 templates | 57600 bps | 512 KB | β RGB LED | β Yes |
| GT-511C3 | 200 templates | 9600 bps | 128 KB | β Limited | β No |
| ZFM-60 | 300 templates | 57600 bps | 256 KB | β RGB LED | β Yes |
| ZFM-20 | 256 templates | 57600 bps | 128 KB | β Limited | β No |
- Open Arduino IDE
- Go to Tools β Manage Libraries
- Search for "UniversalFingerprint"
- Click "Install"
- Download the latest release
- Extract the ZIP file
- Copy to Arduino libraries folder:
- Windows:
Documents\Arduino\libraries\ - Mac:
Documents/Arduino/libraries/ - Linux:
~/Arduino/libraries/
- Windows:
- Restart Arduino IDE
Add to your platformio.ini:
lib_deps =
JOYBOY-3/UniversalFingerprint@^1.0.0Or install via PlatformIO CLI:
pio lib install "UniversalFingerprint"- Required: Adafruit Fingerprint Sensor Library - For basic sensor communication
Install via Arduino Library Manager:
- Open Arduino IDE
- Tools β Manage Libraries
- Search for "Adafruit Fingerprint Sensor"
- Click "Install"
Or via PlatformIO:
lib_deps =
adafruit/Adafruit Fingerprint Sensor Library@^1.2.1Fingerprint Sensor -> Arduino
VCC -> 3.3V or 5V (check sensor specification)
GND -> GND
TX -> D2 (RX pin for SoftwareSerial)
RX -> D3 (TX pin for SoftwareSerial)
Sensor -> ESP32
VCC -> 3.3V
GND -> GND
TX -> GPIO16 (RX2)
RX -> GPIO17 (TX2)
β Important: R307 sensors require 3.3V only! 5V will damage them.
#include <UniversalFingerprint.h>
#include <SoftwareSerial.h>
// Create software serial for fingerprint sensor
SoftwareSerial fingerSerial(2, 3); // RX, TX
UniversalFingerprint finger(&fingerSerial);
void setup() {
Serial.begin(115200);
while (!Serial); // Wait for serial port
Serial.println("UniversalFingerprint Basic Example");
// Initialize fingerprint sensor
if (!finger.begin()) {
Serial.println("Could not find fingerprint sensor!");
Serial.println("Check wiring and power supply.");
while (1); // Halt execution
}
Serial.print("Sensor detected: ");
Serial.println(finger.getSensorModel());
Serial.print("Capacity: ");
Serial.print(finger.getCapacity());
Serial.println(" templates");
Serial.print("Library version: ");
Serial.println(finger.getVersion());
// Show database information
finger.printDatabaseInfo();
Serial.println("\nReady! Place finger on sensor to identify.");
}
void loop() {
// Identify fingerprint
int16_t id = finger.identify();
if (id > 0) {
Serial.print("Fingerprint matched! ID: #");
Serial.println(id);
} else if (id == 0) {
Serial.println("Fingerprint not in database");
} else {
Serial.print("Identification error: ");
Serial.println(finger.errorToString((UF_ErrorCode)(-id)));
}
delay(1000);
}bool begin(uint32_t password = 0x00000000, uint32_t baudRate = 57600);UF_ErrorCode enroll(uint16_t id = 0, uint8_t numScans = 2);int16_t identify(uint16_t* confidence = nullptr, uint8_t timeout = 10);UF_ErrorCode verify(uint16_t id, uint16_t* confidence = nullptr);bool getDatabaseStats(UF_DatabaseStats& stats);
uint16_t findEmptySlot(uint16_t start = 1);
int16_t scanDatabase();
bool isSlotOccupied(uint16_t id);UF_ErrorCode setLED(bool on, UF_LEDColor color = UF_LED_BLUE, uint8_t speed = 0);
UF_ErrorCode setSecurity(uint8_t level);
bool isFingerPresent();
UF_ErrorCode setBaudRate(uint32_t baudRate);struct UF_DatabaseStats {
uint16_t totalSlots; // Total available slots
uint16_t occupiedSlots; // Currently occupied slots
uint16_t freeSlots; // Free slots
uint16_t firstFreeSlot; // First free slot ID
uint16_t lastFreeSlot; // Last free slot ID
float usagePercentage; // Database usage percentage
};struct UF_SensorInfo {
UF_SensorType type; // Sensor type
const char* modelName; // Model name
const char* vendor; // Vendor name
uint16_t capacity; // Template capacity
uint16_t packetSize; // Data packet size
uint32_t defaultBaud; // Default baud rate
bool hasLED; // Has RGB LED control
bool hasTouchSensor; // Has touch detection
};enum UF_ErrorCode {
UF_OK, // Operation successful
UF_ERROR_COMM, // Communication error
UF_ERROR_NO_SENSOR, // Sensor not found
UF_ERROR_INVALID_ID, // Invalid template ID
UF_ERROR_SLOT_FULL, // No empty slots available
UF_ERROR_TIMEOUT, // Operation timeout
UF_ERROR_SENSOR_BUSY, // Sensor is busy
UF_ERROR_PACKET, // Invalid packet received
UF_ERROR_NOT_ENROLLED, // Finger not enrolled
UF_ERROR_NO_FINGER, // No finger detected
UF_ERROR_IMAGE_MESS, // Image too messy
UF_ERROR_FEATURE_FAIL, // Feature extraction failed
UF_ERROR_IMAGE_FAIL, // Image capture failed
UF_ERROR_DUPLICATE_ID, // Slot already occupied
UF_ERROR_NOT_SUPPORTED, // Feature not supported
UF_ERROR_INVALID_PARAM // Invalid parameter
};For complete API documentation, see API.md
The library includes 5 comprehensive examples:
- 01_BasicEnrollment - Simple enrollment and identification
- 02_FullDatabaseManager - Complete database management
- 03_SensorDetector - Auto-detect and report sensor information
- 04_AdvancedOperations - Raw template access and advanced features
- 05_MultiSensorDemo - Working with multiple sensors
void printDatabase() {
UF_DatabaseStats stats;
finger.getDatabaseStats(stats);
Serial.println("\n=== FINGERPRINT DATABASE ===");
Serial.print("Sensor: ");
Serial.println(finger.getSensorModel());
Serial.print("Capacity: ");
Serial.println(stats.totalSlots);
Serial.print("Enrolled: ");
Serial.println(stats.occupiedSlots);
Serial.print("Free: ");
Serial.println(stats.freeSlots);
Serial.print("Usage: ");
Serial.print(stats.usagePercentage, 1);
Serial.println("%");
Serial.println("\nSlot Map (O=Occupied, .=Empty):");
for (uint16_t i = 1; i <= min(stats.totalSlots, (uint16_t)100); i++) {
if (finger.isSlotOccupied(i)) {
Serial.print('O');
} else {
Serial.print('.');
}
if (i % 50 == 0) Serial.println();
}
Serial.println("\n============================\n");
}- Database Scan: ~2-3 seconds for full scan (R307: 1000 slots)
- Identification: < 1 second average
- Enrollment: 10-15 seconds per fingerprint
- Memory Usage: ~1KB RAM for database tracking
- Library Size: ~20KB flash memory
- Use HardwareSerial when possible (faster than SoftwareSerial)
- Cache database statistics instead of scanning repeatedly
- Set appropriate security level (higher = more accurate but slower)
- Use batch operations for multiple template deletions
Symptoms: begin() returns false
Solutions:
- Check power supply (3.3V vs 5V)
- Swap TX/RX connections
- Try different baud rates:
finger.begin(0x00000000, 9600); // Try 9600 baud
finger.begin(0x00000000, 57600); // Try 57600 baudSymptoms: Random failures, timeout errors Solutions:
- Add 1K-10K resistor between TX and RX lines
- Use level shifter for 3.3V/5V conversion
- Check for loose connections
- Use shorter cables (< 30cm)
Symptoms: Crashes on database scan Solutions:
- Reduce database tracking size
- Use
scanDatabase()only when needed - Enable memory optimization in IDE:
- Arduino IDE: Tools β Optimization β "Smallest Code"
Enable serial debugging by defining before including the library:
#define UF_DEBUG 1
#include <UniversalFingerprint.h>// Find first empty slot
uint16_t emptySlot = finger.findEmptySlot();
if (emptySlot > 0) {
Serial.print("First empty slot: #");
Serial.println(emptySlot);
}
// Find last empty slot
uint16_t lastEmpty = finger.findLastEmptySlot();
if (lastEmpty > 0) {
Serial.print("Last empty slot: #");
Serial.println(lastEmpty);
}UF_DatabaseStats stats;
if (finger.getDatabaseStats(stats)) {
Serial.print("Total slots: ");
Serial.println(stats.totalSlots);
Serial.print("Occupied: ");
Serial.println(stats.occupiedSlots);
Serial.print("Free: ");
Serial.println(stats.freeSlots);
Serial.print("Usage: ");
Serial.print(stats.usagePercentage, 1);
Serial.println("%");
}// Delete multiple templates
void deleteRange(uint16_t start, uint16_t end) {
for (uint16_t i = start; i <= end; i++) {
finger.deleteTemplate(i);
}
}
// Clear entire database
UF_ErrorCode result = finger.clearDatabase();
if (result == UF_OK) {
Serial.println("Database cleared successfully");
}#include <UniversalFingerprint.h>
#include <SoftwareSerial.h>
// Multiple sensor setup
SoftwareSerial sensor1Serial(2, 3);
SoftwareSerial sensor2Serial(4, 5);
UniversalFingerprint sensor1(&sensor1Serial, UF_SENSOR_AS608);
UniversalFingerprint sensor2(&sensor2Serial, UF_SENSOR_R307);
void setup() {
Serial.begin(115200);
sensor1.begin();
sensor2.begin();
Serial.print("Sensor 1: ");
Serial.println(sensor1.getSensorModel());
Serial.print("Sensor 2: ");
Serial.println(sensor2.getSensorModel());
}// Advanced sensor configuration
void configureSensor() {
// Set security level (1-5)
finger.setSecurity(4); // High security
// Configure LED
finger.setLED(true, UF_LED_GREEN);
delay(1000);
finger.setLED(false);
// Change baud rate
finger.setBaudRate(115200);
// Reinitialize with new baud rate
finger.begin(0x00000000, 115200);
}UF_ErrorCode result = finger.enroll(5);
if (result != UF_OK) {
Serial.print("Error: ");
Serial.println(finger.errorToString(result));
switch (result) {
case UF_ERROR_SLOT_FULL:
// Handle full database
uint16_t emptySlot = finger.findEmptySlot();
if (emptySlot > 0) {
Serial.print("Try slot #");
Serial.println(emptySlot);
}
break;
case UF_ERROR_TIMEOUT:
// Handle timeout
Serial.println("Please try again");
break;
case UF_ERROR_NO_FINGER:
// Ask user to place finger
Serial.println("Please place finger on sensor");
break;
default:
// Handle other errors
break;
}
}Contributions are welcome! Please follow these steps:
- Fork the repository
- Create a feature branch (
git checkout -b feature/AmazingFeature) - Commit changes (
git commit -m 'Add AmazingFeature') - Push to branch (
git push origin feature/AmazingFeature) - Open a Pull Request
# Clone repository
git clone https://github.com/JOYBOY-3/UniversalFingerprint.git
cd UniversalFingerprint
# For PlatformIO development
pio lib install "adafruit/Adafruit Fingerprint Sensor Library"
pio test # Run tests
# For Arduino development
# Copy to Arduino libraries folder- Follow Arduino library conventions
- Use clear, descriptive variable names
- Add comments for complex logic
- Maintain backward compatibility
- Write tests for new features
This project is licensed under the MIT License - see the LICENSE file for details.
- Based on Adafruit Fingerprint Sensor Library
- Inspired by various open-source fingerprint implementations
- Thanks to all contributors and testers
- Community support from Arduino Forum and GitHub
- Documentation: Complete API reference
- Examples: See
examples/folder for working code - Getting Started: Quick start guide
- Sensor Compatibility: Compatibility guide
- Check existing GitHub Issues
- Search the documentation
- Try the examples
- If issue persists, create new issue with:
- Arduino board and sensor model
- Library version
- Error messages
- Code example
- Wiring diagram
- GitHub Discussions: Feature requests and questions
- Arduino Forum: Community support
- Stack Overflow: Technical questions
Made with β€οΈ for the Arduino community
Version: 1.0.0
Last Updated: 2024-01-01
Maintainer: Sourabh Kumar Gupta rajuhuptaooooo@gmail.com