Engineers Garage

  • Electronic Projects & Tutorials
    • Electronic Projects
      • Arduino Projects
      • AVR
      • Raspberry pi
      • ESP8266
      • BeagleBone
      • 8051 Microcontroller
      • ARM
      • PIC Microcontroller
      • STM32
    • Tutorials
      • Audio Electronics
      • Battery Management
      • Brainwave
      • Electric Vehicles
      • EMI/EMC/RFI
      • Hardware Filters
      • IoT tutorials
      • Power Tutorials
      • Python
      • Sensors
      • USB
      • VHDL
    • Circuit Design
    • Project Videos
    • Components
  • Articles
    • Tech Articles
    • Insight
    • Invention Stories
    • How to
    • What Is
  • News
    • Electronic Product News
    • Business News
    • Company/Start-up News
    • DIY Reviews
    • Guest Post
  • Forums
    • EDABoard.com
    • Electro-Tech-Online
    • EG Forum Archive
  • DigiKey Store
    • Cables, Wires
    • Connectors, Interconnect
    • Discrete
    • Electromechanical
    • Embedded Computers
    • Enclosures, Hardware, Office
    • Integrated Circuits (ICs)
    • Isolators
    • LED/Optoelectronics
    • Passive
    • Power, Circuit Protection
    • Programmers
    • RF, Wireless
    • Semiconductors
    • Sensors, Transducers
    • Test Products
    • Tools
  • Learn
    • eBooks/Tech Tips
    • Design Guides
    • Learning Center
    • Tech Toolboxes
    • Webinars & Digital Events
  • Resources
    • Digital Issues
    • EE Training Days
    • LEAP Awards
    • Podcasts
    • Webinars / Digital Events
    • White Papers
    • Engineering Diversity & Inclusion
    • DesignFast
  • Guest Post Guidelines
  • Advertise
  • Subscribe

How to build an Arduino-based biometric voting machine

By Nikhil Agnihotri March 5, 2024

Typical electronic voting machines require voters to push a button to cast their ballots. However, there have been security concerns with these devices and whether they’re at risk for tampering. One solution is to use biometric-based voting machines, which use fingerprint matching or a retina scan to verify an authorized voter. 

In this project, we’ll develop a biometric voting machine based on a person’s fingerprint. We’ll build the device using Arduino Mega, with a 3.5-inch TFT touchscreen and R307 fingerprint module. The touchscreen will be the user interface for the “voter” to cast their ballot. 

Required components 

  1. Arduino Mega x1
  2. 3.5-inch TFT touchscreen for Arduino x1
  3. R307 fingerprint sensor x1

Circuit connections
To build a biometric voting machine, we must first interface the 3.5-inch TFT touchscreen and R307 fingerprint sensor with Arduino Mega. The touchscreen is an Arduino shield that fits over the board. 

To interface the fingerprint sensor:

  • Connect the R307 sensor’s VCC and GND pins with Arduino’s 5Vout and ground pins.
  • Connect the R307 sensor’s TX and RX pins with Arduino’s RX1 and TX1. 

The circuit connections are shown in the diagram below. 

Uploading the fingerprints
After making circuit connections, we must “enroll” the fingerprints of valid voters. Upload the following sketch in Arduino MEAG and a single fingerprint of each voter.

To learn more about interfacing the R307 sensor, and how to enroll and match fingerprints on it, check out this project.

Preparing the voting machine
After the authorized voters’ fingerprints have been enrolled, it’s time to prepare the voting machine to receive ballots. We’ll use the 3.5-inch TFT touchscreen as the user interface. 

To calibrate the touchscreen:

  • Install the Adafruit_GFX.h and MCUFRIEND_kbv.h libraries to Arduino IDE 
  • Navigate to File-> Examples -> MCUFRIEND_kbv -> Touchscreen_Calibr_native

  • Upload the example sketch to Arduino Mega.
  • Open Arduino IDE’s Serial Monitor and touch the corner points on the touchscreen as indicated by the + signs using a stylus.

You must note down the values for XP, XM, YP, YM, TS_LEFT,TS_RT, TS_TOP, and TS_BOT. It’s important to copy these values from the Serial Monitor and save them in a text file for later use.

For our touchscreen, the variables were found to have the following values:

  • const int XP=6,XM=A2,YP=A1,YM=7; //320×480 ID=0x9486
  • const int TS_LEFT=931,TS_RT=168,TS_TOP=452,TS_BOT=191;

Next, upload the following sketch in Arduino Mega, so it functions as a biometric voting machine.

How it works
The first uploaded sketch sets up an “admin” on Arduino IDE’s Serial Monitor for enrolling the fingerprints of authorized voters. The R307 fingerprint sensor allows up to 128 fingerprints indexed from 0 to 127. 

The machine must be prepared for voting next by calibrating the touchscreen using the example sketch. After the final sketch is uploaded, Arduino resets. It then displays the user interface where voters can select one of three candidates. 

When a voter presses the button on the touchscreen beside their preferred candidate, another screen appears on the TFT display, prompting a fingerprint scan. The voter must place their index finger on the fingerprint sensor. The sensor will flash an LED, capturing an image of their fingerprint. 

If the fingerprint matches with an enrolled print, the vote is counted, and a screen thanking the voter appears on the TFT display. If the voter is not enrolled, the message “Sorry, you cannot vote.” will appear on the TFT display. 

Afterward, the main screen reappears, allowing others to cast their ballots.

The code
The main sketch begins by importing Adafruit_GFX.h, MCUFRIEND_kbv.h, TouchScreen.h, and EEPROM.h libraries. The Adafruit_GFX.h and MCUFRIEND_kbv.h are required to operate the 3.5-inch TFT display. The TouchScreen.h is required for the touchscreen to function as a voting device. The EEPROM.h library is used to store the votes in the Arduino’s EEPROM memory.

The following lines of code define the serial port for communication with the R307 sensor, instantiating an object for the proper fingerprint matching.

#include <Adafruit_Fingerprint.h>
#if (defined(__AVR__) || defined(ESP8266)) && !defined(__AVR_ATmega2560__)
SoftwareSerial mySerial(2, 3);
#else
#define mySerial Serial1
#endif
Adafruit_Fingerprint finger = Adafruit_Fingerprint(&mySerial);

This is followed by defining variables, which store the total number of votes for the three candidates. The following lines of code define the color constants for the TFT display and instantiate a display object.

#define  BLACK   0x0000
#define BLUE    0x001F
#define RED     0xF800
#define GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE   0xFFFF
MCUFRIEND_kbv tft

Next, the constants are defined for the touchscreen function and the instantiation of a touch object.

#define MINPRESSURE 10
#define MAXPRESSURE 1000
const int XP=6,XM=A2,YP=A1,YM=7; //320×480 ID=0x9486
const int TS_LEFT=931,TS_RT=168,TS_TOP=452,TS_BOT=191;
#define TS_MINX 125
#define TS_MINY 85
#define TS_MAXX 965
#define TS_MAXY 905
TouchScreen ts(XP, YP, XM, YM, 300);   //re-initialised after diagnose
TSPoint tp;                            //global point

In the setup() function, the TFT screen is initialized using following code.

tft.reset();
tft.begin(tft.readID());
tft.setRotation(2);

The fingerprint sensor is initialized using the following lines of code in the setup() function.

Serial.begin(9600);
  Serial.println();
  Serial.print(“reading id…”);
  delay(500);
  Serial.println(tft.readID(), HEX);
  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); }
  }

Finally, the voter’s user interface for voting is displayed on the TFT screen, using the following.

tft.fillScreen(BLACK);
  Home();
  pinMode(13, OUTPUT);
  result();

The Home() function defines and displays the main screen of the voting machine, where voters can cast their vote for one of the three candidates.

void Home()
{
  tft.fillScreen(BLACK);
  tft.drawRoundRect(0, 0, 320, 480, 8, WHITE);   //Page border
  tft.setCursor(105, 5);
  tft.setTextSize(3);
  tft.setTextColor(CYAN);
  tft.print(“Voting”);
  tft.setCursor(97, 29);
  tft.print(“Machine”);

  tft.drawRoundRect(35, 70, 250, 50, 8, WHITE);  //Vote
  tft.fillRoundRect(35, 70, 250, 50, 8, YELLOW);
  tft.setTextSize(3);
  tft.setTextColor(WHITE);
  tft.setCursor(60, 82);
  tft.print(“Candidate 1”);

  tft.drawRoundRect(35, 160, 250, 50, 8, WHITE);  //Enroll
  tft.fillRoundRect(35, 160, 250, 50, 8, YELLOW);
  tft.setCursor(60, 172);
  tft.print(“Candidate 2”);

  tft.drawRoundRect(35, 250, 250, 50, 8, WHITE);
  tft.fillRoundRect(35, 250, 250, 50, 8, YELLOW);   //Result
  tft.setCursor(60, 262);
  tft.print(“Candidate 3”);
}

The user interface is defined according to the 3.5-inch TFT touchscreen’s resolution, which is 480×320 pixels.

Screen1() defines the user interface screen, prompting a voter to scan their index finger for authentication.

void screen1()
{
  tft.fillScreen(BLACK);
  tft.setTextSize(3);
  tft.setTextColor(WHITE);
  tft.setCursor(70, 190);
  tft.print(“Please Scan”);
  tft.setCursor(70, 240);
  tft.print(“Your Finger”);
  Serial.println(“Please press finger”);
}

Screen2() defines the user interface, which appears when the user is not validated as an enrolled voter.

void screen2()
{
  Serial.println(“Finger not found”);
  tft.fillScreen(BLACK);
  tft.setTextSize(3);
  tft.setCursor(70, 190);
  tft.print(“Sorry You”);
  tft.setCursor(70, 240);
  tft.print(“Can’t Vote”);
  delay(3000);
  Home();
}

The fingerprintMatch() function scans and matches fingerprints on call and returns TRUE if the fingerprint is matched, and FALSE if it’s not.

bool fingerprintMatch(){
  screen1();
delay(5000);
  uint8_t p = finger.getImage();
  if (p == FINGERPRINT_NOFINGER)  goto NoFinger;
  else if (p == FINGERPRINT_OK) {
    p = finger.image2Tz();
    if (p != FINGERPRINT_OK)  goto NoMatch;
    p = finger.fingerFastSearch();
    if (p != FINGERPRINT_OK)  goto NoMatch;
    Serial.print(“Verified ID:”);
    Serial.println(finger.fingerID);
    delay(1500);
    return true;
}
NoMatch:
{
return false;
}
NoFinger:
{
Serial.println(“No finger detected”);
delay(1500);
return false;
}
}

In the loop() function, a HIGH-to-LOW signal is sent on the GPIO13 pin interfaced with the touchscreen to initiate touch sensing. An object for the touch function is initialized. If the pressure exerted by the voter on the touchscreen is above a specific threshold, the pixel positions are mapped.

During the testing phase, these pixel positions are printed to the Serial console to determine the exact touch points for the buttons (in the user interface) for the three candidates. Later, these lines of code are commented.

digitalWrite(13, HIGH);
  digitalWrite(13, LOW);
  TSPoint p = ts.getPoint();
  // if sharing pins, you’ll need to fix the directions of the touchscreen pins
  //pinMode(XP, OUTPUT);
  //pinMode(YM, OUTPUT);
  pinMode(XM, OUTPUT);
  pinMode(YP, OUTPUT);

  if (p.z > ts.pressureThreshhold)
    {
      p.x = map(p.x, TS_MAXX, TS_MINX, 0, 320);
      p.y = map(p.y, TS_MAXY, TS_MINY, 0, 240);
      //Serial.print(“X:”);  // I used this to get the accurate touch points for X and Y axis
      //Serial.print(p.x);
      //Serial.print(”  “);
      //Serial.print(“Y:”);
      //Serial.println(p.y);

If the touch points correspond to ‘candidate1,’ the voter’s fingerprint is verified to complete the voting process. The display returns to the voting window whether the vote is accepted (and valid) or rejected.

if (p.x > 50 && p.x < 280 && p.y > 160 && p.y < 190  && p.z > MINPRESSURE && p.z < MAXPRESSURE)
        {
          Serial.println(“Candidate 1”);
          if(fingerprintMatch())
          {
            vote1++;
            EEPROM.write(0, vote1);
            tft.fillScreen(BLACK);
            tft.setCursor(70, 220);
            tft.print(“Thank You”);
            delay(3000);
            Home();  
          }
        else  
          {
            screen2();
          }
        }

The same is done for other two candidates. The voting results are printed to Serial console on a reset as the results are saved in EEPROM. The results are calculated by the results() function.

void result()
{
  vote1=EEPROM.read(0);
  vote2=EEPROM.read(1);
vote3=EEPROM.read(2);
  int vote=vote1+vote2+vote3;
  Serial.println(vote1);
  Serial.println(vote2);
  Serial.println(vote3);
 if(vote)
           {
            if((vote1 > vote2 && vote1 > vote3))
            {
             Serial.print(“Candidate 1 Wins”);
             delay(2000);
        }
            else if(vote2 > vote1 && vote2 > vote3)
            {
             Serial.print(“Candidate 2 Wins”);
             delay(2000);
            }
            else if((vote3 > vote1 && vote3 > vote2))
            {
             Serial.print(“Candidate 3 Wins”);
             delay(2000);
            }
           else
       {
             Serial.print(“Tie Up Or”);
             Serial.print(“No Result”);
             delay(1000);
           }
          }      
           else
           {
             Serial.print(“No Voting….”);
             delay(1000);
           }
  }

Results

Demonstration video:

 

Below is a screenshot of the voting process in the Serial console for the above demonstration.

 

You may also like:

  • R30X fingerprint scanner
    How to enroll and match fingerprint templates with Adafruit and…
  • beginners guide
    Basic Electronics 01 – Beginners guide to setting up an…

  • How to build a facial recognition system using ESP32-CAM

  • What are different types of biometric sensors?

  • What are the different types of fingerprint scanners?

  • Arduino enabled electronic voting machine (EVM)

Filed Under: Arduino Projects, Electronic Projects, Video
Tagged With: Arduino, arduinomega, ballots, electronicprojects, fingerprints, r307, sensor, voting, votingmachine
 

Next Article

← Previous Article
Next Article →

Questions related to this article?
👉Ask and discuss on EDAboard.com and Electro-Tech-Online.com forums.



Tell Us What You Think!! Cancel reply

You must be logged in to post a comment.

EE TECH TOOLBOX

“ee
Tech Toolbox: 5G Technology
This Tech Toolbox covers the basics of 5G technology plus a story about how engineers designed and built a prototype DSL router mostly from old cellphone parts. Download this first 5G/wired/wireless communications Tech Toolbox to learn more!

EE Learning Center

EE Learning Center
“engineers
EXPAND YOUR KNOWLEDGE AND STAY CONNECTED
Get the latest info on technologies, tools and strategies for EE professionals.

HAVE A QUESTION?

Have a technical question about an article or other engineering questions? Check out our engineering forums EDABoard.com and Electro-Tech-Online.com where you can get those questions asked and answered by your peers!


RSS EDABOARD.com Discussions

  • Single ended measuring ports and balanced antenna
  • Right Half Plane Zero
  • Thermal modelling of repetitive power pulse
  • Testing 5kW Grid Tied inverter over 200-253VAC
  • Resistor Selection for Amplifier Layout

RSS Electro-Tech-Online.com Discussions

  • Fun with AI and swordfish basic
  • Can I make two inputs from one??
  • Simple LED Analog Clock Idea
  • Is AI making embedded software developers more productive?
  • Behlke swich

Featured – LoRa/LoRaWan Series

  • What is the LoRaWAN network and how does it work?
  • Understanding LoRa architecture: nodes, gateways, and servers
  • Revolutionizing RF: LoRa applications and advantages
  • How to build a LoRa gateway using Raspberry Pi
  • How LoRa enables long-range communication
  • How communication works between two LoRa end-node devices

Recent Articles

  • RPi Python Programming 21: The SIM900A AT commands
  • RPi Python Programming 22: Calls & SMS using a SIM900A GSM-GPRS modem
  • RPi Python Programming 23: Interfacing a NEO-6MV2 GPS module with Raspberry Pi
  • RPi Python Programming 24: I2C explained
  • RPi Python Programming 25 – Synchronous serial communication in Raspberry Pi using I2C protocol

EE ENGINEERING TRAINING DAYS

engineering

Submit a Guest Post

submit a guest post
Engineers Garage
  • Analog IC TIps
  • Connector Tips
  • Battery Power Tips
  • DesignFast
  • EDABoard Forums
  • EE World Online
  • Electro-Tech-Online Forums
  • EV Engineering
  • Microcontroller Tips
  • Power Electronic Tips
  • Sensor Tips
  • Test and Measurement Tips
  • 5G Technology World
  • Subscribe to our newsletter
  • About Us
  • Contact Us
  • Advertise

Copyright © 2025 WTWH Media LLC. All Rights Reserved. The material on this site may not be reproduced, distributed, transmitted, cached or otherwise used, except with the prior written permission of WTWH Media
Privacy Policy

Search Engineers Garage

  • Electronic Projects & Tutorials
    • Electronic Projects
      • Arduino Projects
      • AVR
      • Raspberry pi
      • ESP8266
      • BeagleBone
      • 8051 Microcontroller
      • ARM
      • PIC Microcontroller
      • STM32
    • Tutorials
      • Audio Electronics
      • Battery Management
      • Brainwave
      • Electric Vehicles
      • EMI/EMC/RFI
      • Hardware Filters
      • IoT tutorials
      • Power Tutorials
      • Python
      • Sensors
      • USB
      • VHDL
    • Circuit Design
    • Project Videos
    • Components
  • Articles
    • Tech Articles
    • Insight
    • Invention Stories
    • How to
    • What Is
  • News
    • Electronic Product News
    • Business News
    • Company/Start-up News
    • DIY Reviews
    • Guest Post
  • Forums
    • EDABoard.com
    • Electro-Tech-Online
    • EG Forum Archive
  • DigiKey Store
    • Cables, Wires
    • Connectors, Interconnect
    • Discrete
    • Electromechanical
    • Embedded Computers
    • Enclosures, Hardware, Office
    • Integrated Circuits (ICs)
    • Isolators
    • LED/Optoelectronics
    • Passive
    • Power, Circuit Protection
    • Programmers
    • RF, Wireless
    • Semiconductors
    • Sensors, Transducers
    • Test Products
    • Tools
  • Learn
    • eBooks/Tech Tips
    • Design Guides
    • Learning Center
    • Tech Toolboxes
    • Webinars & Digital Events
  • Resources
    • Digital Issues
    • EE Training Days
    • LEAP Awards
    • Podcasts
    • Webinars / Digital Events
    • White Papers
    • Engineering Diversity & Inclusion
    • DesignFast
  • Guest Post Guidelines
  • Advertise
  • Subscribe