#include <SD.h>
#include <SPI.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#define MAX_CANDIDATES 10
#define MAX_NAME_LENGTH 16
#define MAX_HOUSE_LENGTH 16
#define DATA_FILE "data.csv"
LiquidCrystal_I2C lcd(0x27, 16, 2);
enum buttons {LEFT=2, MID, RIGHT, RESULT};
enum output {BUZZER=7};
enum storage {CARD=10};
int numCandidates = 0;
int currentCandidateIndex = 0;
class Candidate {
public:
char name[MAX_NAME_LENGTH];
char house[MAX_HOUSE_LENGTH];
int votes;
Candidate() {
strcpy(name, "\0");
strcpy(house, "\0");
votes = 0;
}
Candidate(const char *cName, const char *cHouse, int cVotes = 0) {
strcpy(name, cName);
strcpy(house, cHouse);
votes = cVotes;
}
void addVote() {
votes++;
}
};
Candidate candidates[MAX_CANDIDATES];
void setup() {
Serial.begin(9600);
lcd.init();
lcd.backlight();
lcd.print("-VOTING SYSTEM-");
delay(2000);
if (!SD.begin(CARD)) {
Serial.println("SD Card not detected.");
return;
}
Serial.println("SD Card inserted.");
if (SD.exists(DATA_FILE)) {
loadCandidatesFromCSV();
} else {
addDefaultCandidates();
}
pinMode(LEFT, INPUT);
pinMode(MID, INPUT);
pinMode(RIGHT, INPUT);
pinMode(RESULT, INPUT);
pinMode(BUZZER, OUTPUT);
displayCurrentCandidate();
}
void loop() {
if (digitalRead(LEFT))
navigateCandidates(-1);
if (digitalRead(MID))
voteCurrentCandidate();
if (digitalRead(RIGHT))
navigateCandidates(1);
if (digitalRead(RESULT))
displayWinner();
}
void loadCandidatesFromCSV() {
File file = SD.open(DATA_FILE, FILE_READ);
if (!file) {
Serial.println("File could not be opened.");
return;
}
while (file.available()) {
String line = file.readStringUntil('\n');
line.trim();
if (line.length() == 0) continue;
int commaIndex1 = line.indexOf(',');
int commaIndex2 = line.lastIndexOf(',');
const char *name = line.substring(0, commaIndex1).c_str();
const char *house = line.substring(commaIndex1 + 1, commaIndex2).c_str();
int votes = line.substring(commaIndex2 + 1).toInt();
if (numCandidates < MAX_CANDIDATES)
{
Candidate tempCandidate(name, house, votes);
candidates[numCandidates++] = tempCandidate;
}
}
file.close();
}
void addDefaultCandidates() {
addCandidate("Aarav", "Red");
addCandidate("Sunita", "Blue");
addCandidate("Rajendra", "Green");
addCandidate("Anjali", "Blue");
addCandidate("Dinesh", "Red");
addCandidate("Kritika", "Green");
addCandidate("Bijay", "Red");
addCandidate("Sweta", "Blue");
addCandidate("Niraj", "Yellow");
addCandidate("Priya", "Yellow");
updateCSV();
}
void addCandidate(const char *name, const char *house) {
if (numCandidates < MAX_CANDIDATES)
{
Candidate tempCandidate(name, house);
candidates[numCandidates] = tempCandidate;
numCandidates++;
}
}
void navigateCandidates(int direction) {
currentCandidateIndex += direction;
if (currentCandidateIndex < 0)
currentCandidateIndex = numCandidates - 1;
if (currentCandidateIndex >= numCandidates)
currentCandidateIndex = 0;
displayCurrentCandidate();
tone(BUZZER, 4000, 25);
delay(300);
noTone(BUZZER);
}
void updateCSV() {
if (SD.exists(DATA_FILE))
SD.remove(DATA_FILE);
File file = SD.open(DATA_FILE, FILE_WRITE);
if (!file)
{
Serial.println("Could not open or write to the file.");
return;
}
else {
Serial.println("Written!");
}
for (int i = 0; i < numCandidates; i++)
{
file.print(candidates[i].name);
file.print(",");
file.print(candidates[i].house);
file.print(",");
file.println(candidates[i].votes);
}
file.close();
}
void voteCurrentCandidate() {
if (numCandidates > 0) {
candidates[currentCandidateIndex].addVote();
updateCSV();
lcd.clear();
lcd.print("Voted for");
lcd.setCursor(0, 1);
lcd.print(candidates[currentCandidateIndex].name);
tone(BUZZER, 4000, 3000);
delay(3000);
noTone(BUZZER);
lcd.clear();
lcd.print("PLEASE LEAVE...");
delay(4000);
currentCandidateIndex = 0;
displayCurrentCandidate();
}
delay(300);
}
void displayCurrentCandidate() {
lcd.clear();
if (numCandidates > 0) {
lcd.print(candidates[currentCandidateIndex].name);
lcd.setCursor(0, 1);
lcd.print(candidates[currentCandidateIndex].house);
}
else
lcd.print("No candidates");
}
void displayWinner() {
if (numCandidates > 0)
{
int maxVotes = 0;
int winnerIndex = 0;
for (int i = 0; i < numCandidates; i++)
if (candidates[i].votes > maxVotes)
{
maxVotes = candidates[i].votes;
winnerIndex = i;
}
lcd.clear();
lcd.print("Winner: ");
lcd.print(candidates[winnerIndex].name);
lcd.setCursor(0, 1);
lcd.print("Votes: ");
lcd.print(maxVotes);
}
}