Hi, I am new to Arduino and programming etc but I am trying to develop an RFID system to lock and unlock tool cabinets at work. I am using an Elegoo Uno R3 and a data logger shield with DS1307 and an RC522 RFID reader.
I have managed to piece together code from various sources along with some of my own alterations.
This uses a master card to add or remove other cards to an array that is stored in the eeprom. I also want to store the date, time and UID of each access event to an SD card.
I have got the code working for the master card access and eeprom storage working, and I have also got the SD logging working separately but when I combine the two pieces of code everything works as it should except that the servo stops working. I have noted the part that, when incorporated, causes the issue.
Can anyone help me to understand if there is some conflict in my code that is doing this or if there is another issue?
As I am writing this it has occurred to me that maybe it's a power issue, I am only powering this from the USB port. Is it possible that this can't support both the servo and the SD together? Also if I try powering with a 9v battery nothing works, my red LED on my breadboard just flashes slowly, no idea why.
I would really appreciate any help you guys can give. Thanks.
//RFID Based Solenoid Door lock using Arduino
//The IoT Projects https://www.youtube.com/c/TheIoTProjects
//website:https://iotprojectsideas.com/
//RFID RC522 Master Card, Add and Remove multiple Cards
#include <SPI.h>
#include <Wire.h>
#include <MFRC522.h>
#include <Servo.h>
#include <SD.h>
#include <EEPROM.h>
#include <I2C_RTC.h>
#define RST_PIN 9
#define SS_PIN 2
#define SERVO_PIN A5
#define STATE_STARTUP 0
#define STATE_STARTING 1
#define STATE_WAITING 2
#define STATE_SCAN_INVALID 3
#define STATE_SCAN_VALID 4
#define STATE_SCAN_MASTER 5
#define STATE_ADDED_CARD 6
#define STATE_REMOVED_CARD 7
#define REDPIN 4
#define GREENPIN 5
#define BUZZER 7
File dataFile;
Servo servo;
int angle = 0; //current angle of servo motor
const int chipSelect = 10; // SD card CS pin connected to pin 10 of Arduino
const int cardArrSize = 6; // Number of stored card UID's allowed??
const int cardSize = 4; // Number of no. sections
byte cardArr[cardArrSize][cardSize];
byte masterCard[cardSize] = {41,33,216,90}; //Change Master Card ID
byte readCard[cardSize];
byte cardsStored = 0;
static DS1307 RTC;
// Create MFRC522 instance
MFRC522 mfrc522(SS_PIN, RST_PIN);
// Set the LCD I2C address
byte currentState = STATE_STARTUP;
unsigned long LastStateChangeTime;
unsigned long StateWaitTime;
//------------------------------------------------------------------------------------
int readCardState()
{
int index;
Serial.print("Card Data - ");
for(index = 0; index < 4; index++)
{
readCard[index] = mfrc522.uid.uidByte[index];
// Print a comma after the first three uid numbers
Serial.print(readCard[index]);
if (index < 3)
{
Serial.print(",");
}
}
Serial.println(" ");
//Check Master Card
if ((memcmp(readCard, masterCard, 4)) == 0)
{
return STATE_SCAN_MASTER;
}
if (cardsStored == 0)
{
return STATE_SCAN_INVALID;
}
for(index = 0; index < cardsStored; index++)
{
if ((memcmp(readCard, cardArr[index], 4)) == 0)
{
return STATE_SCAN_VALID;
}
}
return STATE_SCAN_INVALID;
}
//------------------------------------------------------------------------------------
void addReadCard()
{
int cardIndex;
int index;
if (cardsStored <= 20)
{
cardsStored++;
cardIndex = cardsStored;
cardIndex--;
}
for (index = 0; index < 4; index++)
{
cardArr[cardIndex][index] = readCard[index];
}
// Write the updated card list to EEPROM
EEPROM.write(0, cardsStored);
for (int i = 0; i < cardsStored; i++)
{
for (int j = 0; j < 4; j++)
{
EEPROM.write((i * 4) + j + 1, cardArr[i][j]);
}
}
//EEPROM.commit();
}
//------------------------------------------------------------------------------------
void removeReadCard()
{
int cardIndex;
int index;
boolean found = false;
if (cardsStored == 0)
{
return;
}
for (index = 0; index < cardsStored; index++)
{
if ((memcmp(readCard, cardArr[index], 4)) == 0)
{
found = true;
cardIndex = index;
}
}
if (found == true)
{
// Remove the card from the array
for (index = cardIndex; index < (cardsStored - 1); index++)
{
for (int j = 0; j < 4; j++)
{
cardArr[index][j] = cardArr[index + 1][j];
}
}
cardsStored--;
// Write the updated card list to EEPROM
EEPROM.write(0, cardsStored);
for (int i = 0; i < cardsStored; i++)
{
for (int j = 0; j < 4; j++)
{
EEPROM.write((i * 4) + j + 1, cardArr[i][j]);
}
}
//EEPROM.commit();
}
}
//------------------------------------------------------------------------------------
void updateState(byte aState)
{
if (aState == currentState)
{
return;
}
// do state change
switch (aState)
{
case STATE_STARTING:
StateWaitTime = 1000;
//digitalWrite(REDPIN, HIGH);
//digitalWrite(GREENPIN, LOW);
break;
case STATE_WAITING:
StateWaitTime = 0;
//digitalWrite(REDPIN, LOW);
//digitalWrite(GREENPIN, LOW);
break;
case STATE_SCAN_INVALID:
if (currentState == STATE_SCAN_MASTER)
{
addReadCard();
aState = STATE_ADDED_CARD;
StateWaitTime = 2000;
tone (BUZZER, 3000);
delay (200);
noTone (BUZZER);
addedLed();
//digitalWrite(REDPIN, LOW);
//digitalWrite(GREENPIN, HIGH);
}
else if (currentState == STATE_REMOVED_CARD)
{
return;
}
else
{
StateWaitTime = 2000;
//digitalWrite(REDPIN, HIGH);
//digitalWrite(GREENPIN, LOW);
tone (BUZZER, 3000);
delay (200);
noTone (BUZZER);
deniedLed();
}
break;
case STATE_SCAN_VALID:
if (currentState == STATE_SCAN_MASTER)
{
removeReadCard();
aState = STATE_REMOVED_CARD;
StateWaitTime = 2000;
tone (BUZZER, 3000);
delay (200);
noTone (BUZZER);
//digitalWrite(REDPIN, LOW);
//digitalWrite(GREENPIN, HIGH);
}
else if (currentState == STATE_ADDED_CARD)
{
return;
}
else
{
StateWaitTime = 2000;
//digitalWrite(REDPIN, LOW);
//digitalWrite(GREENPIN, HIGH);
changeServo();
timeStamp();
}
break;
case STATE_SCAN_MASTER:
StateWaitTime = 5000;
tone (BUZZER, 3000);
delay (200);
noTone (BUZZER);
delay (100);
tone (BUZZER, 3000);
delay (200);
noTone (BUZZER);
//digitalWrite(REDPIN, LOW);
//digitalWrite(GREENPIN, HIGH);
break;
}
currentState = aState;
LastStateChangeTime = millis();
}
void changeServo() {
// change angle of servo motor
if (angle == 0){
angle = 180;
digitalWrite(REDPIN, LOW);
digitalWrite(GREENPIN, HIGH);
}
else {//if(angle == 180)
angle = 0;
digitalWrite(REDPIN, HIGH);
digitalWrite(GREENPIN, LOW);
}
// control servo motor arccoding to the angle
servo.write(angle);
Serial.print("Rotate Servo Motor to ");
Serial.print(angle);
Serial.println("°");
}
void setup()
{
SPI.begin(); // Init SPI Bus
mfrc522.PCD_Init(); // Init MFRC522
servo.attach(SERVO_PIN);
servo.write(angle); // rotate servo to 0°
// Initialize the EEPROM
//EEPROM.begin(512);
// Read the stored card list from EEPROM
cardsStored = EEPROM.read(0);
if (cardsStored > cardArrSize)
{
cardsStored = 0;
}
for (int i = 0; i < cardsStored; i++)
{
for (int j = 0; j < 4; j++)
{
cardArr[i][j] = EEPROM.read((i * 4) + j + 1);
}
}
LastStateChangeTime = millis();
updateState(STATE_STARTING);
pinMode(REDPIN, OUTPUT);
pinMode(GREENPIN, OUTPUT);
pinMode(BUZZER, OUTPUT);
Serial.begin(9600);
/* RTC.begin();
RTC.setHourMode(CLOCK_H24);
RTC.setDate(31,8,24);
RTC.setTime(21,30,00);
SPI.begin(); // Init SPI bus
mfrc522.PCD_Init(); // Init MFRC522
// Setup for the SD card
Serial.print("Initialising SD card..."); // This section stops the servo from working
if(!SD.begin(chipSelect)) {
Serial.println("initialisation failed!");
return;
}
Serial.println("initialisation done.");
*/
dataFile = SD.open("LOGDATA.txt", FILE_WRITE); // Open file
// If file opened ok write to it:
if (dataFile){
Serial.println("File opened ok");
// Print headings for data
dataFile.println("Date, Time, UID");
}
dataFile.close(); // FIND OUT WHAT THESE ARE FOR!!
//Serial.println("CLEARDATA"); // Clears up any data left from previous projects
//Serial.println("LABEL, Date, Time, UID"); // Always write LABEL, to indicate it as first line
//Serial.println("RESETTIMER");
Serial.println("Tap RFID/NFC Tag on reader");
}
void loop()
{
byte cardState;
if ((currentState != STATE_WAITING) &&
(StateWaitTime > 0) &&
(LastStateChangeTime + StateWaitTime < millis()))
{
updateState(STATE_WAITING);
}
// Look for new cards
if ( ! mfrc522.PICC_IsNewCardPresent())
{
return;
}
// Select one of the cards
if ( ! mfrc522.PICC_ReadCardSerial())
{
return;
}
cardState = readCardState();
updateState(cardState);
}
void timeStamp() {
dataFile = SD.open("LOGDATA.txt", FILE_WRITE);
// IF THE FILE IS AVAILABLE, WRITE TO IT:
if (dataFile) {
dataFile.print(RTC.getDay());
dataFile.print("/"); // Move to next column using a ","
dataFile.print(RTC.getMonth());
dataFile.print("/"); // Move to next column using a ","
dataFile.print(RTC.getYear());
dataFile.print(","); // Move to next column using a ","
dataFile.print(RTC.getHours());
dataFile.print(":"); // Move to next column using a ","
dataFile.print(RTC.getMinutes());
dataFile.print(","); // Move to next column using a ","
// Prints cards UID to dataFile
for (int i = 0; i < mfrc522.uid.size; i++) {
dataFile.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
dataFile.print(mfrc522.uid.uidByte[i], HEX);
}
dataFile.println();
}
dataFile.close();
}
void deniedLed(){
if (angle == 180){
digitalWrite (REDPIN, LOW);
delay (200);
digitalWrite (REDPIN, HIGH);
delay (200);
digitalWrite (REDPIN, LOW);
delay (200);
digitalWrite (REDPIN, HIGH);
delay (200);
digitalWrite (REDPIN, LOW);
delay (200);
digitalWrite (REDPIN, HIGH);
delay (200);
digitalWrite (REDPIN, LOW);
delay (200);
digitalWrite (REDPIN, HIGH);
delay (200);
digitalWrite (REDPIN, LOW);
delay (200);
}
else {
digitalWrite (REDPIN, LOW);
delay (200);
digitalWrite (REDPIN, HIGH);
delay (200);
digitalWrite (REDPIN, LOW);
delay (200);
digitalWrite (REDPIN, HIGH);
delay (200);
digitalWrite (REDPIN, LOW);
delay (200);
digitalWrite (REDPIN, HIGH);
delay (200);
digitalWrite (REDPIN, LOW);
delay (200);
digitalWrite (REDPIN, HIGH);
delay (200);
digitalWrite (REDPIN, LOW);
delay (200);
digitalWrite (REDPIN, HIGH);
delay (200);
}
}
void addedLed(){
if (angle == 0){
digitalWrite (GREENPIN, LOW);
delay (200);
digitalWrite (GREENPIN, HIGH);
delay (200);
digitalWrite (GREENPIN, LOW);
delay (200);
digitalWrite (GREENPIN, HIGH);
delay (200);
digitalWrite (GREENPIN, LOW);
delay (200);
digitalWrite (GREENPIN, HIGH);
delay (200);
digitalWrite (GREENPIN, LOW);
delay (200);
digitalWrite (GREENPIN, HIGH);
delay (200);
digitalWrite (GREENPIN, LOW);
delay (200);
}
else {
digitalWrite (GREENPIN, LOW);
delay (200);
digitalWrite (GREENPIN, HIGH);
delay (200);
digitalWrite (GREENPIN, LOW);
delay (200);
digitalWrite (GREENPIN, HIGH);
delay (200);
digitalWrite (GREENPIN, LOW);
delay (200);
digitalWrite (GREENPIN, HIGH);
delay (200);
digitalWrite (GREENPIN, LOW);
delay (200);
digitalWrite (GREENPIN, HIGH);
delay (200);
digitalWrite (GREENPIN, LOW);
delay (200);
digitalWrite (GREENPIN, HIGH);
delay (200);
}
}