#include <Adafruit_Fingerprint.h>
#include <Wire.h>
#define FINGERPRINT_SENSOR_PIN 2 // GPIO pin for fingerprint sensor
#define BUTTON1_PIN 12 // Push button 1: Candidate Registration
#define BUTTON2_PIN 13 // Push button 2: Voter Registration
#define BUTTON3_PIN 14 // Push button 3: Voter Login
#define BUTTON4_PIN 15 // Push button 4: Voting
#define LED_PIN 16 // LED Pin to indicate status
#define MAX_CANDIDATES 5 // Maximum number of candidates
#define MAX_VOTERS 100 // Maximum number of voters
// Candidate class
class Candidate {
public:
uint8_t id;
String name;
uint16_t votes; // Vote count for each candidate
Candidate() : id(0), name(""), votes(0) {}
};
// Voter class
class Voter {
public:
uint8_t id;
uint8_t fingerprintID;
Voter() : id(0), fingerprintID(0) {}
};
// EVMBase class
class EVMBase {
public:
// Constructor
EVMBase() : fingerprintSensor(nullptr), candidateCount(0), voterCount(0), loggedIn(false) {}
// Initialize the system
void begin();
// Main loop for handling button presses and user interaction
void loop();
// Candidate and voter arrays
Candidate candidates[MAX_CANDIDATES];
Voter voters[MAX_VOTERS];
uint8_t candidateCount;
uint8_t voterCount;
private:
// Fingerprint sensor instance
Adafruit_Fingerprint* fingerprintSensor;
// Login status flag
bool loggedIn;
// Core functions
void registerCandidate();
void registerVoter();
void voterLogin();
void castVote();
uint8_t captureFingerprint();
void indicateSuccess();
void indicateFailure();
};
// Create EVMBase object
EVMBase evm;
void setup() {
evm.begin(); // Initialize the EVM system
}
void loop() {
evm.loop(); // Main loop to handle operations
}
// Initialize the system
void EVMBase::begin() {
Serial.begin(115200); // Initialize Serial communication for debugging
// Initialize fingerprint sensor
fingerprintSensor = new Adafruit_Fingerprint(&Serial1);
fingerprintSensor->begin(57600);
if (fingerprintSensor->verifyPassword()) {
Serial.println("Fingerprint sensor initialized successfully.");
} else {
Serial.println("Error: Fingerprint sensor not responding!");
while (true); // Halt if the fingerprint sensor is not responding
}
// Initialize button pins
pinMode(BUTTON1_PIN, INPUT_PULLUP);
pinMode(BUTTON2_PIN, INPUT_PULLUP);
pinMode(BUTTON3_PIN, INPUT_PULLUP);
pinMode(BUTTON4_PIN, INPUT_PULLUP);
// Initialize LED pin
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, LOW);
}
// Main loop for handling button presses
void EVMBase::loop() {
if (digitalRead(BUTTON1_PIN) == LOW) {
Serial.println("Candidate Registration:");
registerCandidate();
delay(1000); // Debounce
}
if (digitalRead(BUTTON2_PIN) == LOW) {
Serial.println("Voter Registration:");
registerVoter();
delay(1000); // Debounce
}
if (digitalRead(BUTTON3_PIN) == LOW) {
Serial.println("Voter Login:");
voterLogin();
delay(1000); // Debounce
}
if (digitalRead(BUTTON4_PIN) == LOW) {
Serial.println("Cast Vote:");
castVote();
delay(1000); // Debounce
}
}
// Register a candidate
void EVMBase::registerCandidate() {
if (candidateCount >= MAX_CANDIDATES) {
Serial.println("Maximum number of candidates registered.");
indicateFailure();
return;
}
Serial.println("Enter candidate name:");
while (!Serial.available()); // Wait for user input
String name = Serial.readStringUntil('\n');
name.trim();
if (name.isEmpty()) {
Serial.println("Candidate name cannot be empty.");
indicateFailure();
return;
}
candidates[candidateCount].id = candidateCount + 1;
candidates[candidateCount].name = name;
candidateCount++;
Serial.println("Candidate registered: " + name);
indicateSuccess();
}
// Register a voter
void EVMBase::registerVoter() {
if (voterCount >= MAX_VOTERS) {
Serial.println("Maximum number of voters registered.");
indicateFailure();
return;
}
Serial.println("Place your finger for registration:");
uint8_t fingerprintID = captureFingerprint();
if (fingerprintID > 0) {
for (uint8_t i = 0; i < voterCount; i++) {
if (voters[i].fingerprintID == fingerprintID) {
Serial.println("This fingerprint is already registered.");
indicateFailure();
return;
}
}
voters[voterCount].id = voterCount + 1;
voters[voterCount].fingerprintID = fingerprintID;
voterCount++;
Serial.println("Voter registered successfully.");
indicateSuccess();
} else {
Serial.println("Fingerprint registration failed.");
indicateFailure();
}
}
// Authenticate voter login
void EVMBase::voterLogin() {
Serial.println("Place your finger to log in:");
uint8_t fingerprintID = captureFingerprint();
if (fingerprintID > 0) {
for (uint8_t i = 0; i < voterCount; i++) {
if (voters[i].fingerprintID == fingerprintID) {
loggedIn = true;
Serial.println("Login successful. Welcome, voter ID: " + String(voters[i].id));
indicateSuccess();
return;
}
}
Serial.println("Voter not registered.");
} else {
Serial.println("Fingerprint not recognized.");
}
loggedIn = false;
indicateFailure();
}
// Cast a vote
void EVMBase::castVote() {
if (!loggedIn) {
Serial.println("You must be logged in to vote.");
indicateFailure();
return;
}
if (candidateCount == 0) {
Serial.println("No candidates available for voting.");
indicateFailure();
return;
}
Serial.println("Select a candidate to vote for:");
for (uint8_t i = 0; i < candidateCount; i++) {
Serial.println(String(i + 1) + ". " + candidates[i].name);
}
while (!Serial.available()); // Wait for user input
int choice = Serial.parseInt();
if (choice > 0 && choice <= candidateCount) {
candidates[choice - 1].votes++;
Serial.println("You voted for: " + candidates[choice - 1].name);
indicateSuccess();
} else {
Serial.println("Invalid choice. Vote not recorded.");
indicateFailure();
}
loggedIn = false; // Reset login status after voting
}
// Capture fingerprint
uint8_t EVMBase::captureFingerprint() {
if (fingerprintSensor->getImage() != FINGERPRINT_OK) return 0;
if (fingerprintSensor->image2Tz() != FINGERPRINT_OK) return 0;
if (fingerprintSensor->fingerFastSearch() != FINGERPRINT_OK) return 0;
return fingerprintSensor->fingerID;
}
// Indicate success
void EVMBase::indicateSuccess() {
digitalWrite(LED_PIN, HIGH);
delay(500);
digitalWrite(LED_PIN, LOW);
}
// Indicate failure
void EVMBase::indicateFailure() {
for (int i = 0; i < 3; i++) {
digitalWrite(LED_PIN, HIGH);
delay(200);
digitalWrite(LED_PIN, LOW);
delay(200);
}
}