Cirkit Designer LogoCirkit DesignerYour all-in-one circuit design IDE Launch Cirkit Designer App

ESP32-Based Fingerprint Sensor and SD Card Module for Secure Data Storage

View and Edit Project In Cirkit DesignerImage of ESP32-Based Fingerprint Sensor and SD Card Module for Secure Data Storage

Circuit Documentation

Summary

This circuit integrates an ESP32 microcontroller with a fingerprint sensor, an SD card module, and a pushbutton. The ESP32 handles the communication with the fingerprint sensor and the SD card module via SPI, and it also reads input from the pushbutton to trigger fingerprint capture and storage.

Component List

  1. ESP32 (30 pin)

    • Description: A powerful microcontroller with built-in Wi-Fi and Bluetooth capabilities.
    • Pins: EN, VP, VN, D34, D35, D32, D33, D25, D26, D27, D14, D12, D13, GND, Vin, D23, D22, TX0, RX0, D21, D19, D18, D5, TX2, RX2, D4, D2, D15, 3V3
  2. Fingerprint Sensor

    • Description: A sensor used to capture fingerprint images.
    • Pins: SPI_DO, VDD, RST_N, SPI_CK, GND, SPI_DI, SPI_CS_N, ESD drain
  3. SD Module

    • Description: A module for interfacing with an SD card for data storage.
    • Pins: GND, VCC (5V), MISO (D12), MOSI (D11), SCK (D13), CS (D10)
  4. Pushbutton

    • Description: A simple pushbutton used to trigger actions in the circuit.
    • Pins: Pin 2, Pin 1, Pin 3, Pin 4

Wiring Details

ESP32 (30 pin)

Fingerprint Sensor

SD Module

Pushbutton

Documented Code

#include <SPI.h>
#include <SD.h>

// Definição de pinos do ESP32
#define SENSOR_SPI_CS 5      // GPIO5 -> CS do sensor FPC1011F3
#define SENSOR_RST 22        // GPIO22 -> Reset do sensor FPC1011F3
#define SD_CS 4              // GPIO4 -> CS do módulo SD Card
#define BUTTON_PIN 21        // GPIO21 -> Botão de captura
#define SPI_MISO 19          // GPIO19 -> MISO (compartilhado entre SD e sensor)
#define SPI_MOSI 23          // GPIO23 -> MOSI (compartilhado entre SD e sensor)
#define SPI_SCLK 18          // GPIO18 -> SCLK (compartilhado entre SD e sensor)

// Parâmetros do sensor
#define IMAGE_ROWS 200       // Linhas da matriz do sensor
#define IMAGE_COLS 152       // Colunas da matriz do sensor
uint8_t fingerprintImage[IMAGE_ROWS][IMAGE_COLS];

// Comandos do sensor FPC1011F3
#define CMD_CAPTURE_IMAGE 0x11
#define CMD_READ_DATA 0x20

void setup() {
  Serial.begin(115200);

  // Configuração dos pinos do ESP32
  pinMode(SENSOR_SPI_CS, OUTPUT);
  pinMode(SENSOR_RST, OUTPUT);
  pinMode(SD_CS, OUTPUT);
  pinMode(BUTTON_PIN, INPUT_PULLUP);  // Configura o botão com pull-up interno
  digitalWrite(SENSOR_SPI_CS, HIGH);  // Desativa o CS do sensor
  digitalWrite(SENSOR_RST, HIGH);     // Desativa o reset do sensor
  digitalWrite(SD_CS, HIGH);          // Desativa o CS do SD Card

  // Inicialização da SPI
  SPI.begin(SPI_SCLK, SPI_MISO, SPI_MOSI, SENSOR_SPI_CS);

  // Reset do sensor
  resetSensor();
  Serial.println("Sensor initialized!");

  // Inicialização do SD Card
  if (!SD.begin(SD_CS)) {
    Serial.println("SD Card initialization failed! Check connections.");
    while (1);  // Para execução se o SD Card falhar
  }
  Serial.println("SD Card initialized.");
}

void loop() {
  // Aguarda o botão ser pressionado
  if (digitalRead(BUTTON_PIN) == LOW) {
    Serial.println("Button pressed! Capturing fingerprint...");

    // Captura a imagem da impressão digital
    startCapture();
    delay(100);

    // Lê os dados capturados e armazena na matriz
    readFingerprintData();
    Serial.println("Fingerprint image captured!");

    // Salva a matriz no cartão SD como arquivo BMP
    saveFingerprintToSD();

    // Evita múltiplas capturas enquanto o botão ainda estiver pressionado
    while (digitalRead(BUTTON_PIN) == LOW);
    delay(200);  // Debounce para evitar leituras múltiplas rápidas
  }
}

void resetSensor() {
  digitalWrite(SENSOR_RST, LOW);  // Ativa reset do sensor
  delay(10);
  digitalWrite(SENSOR_RST, HIGH); // Desativa reset do sensor
  delay(100);
}

void startCapture() {
  digitalWrite(SENSOR_SPI_CS, LOW);  // Seleciona o sensor
  SPI.transfer(CMD_CAPTURE_IMAGE);   // Comando para iniciar captura
  SPI.transfer(0x00);                // Byte vazio para completar a transação
  digitalWrite(SENSOR_SPI_CS, HIGH); // Desseleciona o sensor
}

void readFingerprintData() {
  digitalWrite(SENSOR_SPI_CS, LOW);  // Seleciona o sensor
  SPI.transfer(CMD_READ_DATA);       // Comando para ler dados
  SPI.transfer(0x00);                // Byte vazio para iniciar leitura

  for (int row = 0; row < IMAGE_ROWS; row++) {
    for (int col = 0; col < IMAGE_COLS; col++) {
      fingerprintImage[row][col] = SPI.transfer(0x00);  // Lê um byte por pixel
    }
  }

  digitalWrite(SENSOR_SPI_CS, HIGH); // Desseleciona o sensor
}

void saveFingerprintToSD() {
  String fileName = "/fingerprint.bmp";  // Nome do arquivo
  File file = SD.open(fileName, FILE_WRITE);

  if (file) {
    Serial.println("Saving fingerprint image to SD card...");

    // Grava o cabeçalho BMP
    writeBMPHeader(file);

    // Grava a matriz da imagem
    for (int row = IMAGE_ROWS - 1; row >= 0; row--) {  // BMP é salvo de baixo para cima
      for (int col = 0; col < IMAGE_COLS; col++) {
        file.write(fingerprintImage[row][col]);
      }
    }

    file.close();
    Serial.println("Fingerprint image saved!");
  } else {
    Serial.println("Failed to open file for writing.");
  }
}

void writeBMPHeader(File &file) {
  uint32_t fileSize = 54 + IMAGE_ROWS * IMAGE_COLS;  // Cabeçalho (54 bytes) + dados
  uint32_t pixelDataOffset = 54;                     // Offset do início dos pixels
  uint32_t dibHeaderSize = 40;                       // Tamanho do DIB header
  uint16_t planes = 1;                               // Número de planos de cor
  uint16_t bpp = 8;                                  // Bits por pixel (8 = escala de cinza)

  // Assinatura BMP
  file.write('B');
  file