IOT

How to interface R502/R503 Capacitive Fingerprint Sensor with Arduino?

Many fingerprint sensors are available on the market, and we commonly use R305/R307 Optical fingerprint sensors in projects such as Attendance systems and Biometric Security systems. We also employed an advanced fingerprint sensor, such as the GT511C3, which has a high level of accuracy and a quick response time. It detects fingerprints using a camera image processing technology rather than the optical method.

In this blog, we discuss the details and specifications of the R502/R503 Capacitive Fingerprint Sensor, as well as how the Capacitive Fingerprint Sensor works. Apart from that, we’ll use the Adafruit Library to connect the R502/R503 Capacitive Fingerprint Sensor to Arduino, and then learn how to enroll and test fingerprints.

How do fingerprint scanners work - Explain that Stuff

Hardware Required

  • Arduino UNO/Nano Board
  • R503 Optical fingerprint sensors 
  • Jumper Wires

R502/R503 Capacitive Fingerprint Sensor

R502 R503 Capacitive Fingerprint Sensor

The R502/R503 is the most widely used and cheapest capacitive fingerprint sensor on the market. The chip was created by combining image gathering and algorithm chips. The best thing about R502/R503 is that it responds to different finger circumstances, such as dry fingers, moist, light texture, or aged fingertips with a high recognition rate. When comparing R502 to R503, the distinction is that R502 is thinner and smaller.

The fingerprint sensor operates at 3.3V and consumes 18mA during fingerprint acquisition and 2uA on average during standby. It communicates using the RS232 UART interface at a baud rate of 57600bps by default. It has a maximum capacity of 200 fingerprints. Arduino, Android, Windows, and Linux are all supported by the R502/R503 fingerprint module.

Features & Specifications

  • Interface: RS232 (TTL)
  • Resolution: 508 DPI
  • Voltage: DC 3.3V
  • Working current(Fingerprint acquisition): 18mA
  • Standby current(finger detection): Typical touch standby voltage: 3.3V, Average current: 2uA
  • Fingerprint capacity: 200
  • Sensing Array: 192*192 pixel
  • LED Color: Bule and Red
  • Scanning Speed: < 0.2 second
  • Verification Speed: < 0.3 second
  • Matching Method: 1:1; 1:N
  • FRR (False Rejection Ratio): ≤0.01%
  • FAR (False Acceptance Ratio): ≤0.00001%
  • Communications baud rate (UART):(9600 × N) bps where N = 1 ~ 12(default N = 6, ie 57600bps)

R502/R503 Pinout

There is a total of 6 wires basically pinout of R502/R503 Fingerprint Sensor which is as follows.

R502 Pinout

How does Capacitive Fingerprint Sensor work?

When compared to optical fingerprint sensors, the capacitive fingerprint sensor uses a different algorithm. Capacitive fingerprint scanners acquire data using arrays of tiny capacitor circuits rather than a typical image of a fingerprint.

Since capacitors hold an electrical charge, they may be used to track the details of a fingerprint by attaching them to conductive plates on the scanner’s surface. When the ridge of a finger is placed over the conductive plates, the stored charge is somewhat altered. An air gap, on the other hand, keeps the charge at the capacitor relatively constant. These changes are tracked using an op-amp integrator circuit, which can then be recorded using an analog-to-digital converter.

Once captured,  the digital data is evaluated for distinguishing and unique fingerprint characteristics. They can then be saved for future comparisons.

Interfacing R502/R503 Capacitive Fingerprint Sensor with Arduino

Let’s look at how to connect an R502/R503 Capacitive Fingerprint Sensor to an Arduino. The connection diagram is given below

Capacitive Fingerprint Sensor Arduino

A UART Module is used to detect fingerprints. Connect the VCC & GND pin of R502/R503 to Arduino 3.3V & GND pin. Connect the Tx (Yellow Wire) and Rx (Green Wire) to Arduino D2 and D3, respectively. The blue wire is an interrupt wire that is left open. Connect the white wire to the 3.3V power supply.

R502 R503 Arduino

You can directly connect the fingerprint sensor module with Arduino using jumper wires.

Source Code/Program

Adafruit offers an Arduino library for the R502/R503 Capacitive Fingerprint Sensor. You can download the Adafruit Fingerprint Sensor Library from the Github repository.

For enrolling and reading fingerprint data, there are two different codes. The fingerprint data will be saved in EEPROM memory by the enroll code. The fingerprint read code, on the other hand, will read the fingerprint stored in EEPROM memory and compare it to the one scanned.

Enroll Code

#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.println(“.”);
      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;
}
  • Open the Serial Monitor after you’ve uploaded the code. The monitor will prompt you to enter a fingerprint ID number between 1 and 127.
  • Now, in the Serial Monitor Screen, input the ID number and send it. You can then enroll your fingerprint by following the instructions on the screen.
  • You can put your finger on the fingerprint sensor that you want to enroll.
  • The finger is successfully enrolled. You can enroll multiple fingers this way.

Fingerprint Read Code

#include <Adafruit_Fingerprint.h>
int u=0;
int relay=5;
 
#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);
 
void setup()
{
  pinMode(relay,OUTPUT);
  Serial.begin(9600);
  while (!Serial);  // For Yun/Leo/Micro/Zero/…
  delay(100);
  Serial.println(“\n\nAdafruit finger detect test”);
 
  // set the data rate for the sensor serial port
  finger.begin(57600);
  delay(5);
  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);
 
  finger.getTemplateCount();
 
  if (finger.templateCount == 0) {
    Serial.print(“Sensor doesn’t contain any fingerprint data. Please run the ‘enroll’ example.”);
  }
  else {
    Serial.println(“Waiting for valid finger…”);
      Serial.print(“Sensor contains “); Serial.print(finger.templateCount); Serial.println(” templates”);
  }
}
 
void loop()                 // run over and over again
{
  getFingerprintID();
  delay(50);            //don’t ned to run this at full speed.
}
 
uint8_t getFingerprintID() {
  uint8_t p = finger.getImage();
  switch (p) {
    case FINGERPRINT_OK:
      Serial.println(“Image taken”);
      break;
    case FINGERPRINT_NOFINGER:
      Serial.println(“No finger detected”);
      finger.LEDcontrol(FINGERPRINT_LED_OFF, 0, FINGERPRINT_LED_BLUE);
      finger.LEDcontrol(FINGERPRINT_LED_OFF, 0, FINGERPRINT_LED_RED);
      return p;
    case FINGERPRINT_PACKETRECIEVEERR:
      Serial.println(“Communication error”);
      return p;
    case FINGERPRINT_IMAGEFAIL:
      Serial.println(“Imaging error”);
      return p;
    default:
      Serial.println(“Unknown error”);
      return p;
  }
 
  // OK success!
 
  p = finger.image2Tz();
  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!
  p = finger.fingerSearch();
  if (p == FINGERPRINT_OK) {
    Serial.println(“Found a print match!”);
    finger.LEDcontrol(FINGERPRINT_LED_FLASHING, 25, FINGERPRINT_LED_PURPLE, 10);
    delay(1000);
  if(u==0)
    {
      digitalWrite(relay,HIGH);
      u=1;
    }
    else if(u==1)
    {
      digitalWrite(relay,LOW);
      u=0;
    }
  } else if (p == FINGERPRINT_PACKETRECIEVEERR) {
    Serial.println(“Communication error”);
    return p;
  } else if (p == FINGERPRINT_NOTFOUND) {
    finger.LEDcontrol(FINGERPRINT_LED_FLASHING, 25, FINGERPRINT_LED_RED, 10);
  delay(1000);
  Serial.println(“Did not find a match”);
    return p;
  } else {
    Serial.println(“Unknown error”);
    return p;
  }
 
  // found a match!
  Serial.print(“Found ID #”); Serial.print(finger.fingerID);
  Serial.print(” with confidence of “); Serial.println(finger.confidence);
 
  return finger.fingerID;
}
 
// returns -1 if failed, otherwise returns ID #
int getFingerprintIDez() {
  uint8_t p = finger.getImage();
  if (p != FINGERPRINT_OK)  return -1;
 
  p = finger.image2Tz();
  if (p != FINGERPRINT_OK)  return -1;
 
  p = finger.fingerFastSearch();
  if (p != FINGERPRINT_OK)  return -1;
 
  // found a match!
  Serial.print(“Found ID #”); Serial.print(finger.fingerID);
  Serial.print(” with confidence of “); Serial.println(finger.confidence);
  return finger.fingerID;
}
  • After the fingers have been enlisted, you may use the above code to read the fingerprint saved in the database.
  • You can read the data recorded by placing your finger on the fingerprint sensor.

Conclusion:

I hope all of you have understood how to interface the R502/R503 Capacitive Fingerprint Sensor with Arduino. We MATHA ELECTRONICS will be back soon with more informative blogs.

Leave a Reply

Your email address will not be published.