I am trying to store the timeIn and timeOut for each user every day. They need to have two timeIn and timeOut entries per day. I have tried to do this, but my Arduino keeps restarting for some reason.
Full Code:
#include <Adafruit_Fingerprint.h>
#include <EEPROM.h>
#include <LiquidCrystal_I2C.h>
#include "OneButton.h"
#include "uRTCLib.h"
LiquidCrystal_I2C lcd(0x27, 16, 2);
SoftwareSerial fingerSerial(2, 3);
uRTCLib rtc(0x68);
Adafruit_Fingerprint finger = Adafruit_Fingerprint(&fingerSerial);
OneButton pushButton = OneButton(A3, true, true);
int count = 1;
bool regMode = false;
String currentTime;
String currentDate;
uint8_t id;
struct FingerprintData {
int fingerprintIds[128];
};
void (*resetFunc)(void) = 0;
void setup() {
// put your setup code here, to run once:
// Initialize the modules
Serial.begin(9600);
// Initialize the lcd
lcd.init();
lcd.backlight();
displayText(false, 0, 0, F("Initializing"));
displayText(false, 0, 1, F("Data"));
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
// Initialize the fingeprint if not found then reboot the arduino
finger.begin(57600);
if (finger.verifyPassword()) {
displayText(true, 0, 0, F("Fingerprint"));
displayText(false, 1000, 1, F("Initialize"));
} else {
displayText(true, 0, 0, F("Fingerprint"));
displayText(false, 1000, 1, F("Not Initialize"));
displayText(false, 0, 0, F("Rebooting"));
displayText(false, 1000, 1, F("System"));
delay(1000);
resetFunc();
while (1) { delay(1); }
}
finger.getTemplateCount();
if (finger.templateCount == 0) {
displayText(true, 0, 0, F("No Finger"));
displayText(false, 2000, 1, F("Enrolled"));
} else {
displayText(true, 0, 0, String(finger.templateCount) + F(" Fingerprints"));
displayText(false, 2000, 1, F("Enrolled"));
}
displayText(true, 0, 0, F("Attendance"));
displayText(false, 0, 1, F("System"));
// Button Events
pushButton.attachClick(onSingleClick);
pushButton.attachDoubleClick(onDoubleClick);
pushButton.attachMultiClick(onMultiClick);
}
void loop() {
// put your main code here, to run repeatedly:
int result = getFingerprintIDez();
if (result > 0) {
displayText(true, 0, 0, F("Attendance"));
displayText(false, 1000, 1, F("Recorded"));
getTime();
String studentName = getNameFromID(result);
Serial.print(studentName.length());
displayText(true, 0, 0, F("Welcome"));
if (studentName.length() > 16) {
for (int i = 0; i <= studentName.length() - 16; i++) {
lcd.setCursor(0, 1);
lcd.print(studentName.substring(i, i + 16));
delay(400);
}
} else {
displayText(false, 2000, 1, studentName);
}
displayText(true, 0, 0, F("Attendance"));
displayText(false, 0, 1, F("System"));
return;
} else if (result == -2) {
displayText(true, 0, 0, F("Fingerprint"));
displayText(false, 1000, 1, F("Not Enrolled"));
displayText(true, 0, 0, F("Attendance"));
displayText(false, 0, 1, F("System"));
return;
}
pushButton.tick();
}
void storeFingerprint(int fingerprint) {
FingerprintData data;
int eeAddress = 0;
EEPROM.get(eeAddress, data);
for (int i = 0; i < 128; ++i) {
if (data.fingerprintIds[i] == fingerprint) {
Serial.println(F("Error: Fingerprint ID already exists!"));
return;
}
}
int i;
for (i = 0; i < 128; ++i) {
if (data.fingerprintIds[i] == 0) {
data.fingerprintIds[i] = fingerprint;
break;
}
}
if (i == 128) {
Serial.println(F("Error: No available slots to store the fingerprint ID!"));
return;
}
EEPROM.put(eeAddress, data);
}
FingerprintData readFingerprints() {
FingerprintData data;
int eeAddress = 0;
EEPROM.get(eeAddress, data);
Serial.println(F("Stored Fingerprint IDs:"));
for (int i = 0; i < 128; ++i) {
if (data.fingerprintIds[i] != 0) {
Serial.println(data.fingerprintIds[i]);
}
}
return data;
}
String getNameFromID(int fingerprintID) {
String studentName = "";
if (fingerprintID == 1) {
studentName = F("");
} else if (fingerprintID == 2) {
studentName = F("");
} else if (fingerprintID == 3) {
studentName = F("");
} else if (fingerprintID == 4) {
studentName = F("");
} else if (fingerprintID == 5) {
studentName = F("");
} else if (fingerprintID == 6) {
studentName = F("");
} else if (fingerprintID == 7) {
studentName = F("");
} else if (fingerprintID == 8) {
studentName = F("");
} else if (fingerprintID == 9) {
studentName = F("");
} else if (fingerprintID == 10) {
studentName = F("");
}
return studentName;
}
void getTime() {
rtc.refresh();
lcd.setCursor(0, 0);
lcd.print(F("Time: "));
int hour12 = rtc.hour() % 12;
if (hour12 == 0) {
hour12 = 12;
}
currentTime = String(hour12);
currentTime += ":";
if (rtc.minute() < 10) {
currentTime += "0";
}
currentTime += String(rtc.minute());
if (rtc.hour() < 12) {
currentTime += " AM";
} else {
currentTime += " PM";
}
lcd.print(currentTime);
lcd.setCursor(0, 1);
lcd.print(F("Date: "));
currentDate = String(rtc.month()) + "/" + rtc.day() + "/" + rtc.year();
lcd.print(currentDate);
delay(2000);
}
void incrementID() {
if (regMode) {
count++;
if (count > 128) {
count = 1;
}
}
}
void decrementID() {
if (regMode) {
count--;
if (count < 1) {
count = 1;
}
}
}
void centerText(int row, String text) {
int totalColumns = 16;
int textLength = text.length();
int startingColumn = (totalColumns - textLength) / 2;
lcd.setCursor(startingColumn, row);
lcd.print(text);
}
void displayText(bool clearScreen, int duration, int row, String text) {
if (clearScreen) {
lcd.clear();
}
centerText(row, text);
if (duration != 0) {
delay(duration);
lcd.clear();
}
}
void enroll() {
regMode = true;
displayText(true, 0, 0, F("Enter your ID:"));
while (regMode) {
displayText(false, 0, 1, String(count));
pushButton.tick();
}
}
void confirm() {
id = count;
FingerprintData data = readFingerprints();
bool idFound = false;
for (int i = 0; i < 128; ++i) {
if (data.fingerprintIds[i] == id) {
idFound = true;
break;
}
}
if (idFound) {
displayText(true, 0, 0, F("Fingerprint ID"));
displayText(false, 2000, 1, F("Already Used"));
displayText(true, 0, 0, F("Select Another"));
displayText(false, 2000, 1, F("ID"));
home();
} else {
displayText(true, 0, 0, F("Registering New"));
displayText(false, 2000, 1, F("ID Fingerprint"));
getFingerprintEnroll();
}
regMode = false;
}
void home() {
regMode = false;
count = 1;
displayText(true, 0, 0, F("Attendance"));
displayText(false, 0, 1, F("System"));
}
void onSingleClick() {
incrementID();
}
void onDoubleClick() {
decrementID();
}
void onMultiClick() {
int n = pushButton.getNumberClicks();
if (n == 3 && regMode) {
// Set back to home
home();
}
else if (n == 4 && !regMode) {
// Set to regMode
enroll();
}
else if (n == 5 && regMode) {
// Enroll the user
confirm();
}
else if (n == 10) {
displayText(true, 0, 0, F("Rebooting"));
displayText(false, 2000, 1, F("System"));
resetFunc();
}
}
uint8_t getFingerprintEnroll() {
int p = -1;
String flashString = F("Your ID: ");
String idString = String(id);
String combinedString = flashString + idString;
displayText(true, 1000, 0, combinedString);
displayText(false, 0, 0, F("Place your"));
displayText(false, 2000, 1, F("finger"));
while (p != FINGERPRINT_OK) {
p = finger.getImage();
switch (p) {
case FINGERPRINT_OK:
displayText(true, 0, 0, F("Image taken"));
break;
case FINGERPRINT_NOFINGER:
displayText(true, 0, 0, F("No Finger"));
displayText(false, 0, 1, F("Found"));
break;
case FINGERPRINT_PACKETRECIEVEERR:
displayText(true, 0, 0, F("Communication"));
displayText(false, 0, 1, F("Error"));
break;
case FINGERPRINT_IMAGEFAIL:
displayText(true, 0, 0, F("Imaging"));
displayText(false, 0, 1, F("Error"));
break;
default:
displayText(true, 0, 0, F("Unknown"));
displayText(false, 0, 1, F("Error"));
break;
}
}
// OK success!
p = finger.image2Tz(1);
switch (p) {
case FINGERPRINT_OK:
displayText(true, 0, 0, F("Image"));
displayText(false, 0, 1, F("Converted"));
break;
case FINGERPRINT_IMAGEMESS:
displayText(true, 0, 0, F("Image"));
displayText(false, 0, 1, F("Too Messy"));
return p;
case FINGERPRINT_PACKETRECIEVEERR:
displayText(true, 0, 0, F("Communication"));
displayText(false, 0, 1, F("Error"));
return p;
case FINGERPRINT_FEATUREFAIL:
displayText(true, 0, 0, F("Feature"));
displayText(false, 0, 1, F("Not Found"));
return p;
case FINGERPRINT_INVALIDIMAGE:
displayText(true, 0, 0, F("Feature"));
displayText(false, 0, 1, F("Not Found"));
return p;
default:
displayText(true, 0, 0, F("Unknown"));
displayText(false, 0, 1, F("Error"));
return p;
}
displayText(true, 0, 0, F("Remove your"));
displayText(false, 2000, 1, F("finger"));
p = 0;
while (p != FINGERPRINT_NOFINGER) {
p = finger.getImage();
}
p = -1;
displayText(true, 0, 0, F("Place your"));
displayText(false, 0, 1, F("Finger Again"));
while (p != FINGERPRINT_OK) {
p = finger.getImage();
switch (p) {
case FINGERPRINT_OK:
Serial.println(F("Image taken"));
break;
case FINGERPRINT_NOFINGER:
Serial.print(F("."));
break;
case FINGERPRINT_PACKETRECIEVEERR:
Serial.println(F("Communication error"));
break;
case FINGERPRINT_IMAGEFAIL:
Serial.println(F("Imaging error"));
break;
default:
Serial.println(F("Unknown error"));
return;
}
}
// OK success!
p = finger.image2Tz(2);
switch (p) {
case FINGERPRINT_OK:
Serial.println(F("Image converted"));
break;
case FINGERPRINT_IMAGEMESS:
Serial.println(F("Image too messy"));
return p;
case FINGERPRINT_PACKETRECIEVEERR:
Serial.println(F("Communication error"));
return p;
case FINGERPRINT_FEATUREFAIL:
Serial.println(F("Could not find fingerprint features"));
return p;
case FINGERPRINT_INVALIDIMAGE:
Serial.println(F("Could not find fingerprint features"));
return p;
default:
Serial.println(F("Unknown error"));
return p;
}
// OK converted!
Serial.print(F("Creating model for #"));
Serial.println(id);
p = finger.createModel();
if (p == FINGERPRINT_OK) {
Serial.println(F("Prints matched!"));
} else if (p == FINGERPRINT_PACKETRECIEVEERR) {
Serial.println(F("Communication error"));
return p;
} else if (p == FINGERPRINT_ENROLLMISMATCH) {
Serial.println(F("Fingerprints did not match"));
return p;
} else {
Serial.println(F("Unknown error"));
return p;
}
Serial.print(F("ID "));
Serial.println(id);
p = finger.storeModel(id);
if (p == FINGERPRINT_OK) {
storeFingerprint(id);
displayText(true, 0, 0, F("Your Fingerprint"));
displayText(false, 2000, 1, F("ID is Stored"));
id = 1;
count = 1;
displayText(false, 0, 0, F("Registering"));
displayText(false, 1000, 1, F("Data"));
resetFunc();
} else if (p == FINGERPRINT_PACKETRECIEVEERR) {
Serial.println(F("Communication error"));
return p;
} else if (p == FINGERPRINT_BADLOCATION) {
Serial.println(F("Could not store in that location"));
return p;
} else if (p == FINGERPRINT_FLASHERR) {
Serial.println(F("Error writing to flash"));
return p;
} else {
Serial.println(F("Unknown error"));
return p;
}
}
uint8_t getimg_data[] = { FINGERPRINT_GETIMAGE };
#define FINGERPRINT_COMMANDPACKET 0x1 //!< Command packet
Adafruit_Fingerprint_Packet packet(FINGERPRINT_COMMANDPACKET, sizeof(getimg_data), getimg_data);
const Adafruit_Fingerprint_Packet startPacket(FINGERPRINT_COMMANDPACKET, sizeof(getimg_data), getimg_data);
bool is_waiting_for_response = false;
int better_get_image() {
// Serial.println("Get better image()");
if (!is_waiting_for_response) {
packet = startPacket;
finger.writeStructuredPacket(packet);
is_waiting_for_response = true;
// Serial.println("Send command packet");
return -2; // nothing yet! :)
} else {
/* check if there is any serial data at all */
if (fingerSerial.available() == 0) {
/* FAST EXIT TO MAKE BUTTON WORK */
return -2;
}
// Serial.println("Got response");
// we definitely have some amount of data now, read it
if (finger.getStructuredPacket(&packet) != FINGERPRINT_OK) {
is_waiting_for_response = false;
return FINGERPRINT_PACKETRECIEVEERR;
}
// we have received something, so evaluate the result in all cases
is_waiting_for_response = false;
if (packet.type != FINGERPRINT_ACKPACKET)
return FINGERPRINT_PACKETRECIEVEERR;
return packet.data[0];
}
}
// returns -1 if failed, otherwise returns ID #
int getFingerprintIDez() {
uint8_t p = better_get_image();
if (p != FINGERPRINT_OK) return -1;
p = finger.image2Tz();
if (p != FINGERPRINT_OK) return -1;
p = finger.fingerFastSearch();
if (p == FINGERPRINT_OK) {
return finger.fingerID;
} else if (p == FINGERPRINT_NOTFOUND) {
return -2;
} else {
return -1;
}
}
The code that keeps resetting the arduino when the function is called
struct FingerprintData {
int fingerprintIds[128];
String timeIn[128];
String timeOut[128];
};
String getTimeIn(int fingerprint) {
Serial.print(String(fingerprint));
delay(2000);
FingerprintData data;
int eeAddress = 0;
EEPROM.get(eeAddress, data);
for (int i = 0; i < 128; ++i) {
if (data.fingerprintIds[i] == fingerprint) {
Serial.print(String(data.timeIn[i]));
return data.timeIn[i];
}
}
return "";
}
When called in loop and setup it resets the Arduino
getTimeIn(1);