Andrey Ovcharov

Professional Software Engineer and hobbyist Hardware enthusiast

Andrey Ovcharov

Progress in capturing raw fingerprint image with FPC1020A scanner

Recently I’ve started connecting FPC1020A Fingerprint scanners to ESP32 microcontroller and built a working test board for both modifications I have.

Surprisingly, scanning the fingerprint image was not an easy task. I’ve spent several days trying to retrieve any data from the sensor except the Hardware ID but without any success. Apparently, the task of processing raw images from the capacitive scanner is not a very common task and it was hard to find any code examples or documentation online.

However, a thorough search could help me to solve this problem. I have discovered that some branches of Android kernel have a special driver for the FPC1020A scanners written by the company Fingerprints, the manufacturer of the scanners. And, working with these sources could help me to find out that documentation provided by sellers of the module is incomplete, to say the least.

First of all, the FPC1020A chip has at least four revisions requiring different setup procedures. Many of the setup values are real random “magic numbers” to me as they look like 0x1717171723232323 and they are not described in the documentation. Probably the full and proper documentation could bring some light on this topic but I don’t have it at the moment.

I did not write the code to detect which revision I have but just tried out one setup sequence by one. Suddenly, the revision A3 enabled finger detection and scanning functions. The setup code looks like this now:

esp_err_t fpc1020_setup()
    uint8_t val8;
    uint16_t val16;
    uint32_t val32;
    uint64_t val64;

    // revision 3
    val64 = 0x1717171723232323;
    CHECK_RET(fpc1020_transmit_uint64(FPC102X_REG_SAMPLE_PX_DLY, &val64), "");

    val8 = 0x0f;
    CHECK_RET(fpc1020_transmit_uint8(FPC102X_REG_PXL_RST_DLY, &val8), "");

    val8 = 0x18;
    CHECK_RET(fpc1020_transmit_uint8(FPC102X_REG_FINGER_DRIVE_DLY, &val8), "");

    val8 = 0x02;
    CHECK_RET(fpc1020_transmit_uint8(FPC102X_REG_FINGER_DRIVE_CONF, &val8), "");

    val16 = 0x1002;
    CHECK_RET(fpc1020_transmit_uint16(FPC102X_REG_ADC_SHIFT_GAIN, &val16), "");

    val16 = 0x000a | 0x0F00;
    CHECK_RET(fpc1020_transmit_uint16(FPC102X_REG_PXL_CTRL, &val16), "");

    val8 = 0x03 | 0x08;
    CHECK_RET(fpc1020_transmit_uint8(FPC102X_REG_IMAGE_SETUP, &val8), "");

    val8 = 0x50;
    CHECK_RET(fpc1020_transmit_uint8(FPC1020_REG_FNGR_DET_THRES, &val8), "");

    val16 = 0x00FF;
    CHECK_RET(fpc1020_transmit_uint16(FPC1020_REG_FNGR_DET_CNTR, &val16), "");
    return ESP_OK;

The full code of the component handling FPC1020 scanners is available on Github.

So, at the moment, I have a code for ESP IDF to work with both types of the FPC1020A scanners I have, detect the presence of the finger and receive a huge array of 8-bit values representing the fingerprint image. Not a big step, but a very important milestone - now the biometric part of the project moves from the hardware to software section - I need to find/build algorithms for recognition and matching fingerprints.