> For the complete documentation index, see [llms.txt](https://docs.launchboard.app/cxd/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.launchboard.app/cxd/internet-of-things-project/references-for-wiring-and-coding/fingerprint-scanner.md).

# Fingerprint Scanner

A fingerprint scanner can add encoded fingerprint images to a database and then read a fingerprint to compare it against the stored fingerprints for identification purposes.

The [GT-511C3 fingerprint scanner](https://www.sparkfun.com/products/11792) can store up to 200 different fingerprints in its onboard database.

![Fingerprint Scanner](https://576155698-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LDgX-RdB-DPZBPuXzJ1%2F-LDgX75Qrx69yS4tZ2_Z%2F-LDgXGo-0Be5BIhXBBq0%2Ffingerprint-scanner.jpg?generation=1527608059047784\&alt=media) ![Fingerprint Scanner Wiring](https://576155698-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LDgX-RdB-DPZBPuXzJ1%2F-LDgX75Qrx69yS4tZ2_Z%2F-LDgXGo1Au1xfg94JHNp%2Ffingerprint-scanner-wiring.jpg?generation=1527608059034434\&alt=media)

This fingerprint scanner comes with a 4-wire connector (1 black wire + 3 white wires). Insert the wires into different numbered rows on a breadboard. Then use jumper wires to connect these rows to the Photon.

If the fingerprint scanner wires were numbered left to right as 1-4 (with the black wire being Wire 1), the jumper wire connections would be:

| Fingerprint Scanner  | Photon Pin |
| -------------------- | ---------- |
| Wire 1 (Black) = TX  | RX         |
| Wire 2 (White) = RX  | TX         |
| Wire 3 (White) = GND | GND        |
| Wire 4 (White) = VCC | V-USB (5V) |

The fingerprint scanner will transfer data with the Photon board over a serial data connection using the Photon RX and TX pins.

**NOTE:** For serial data connections, the RX pin of one device connects to the TX pin of the other device. (RX = receive, TX = transmit)

**TIP:** The fingerprint scanner has a small built-in green LED. If the Photon device is powered on and you have correctly wired the fingerprint scanner, this green LED should be on.

## Code for Fingerprint Reader

### #Include Library

Your Photon app must include a code library with special functions that will allow you to control the fingerprint reader.

1. In Particle Build, click on the bookmark icon to open the Libraries sidebar.
2. Type "fingerprint" into the search field. Select the result called: **FINGERPRINT\_FPS\_GT511C3**
3. Click the button to "Include in Project"
4. Select the name of your Photon app, and then click the "Confirm" button
5. Particle Build will automatically insert an `#include` statement at the top of your app code

```java
// This #include statement was automatically added by the Particle IDE.
#include <Fingerprint_FPS_GT511C3.h>
```

### Global Variables

In your global variables, you need to declare an FPS\_GT511C3 object variable that you will use to run the special functions in the library. The example below declares an object variable called "fps" (but you could use a different variable name).

```java
// declare FPS_GT511C3 object variable called "fps"
FPS_GT511C3 fps;
```

You will probably also want to declare an integer variable to store a fingerprint ID number (such as the ID of the detected fingerprint, etc.). This will make it easier to do something with this ID. The example below declares a variable called "fingerprintID" (but you could use a different variable name).

```java
// global variable
int fingerprintID;
```

### setup( ) function

You need to include a statement within the `setup()` function to start a serial data connection (which will activate both the RX and TX pins on the Photon). This will allow the Photon and the fingerprint scanner to send and receive data between each other. The fingerprint scanner communicates at a baud rate of 9600 bps.

You also need to include statements to start ("open") the fingerprint scanner and to turn on the LED inside the scanner.

```java
Serial1.begin(9600);
fps.Open();
fps.SetLED(true);
```

### Test Fingerprint Scanner

You can use the following **temporary** code to test whether your fingerprint scanner is wired correctly and able to communicate with your Photon. It will simply turn the scanner's internal LED on and off in a blinking pattern. Once you've verified this works, you can remove this code from the `loop()` function.

```java
void loop() {
    // FPS Blink LED Test
    fps.SetLED(true); // turn on the LED inside the fps
    delay(1000);
    fps.SetLED(false);// turn off the LED inside the fps
    delay(1000);
}
```

### FINGERPRINT SCANNER TASKS

You can do the following tasks with the fingerprint scanner:

* Check If Finger Pressed
* Add Fingerprint
* Delete Fingerprint
* Verify Fingerprint Against Specific ID
* Verify Fingerprint Against All Stored IDs

This code will most likely be placed within the `loop()` function or within custom functions.

**RECOMMENDATION:** Use the speaker and/or LEDs to provide feedback on whether a fingerprint was verified or not. For example, if the fingerprint is verified, you could turn on a green LED and/or play a short medium-pitched sound. If the fingerprint is not recognized, you could turn on a red LED and/or play a longer low-pitched sound.

### Check If Finger Pressed

You can check whether a finger is being pressed against the scanner using a `fps.IsPressFinger()` statement, which will return either true or false.

```java
if(fps.IsPressFinger() == true) {

    // insert code to do something if finger press detected

}
```

For example, if a finger is pressed against the scanner, you could have your code verify whether the fingerprint is already stored in the database, etc.

Before you can verify a fingerprint, you will obviously need to have at least one fingerprint added to the scanner database.

### Add Fingerprint

The fingerprint scanner can store up to 200 different fingerprints in its onboard database. Each fingerprint is given a unique ID number from 0-199. The fingerprints stored in the database will be retained even when the scanner is powered off.

Adding a new fingerprint is a process called "enrollment" which consists of capturing high-quality images of the same fingerprint 3 times in a row for comparison. This 3-step enrollment verifies the scanner is able to read and identify the fingerprint accurately and consistently.

During fingerprint enrollment, the person presses their finger on the scanner for the first capture, and then lifts the finger. The same finger is pressed down again for a second capture, and lifted again. Finally, the finger is pressed for a third capture, which will ideally complete the process. However, the enrollment process can fail at any of these 3 steps.

**TIP:** Be patient, as enrollment may take more than one try. However, once a fingerprint is successfully enrolled, verifying that fingerprint in the future is usually fast and accurate.

It is important to have some type of clear feedback during the enrollment process to know when to press and lift the finger, as well as to know whether the enrollment steps were successful or failed. This feedback could be provided through the OLED display screen, red & green LED lights, the web app, etc.

**IMPORTANT:** The code example below uses the [Micro OLED display screen](/cxd/internet-of-things-project/references-for-wiring-and-coding/micro-oled-display.md). You will need to wire the OLED screen to your Photon, and include other necessary code (library, global variables, etc.) for the OLED display.

You could use this code to enroll one or more fingerprints. Then you could remove the `addFingerprint()` statement from the `loop()` function, and replace it with your primary app code (to verify a fingerprint against the database and then do something with the result).

**TIP:** Once you are done enrolling fingerprints, you can still keep the code for the `addFingerprint()` custom function in your app, even if you are no longer calling it in the `loop()`. This will make it easier for you to add more fingerprints later, if necessary.

**RECOMMENDATION:** If you will need your Photon app (or web app) to know which fingerprint ID is assigned to which person, it may be easier to record this ID number immediately after successfully enrolling the finger. If a person (such as yourself) is going to register multiple fingers, then record the ID number for each specific finger (right index, left thumb, etc.) that you enroll. Then later, you can use this information to have your Photon app (or web app) make different decisions based on which specific fingerprint ID is detected by the scanner.

```java
void setup() {
    oled.begin();
    Serial1.begin(9600);
    fps.Open();
    fps.SetLED(true);
}

void loop() {
    addFingerprint();
}

// custom function to display messages on OLED screen
void displayOLED(String message) {
    oled.clear(PAGE);
    oled.setFontType(0);
    oled.setCursor(0,0);
    oled.println(message);
    oled.display();
}

// custom function to enroll new fingerprint
void addFingerprint() {
    // find next available fingerprint ID
    int enrollID = 0;
    bool usedID = true;
    String message;
    while (usedID == true) {
        usedID = fps.CheckEnrolled(enrollID);
        if (usedID == true) enrollID++;
        if (enrollID == 200) {
            message = "Fingerprint\nDatabase\nFull";
            displayOLED(message);
            return;
        }
    }
    // start enrollment for new fingerprint ID
    fps.EnrollStart(enrollID);
    message = "Add ID ";
    message += String(enrollID);
    message += "\n\nPRESS\nFINGER";
    displayOLED(message);
    while(fps.IsPressFinger() == false) {
        delay(100);
        Particle.process();
    }
    // capture fingerprint (true = slower high-res image)
    bool bret = fps.CaptureFinger(true);
    int iret = 0;
    if (bret != false) {
        message = "REMOVE\nFINGER";
        displayOLED(message);
        // save fingerprint image 1
        fps.Enroll1();
        while(fps.IsPressFinger() == true) {
            delay(100);
            Particle.process();
        }
        message = "Confirm\n\nPRESS\nSAME\nFINGER";
        displayOLED(message);
        while(fps.IsPressFinger() == false) {
            delay(100);
            Particle.process();
        }
        bret = fps.CaptureFinger(true);
        if (bret != false) {
            message = "REMOVE\nFINGER";
            displayOLED(message);
            // verify fingerprint image 2
            fps.Enroll2();
            while(fps.IsPressFinger() == true) {
                delay(100);
                Particle.process();
            }
            message = "Final\nConfirm\n\nPRESS\nSAME\nFINGER";
            displayOLED(message);
            while(fps.IsPressFinger() == false) {
                delay(100);
                Particle.process();
            }
            bret = fps.CaptureFinger(true);
            if (bret != false) {
                message = "REMOVE\nFINGER";
                displayOLED(message);
                delay(1000);
                // verify fingerprint image 3
                iret = fps.Enroll3();
                if (iret == 0) {
                    message = "SUCCESS\n\nAdded\nFinger\nID ";
                    message += String(enrollID);
                    displayOLED(message);
                } else {
                    message = "FAILED\n\nError\nCode\n";
                    message += String(iret);
                    displayOLED(message);
                }
            } else {
                message = "3rd Press\nFAILED";
                displayOLED(message);
            }
        } else {
            message = "2nd Press\nFAILED";
            displayOLED(message);
        }
    } else {
        message = "1st Press\nFAILED";
        displayOLED(message);
    }
    // wait to allow final message to be read
    delay(5000);
}
```

That's a lot of code compared to what's been needed for other parts. Luckily, the other fingerprint scanner tasks only require a few lines of code at most.

### Delete Fingerprint

If necessary, you can delete a **specific** fingerprint from the scanner database by providing its ID (0-199) either as a number or as an integer variable.

```java
// ID number to delete - change as needed
fingerprintID = 13;

fps.DeleteID(fingerprintID);
```

If necessary, you can also delete **all** the fingerprint images from the scanner database. Be careful using this statement – there is no "undo" if you delete all the stored fingerprints.

```java
fps.DeleteAll(); // caution - cannot undo
```

### Verify Fingerprint Against Specific ID

You can use the `fps.Verify1_1()` statement to verify whether a finger matches a **specific** fingerprint ID by providing the ID (0-199) to check against. The ID can be provided as a number or as an integer variable.

First, you need to capture an image of the finger being pressed. For faster identification, a lower-resolution image is captured.

If the captured fingerprint matches the specific fingerprint ID stored in the database, the `fps.Verify1_1()` statement will return true. Otherwise, it will return false.

```java
// ID number to check against - change as needed
fingerprintID = 7;

if(fps.IsPressFinger() == true) {

    // capture fingerprint (false = faster low-res image)
    fps.CaptureFinger(false);

    if(fps.Verify1_1(fingerprintID)) {

        // insert code to do something if fingerprint matches specific ID

    } else {

        // optional: do something else if it does not match specific ID
    }
}
```

### Verify Fingerprint Against All Stored IDs

In most cases, you will want to use the `fps.Identify1_N()` statement to verify whether a fingerprint matches **any** of the fingerprints stored in the database – and if so, identify which fingerprint ID matches.

First, you need to capture an image of the finger being pressed. For faster identification, a lower-resolution image is captured.

If the fingerprint matches an ID stored in the database, the `fps.Identify1_N()` statement will return the matching ID number (0-199). Otherwise, it returns a value of 200 if the fingerprint isn't in the database.

```java
if(fps.IsPressFinger() == true) {

    // capture fingerprint (false = faster low-res image)
    fps.CaptureFinger(false);

    fingerprintID = fps.Identify1_N();

    if(fingerprintID == 200) {

        // insert code to do something if fingerprint is NOT in database

    } else {

        // insert code to do something with matching fingerprint ID
    }
}
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.launchboard.app/cxd/internet-of-things-project/references-for-wiring-and-coding/fingerprint-scanner.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
