Introduction
How to Interface the R307 Fingerprint Sensor with Arduino: Fingerprint sensors are a critical component in modern security systems, providing a reliable method for identification and verification. The R307 fingerprint sensor module is well-regarded for its performance and ease of use. In this tutorial, we will demonstrate how to interface the R307 fingerprint sensor with an Arduino Uno and control the built-in LED (LED 13) using stored fingerprints.
Specifications of the R307 Fingerprint Sensor
The R307 fingerprint sensor module offers a range of features and specifications that make it suitable for various biometric applications. Here are the key specifications:
- Power Supply: DC 4.2V – 6V
- Interface: UART (TTL logical level) / USB 2.0
- Working Current: Typical 50mA
- Matching Mode: 1:1 (one-to-one) and 1(one-to-many)
- Baud Rate: (9600 * N) bps, N = 1 to 12 (default N = 6)
- Character File Size: 256 bytes
- Image Acquiring Time: < 0.5s
- Template Size: 512 bytes
- Storage Capacity: Up to 1000 fingerprints
- Security Level: 5 (1, 2, 3, 4, 5, with 5 being the highest)
- False Acceptance Rate (FAR): < 0.001%
- False Rejection Rate (FRR): < 0.1%
- Average Searching Time: < 1s (1:1000)
- Window Dimension: 19mm x 21mm
- Operating Temperature: -10℃ to +40℃
- Storage Temperature: -40℃ to +85℃
- Working Environment: RH 20% – 85%
- Storage Environment: RH < 85%
- Outline Dimension: Split type Module: 44.1mm x 20mm x 23.5mm
Pin Connections of the R307 Fingerprint Sensor
The R307 module has the following pins:
- VCC (Pin 1): Connects to 5V power supply.
- GND (Pin 2): Connects to ground.
- TXD (Pin 3): Transmit data pin, connects to the RX (2) pin of the Arduino.
- RXD (Pin 4): Receive data pin, connects to the TX (3) pin of the Arduino.
Circuit Diagram
Below is the circuit diagram showing how to connect the R307 fingerprint sensor to the Arduino Uno:
- VCC (Pin 1) → 5V on the Arduino
- GND (Pin 2) → GND on the Arduino
- TXD (Pin 3) → Arduino Pin 2 (RX)
- RXD (Pin 4) → Arduino Pin 3 (TX)
Caution: If you are using an Arduino Uno, use these same pins and always check your wire continuity to ensure reliable connections.
Step 1: Adding the Required Library
To start, you need to add the necessary library to your Arduino IDE. This library will facilitate communication between the Arduino and the R307 fingerprint sensor.
Click here to download the library
Step 2: Enrolling a Fingerprint
First, let’s enroll a fingerprint in the sensor. This process involves capturing a fingerprint and storing it in the sensor’s memory. Use the following code to accomplish this:
/***************************************************
This is an example sketch for our optical Fingerprint sensor
Designed specifically to work with the Adafruit BMP085 Breakout
----> http://www.adafruit.com/products/751
These displays use TTL Serial to communicate, 2 pins are required to
interface
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
Written by Limor Fried/Ladyada for Adafruit Industries.
Small bug-fix by Michael cochez
BSD license, all text above must be included in any redistribution
****************************************************/
#include <Adafruit_Fingerprint.h>
#if (defined(__AVR__) || defined(ESP8266)) && !defined(__AVR_ATmega2560__)
// For UNO and others without hardware serial, we must use software serial...
// pin #2 is IN from sensor (GREEN wire)
// pin #3 is OUT from arduino (WHITE wire)
// Set up the serial port to use softwareserial..
SoftwareSerial mySerial(2, 3);
#else
// On Leonardo/M0/etc, others with hardware serial, use hardware serial!
// #0 is green wire, #1 is white
#define mySerial Serial1
#endif
Adafruit_Fingerprint finger = Adafruit_Fingerprint(&mySerial);
uint8_t id;
void setup()
{
Serial.begin(9600);
while (!Serial); // For Yun/Leo/Micro/Zero/...
delay(100);
Serial.println("\n\nAdafruit Fingerprint sensor enrollment");
// set the data rate for the sensor serial port
finger.begin(57600);
if (finger.verifyPassword()) {
Serial.println("Found fingerprint sensor!");
} else {
Serial.println("Did not find fingerprint sensor :(");
while (1) { delay(1); }
}
Serial.println(F("Reading sensor parameters"));
finger.getParameters();
Serial.print(F("Status: 0x")); Serial.println(finger.status_reg, HEX);
Serial.print(F("Sys ID: 0x")); Serial.println(finger.system_id, HEX);
Serial.print(F("Capacity: ")); Serial.println(finger.capacity);
Serial.print(F("Security level: ")); Serial.println(finger.security_level);
Serial.print(F("Device address: ")); Serial.println(finger.device_addr, HEX);
Serial.print(F("Packet len: ")); Serial.println(finger.packet_len);
Serial.print(F("Baud rate: ")); Serial.println(finger.baud_rate);
}
uint8_t readnumber(void) {
uint8_t num = 0;
while (num == 0) {
while (! Serial.available());
num = Serial.parseInt();
}
return num;
}
void loop() // run over and over again
{
Serial.println("Ready to enroll a fingerprint!");
Serial.println("Please type in the ID # (from 1 to 127) you want to save this finger as...");
id = readnumber();
if (id == 0) {// ID #0 not allowed, try again!
return;
}
Serial.print("Enrolling ID #");
Serial.println(id);
while (! getFingerprintEnroll() );
}
uint8_t getFingerprintEnroll() {
int p = -1;
Serial.print("Waiting for valid finger to enroll as #"); Serial.println(id);
while (p != FINGERPRINT_OK) {
p = finger.getImage();
switch (p) {
case FINGERPRINT_OK:
Serial.println("Image taken");
break;
case FINGERPRINT_NOFINGER:
Serial.print(".");
break;
case FINGERPRINT_PACKETRECIEVEERR:
Serial.println("Communication error");
break;
case FINGERPRINT_IMAGEFAIL:
Serial.println("Imaging error");
break;
default:
Serial.println("Unknown error");
break;
}
}
// OK success!
p = finger.image2Tz(1);
switch (p) {
case FINGERPRINT_OK:
Serial.println("Image converted");
break;
case FINGERPRINT_IMAGEMESS:
Serial.println("Image too messy");
return p;
case FINGERPRINT_PACKETRECIEVEERR:
Serial.println("Communication error");
return p;
case FINGERPRINT_FEATUREFAIL:
Serial.println("Could not find fingerprint features");
return p;
case FINGERPRINT_INVALIDIMAGE:
Serial.println("Could not find fingerprint features");
return p;
default:
Serial.println("Unknown error");
return p;
}
Serial.println("Remove finger");
delay(2000);
p = 0;
while (p != FINGERPRINT_NOFINGER) {
p = finger.getImage();
}
Serial.print("ID "); Serial.println(id);
p = -1;
Serial.println("Place same finger again");
while (p != FINGERPRINT_OK) {
p = finger.getImage();
switch (p) {
case FINGERPRINT_OK:
Serial.println("Image taken");
break;
case FINGERPRINT_NOFINGER:
Serial.print(".");
break;
case FINGERPRINT_PACKETRECIEVEERR:
Serial.println("Communication error");
break;
case FINGERPRINT_IMAGEFAIL:
Serial.println("Imaging error");
break;
default:
Serial.println("Unknown error");
break;
}
}
// OK success!
p = finger.image2Tz(2);
switch (p) {
case FINGERPRINT_OK:
Serial.println("Image converted");
break;
case FINGERPRINT_IMAGEMESS:
Serial.println("Image too messy");
return p;
case FINGERPRINT_PACKETRECIEVEERR:
Serial.println("Communication error");
return p;
case FINGERPRINT_FEATUREFAIL:
Serial.println("Could not find fingerprint features");
return p;
case FINGERPRINT_INVALIDIMAGE:
Serial.println("Could not find fingerprint features");
return p;
default:
Serial.println("Unknown error");
return p;
}
// OK converted!
Serial.print("Creating model for #"); Serial.println(id);
p = finger.createModel();
if (p == FINGERPRINT_OK) {
Serial.println("Prints matched!");
} else if (p == FINGERPRINT_PACKETRECIEVEERR) {
Serial.println("Communication error");
return p;
} else if (p == FINGERPRINT_ENROLLMISMATCH) {
Serial.println("Fingerprints did not match");
return p;
} else {
Serial.println("Unknown error");
return p;
}
Serial.print("ID "); Serial.println(id);
p = finger.storeModel(id);
if (p == FINGERPRINT_OK) {
Serial.println("Stored!");
} else if (p == FINGERPRINT_PACKETRECIEVEERR) {
Serial.println("Communication error");
return p;
} else if (p == FINGERPRINT_BADLOCATION) {
Serial.println("Could not store in that location");
return p;
} else if (p == FINGERPRINT_FLASHERR) {
Serial.println("Error writing to flash");
return p;
} else {
Serial.println("Unknown error");
return p;
}
return true;
}
Step 3: Connecting the Arduino to the R307 Fingerprint Sensor
With the circuit wired up as per the diagram, ensure the connections are secure:
Arduino Pin 2 → R307 Pin 3 Yellow
Arduino Pin 3 → R307 Pin 4 Green
Step 4: Turning on the Built-In LED Using a Fingerprint
Once a fingerprint is stored, you can use it to control the built-in LED (LED 13) on the Arduino. The following code will allow you to turn on the LED when a recognized fingerprint is detected:
// Code 2: Controlling LED 13 with a Fingerprint
#include <Adafruit_Fingerprint.h>
#include <SoftwareSerial.h>
// Define the pins for the fingerprint sensor
#define rxPin 2
#define txPin 3
// Create a SoftwareSerial object
SoftwareSerial mySerial(rxPin, txPin);
// Create a fingerprint sensor object
Adafruit_Fingerprint finger = Adafruit_Fingerprint(&mySerial);
void setup() {
// Initialize serial communication
Serial.begin(9600);
// Initialize the fingerprint sensor
finger.begin(57600);
// Check if the fingerprint sensor is connected
if (finger.verifyPassword()) {
Serial.println("Fingerprint sensor found!");
} else {
Serial.println("Did not find fingerprint sensor :(");
while (1);
}
// Set pin 13 as an output
pinMode(13, OUTPUT);
}
void loop() {
// Check if a fingerprint is detected
if (finger.getImage() == FINGERPRINT_OK) {
// Convert the image to a template
if (finger.image2Tz() == FINGERPRINT_OK) {
// Search for a match
if (finger.fingerFastSearch() == FINGERPRINT_OK) {
// Check if the fingerprint ID matches 1
if (finger.fingerID == 1) {
Serial.println("Fingerprint matched!");
// Turn on the LED
digitalWrite(13, HIGH);
} else {
Serial.println("Fingerprint did not match.");
// Turn off the LED
digitalWrite(13, LOW);
}
}
}
}
delay(1000); // Add a delay to avoid overwhelming the sensor
}
Step 5: Turning the Built-In LED On and Off with Two Different Fingerprints
This step involves using two different fingerprints to control the LED. One fingerprint will turn the LED on, and the other will turn it off.
// Code 3: Controlling LED 13 with Multiple Fingerprints
#include <Adafruit_Fingerprint.h>
#include <SoftwareSerial.h>
// Define the pins for the fingerprint sensor
#define rxPin 2
#define txPin 3
// Create a SoftwareSerial object
SoftwareSerial mySerial(rxPin, txPin);
// Create a fingerprint sensor object
Adafruit_Fingerprint finger = Adafruit_Fingerprint(&mySerial);
void setup() {
// Initialize serial communication
Serial.begin(9600);
// Initialize the fingerprint sensor
finger.begin(57600);
// Check if the fingerprint sensor is connected
if (finger.verifyPassword()) {
Serial.println("Fingerprint sensor found!");
} else {
Serial.println("Did not find fingerprint sensor :(");
while (1);
}
// Set pin 13 as an output
pinMode(13, OUTPUT);
}
void loop() {
// Check if a fingerprint is detected
if (finger.getImage() == FINGERPRINT_OK) {
// Convert the image to a template
if (finger.image2Tz() == FINGERPRINT_OK) {
// Search for a match
if (finger.fingerFastSearch() == FINGERPRINT_OK) {
// Check if the fingerprint ID matches 1
if (finger.fingerID == 1) {
Serial.println("Fingerprint matched ID 1!");
// Turn on the LED
digitalWrite(13, HIGH);
}
// Check if the fingerprint ID matches 2
else if (finger.fingerID == 2) {
Serial.println("Fingerprint matched ID 2!");
// Turn off the LED
digitalWrite(13, LOW);
}
else {
Serial.println("Fingerprint did not match ID 1 or ID 2.");
}
}
}
}
delay(1000); // Add a delay to avoid overwhelming the sensor
}
Step 6: Toggling the Built-In LED with the Same Fingerprint
You can also modify the code to toggle the LED on and off using the same fingerprint. This method is handy for situations where a single fingerprint needs to control an action.
Modification Tip: Adjust the logic in Code 2 to achieve this toggling effect.
#include <Adafruit_Fingerprint.h>
#include <SoftwareSerial.h>
// Define the pins for the fingerprint sensor
#define rxPin 2
#define txPin 3
// Create a SoftwareSerial object
SoftwareSerial mySerial(rxPin, txPin);
// Create a fingerprint sensor object
Adafruit_Fingerprint finger = Adafruit_Fingerprint(&mySerial);
// Variable to keep track of the LED state
bool ledState = false;
void setup() {
// Initialize serial communication
Serial.begin(9600);
// Initialize the fingerprint sensor
finger.begin(57600);
// Check if the fingerprint sensor is connected
if (finger.verifyPassword()) {
Serial.println("Fingerprint sensor found!");
} else {
Serial.println("Did not find fingerprint sensor :(");
while (1);
}
// Set pin 13 as an output
pinMode(13, OUTPUT);
// Ensure the LED is initially off
digitalWrite(13, LOW);
}
void loop() {
// Check if a fingerprint is detected
if (finger.getImage() == FINGERPRINT_OK) {
// Convert the image to a template
if (finger.image2Tz() == FINGERPRINT_OK) {
// Search for a match
if (finger.fingerFastSearch() == FINGERPRINT_OK) {
// Check if the fingerprint ID matches 1
if (finger.fingerID == 1) {
Serial.println("Fingerprint matched ID 1!");
// Toggle the LED state
ledState = !ledState;
digitalWrite(13, ledState ? HIGH : LOW);
// Add a delay to avoid multiple toggles from a single fingerprint scan
delay(1000);
} else {
Serial.println("Fingerprint did not match ID 1.");
}
}
}
}
delay(1000); // Add a delay to avoid overwhelming the sensor
}
Clear All Finger Prints
#include <Adafruit_Fingerprint.h>
#include <SoftwareSerial.h>
// Set up the serial pins for the fingerprint sensor
SoftwareSerial mySerial(2, 3); // RX, TX
Adafruit_Fingerprint finger = Adafruit_Fingerprint(&mySerial);
void setup() {
Serial.begin(9600);
mySerial.begin(57600); // Start communication with the fingerprint sensor
if (finger.verifyPassword()) {
Serial.println("Fingerprint sensor found!");
} else {
Serial.println("Did not find fingerprint sensor :(");
while (1);
}
// Clear all fingerprint data
Serial.println("Clearing all fingerprint data...");
if (finger.emptyDatabase() == FINGERPRINT_OK) {
Serial.println("All fingerprint data cleared.");
} else {
Serial.println("Failed to clear fingerprint data.");
}
}
void loop() {
// Nothing to do in the loop
}
Conclusion
By following these steps, you’ve successfully interfaced the R307 fingerprint sensor with an Arduino Uno and controlled the built-in LED using fingerprints. This project lays the foundation for more complex biometric systems, such as security access controls or attendance systems. Experiment with the code and explore additional features of the R307 sensor to enhance your project.