#include <LiquidCrystal.h>
#include <SD.h>
#include <SPI.h>
#include <MFRC522.h>
#include <math.h>
const int RS = 31, EN = 33, D4 = 35, D5 = 37, D6 = 39, D7 = 41;
const int RFID_SS = 26, RFID_RST = 28;
const int SD_CS = 24, SD_VCC = 22;
const int MAXA = 255, BIT = 4, DOOR = 25, ADMIN = 23, BG = 29, OPEN_INDOOR = 27;
MFRC522 rfid(RFID_SS, RFID_RST);
MFRC522::MIFARE_Key key;
LiquidCrystal lcd(RS, EN, D4, D5, D6, D7);
byte nuidPICC[BIT], record[MAXA][BIT];
int num, new_time = 0;
unsigned long long skey = 0;
void lcdInit() //LCD屏幕初始化
{
int xyz = millis() / 1000;
xyz /= 5;
if(fmod(xyz, 2) == 0)
{
lcd.setCursor(0, 0);
lcd.print("Welcome To ");
lcd.setCursor(0, 1);
lcd.print("Star Grazers Lab");
}
if(fmod(xyz, 2) == 1)
{
lcd.setCursor(0, 0);
lcd.print("Please Check! ");
lcd.setCursor(0, 1);
lcd.print("R U my master? ");
}
}
void openWrong()//开门错误
{
digitalWrite(BG, HIGH);
new_time = millis() / 1000;
lcd.clear();
lcd.print("Wrong card!");
lcd.setCursor(0, 1);
lcd.print("You cant DG here");
delay(2500);
lcdInit();
}
void openDoor()//开门成功
{
digitalWrite(BG, HIGH);
new_time = millis() / 1000;
lcd.clear();
lcd.print("Right!!!");
lcd.setCursor(0, 1);
lcd.print("Come and DG,Dear");
digitalWrite(DOOR, LOW);
delay(2500);
digitalWrite(DOOR, HIGH);
lcdInit();
}
void getCard()//读取卡片
{
for(register int i = 0; i < MAXA; i++)
for(register int j = 0; j < 4; j++)
record[i][j] = 0;
num = 0;
int b = 0;
digitalWrite(SD_VCC, HIGH);
SD.begin(SD_CS);
File fileRead = SD.open("RFID.csv", FILE_READ);
while(fileRead.available())
{
char c = fileRead.read();
if(c >= '0' && c <= '9') record[num][b] = record[num][b] * 10 + c - '0';
if(c == ',') b++;
if(c == '\n')
{
b = 0;
num++;
}
}
digitalWrite(SD_VCC, LOW);
}
void insertCard()//管理员模式添加卡片
{
digitalWrite(BG, HIGH);
int before;
if ( ! rfid.PICC_IsNewCardPresent()) return;
if ( ! rfid.PICC_ReadCardSerial()) return;
MFRC522::PICC_Type piccType = rfid.PICC_GetType(rfid.uid.sak);
if (piccType != MFRC522::PICC_TYPE_MIFARE_MINI &&
piccType != MFRC522::PICC_TYPE_MIFARE_1K &&
piccType != MFRC522::PICC_TYPE_MIFARE_4K)
return;
lcd.clear();
lcd.print("wait to finish");
for (byte i = 0; i < 4; i++)
nuidPICC[i] = rfid.uid.uidByte[i];
digitalWrite(SD_VCC, HIGH);
delay(500);
SD.begin(SD_CS);
File myFile = SD.open("rfid.csv", FILE_WRITE);
myFile.print(nuidPICC[0]);
myFile.print(",");
myFile.print(nuidPICC[1]);
myFile.print(",");
myFile.print(nuidPICC[2]);
myFile.print(",");
myFile.println(nuidPICC[3]);
myFile.close();
digitalWrite(SD_VCC, LOW);
rfid.PICC_HaltA();
rfid.PCD_StopCrypto1();
before = num;
getCard();
lcd.clear();
if(before + 1 == num) lcd.print("Succeed!");
else lcd.print("Failed! Reset!");
delay(1500);
lcd.clear();
lcd.print("Administrator");
}
void readCard()//判断是否开门
{
if(abs(millis() / 1000 - new_time) > 10) digitalWrite(BG, LOW);
digitalWrite(DOOR, HIGH);
lcdInit();
bool right = false;
if ( ! rfid.PICC_IsNewCardPresent()) return;
if ( ! rfid.PICC_ReadCardSerial()) return;
MFRC522::PICC_Type piccType = rfid.PICC_GetType(rfid.uid.sak);
if (piccType != MFRC522::PICC_TYPE_MIFARE_MINI &&
piccType != MFRC522::PICC_TYPE_MIFARE_1K &&
piccType != MFRC522::PICC_TYPE_MIFARE_4K)
return;
for (byte i = 0; i < 4; i++)
nuidPICC[i] = rfid.uid.uidByte[i];
for(int i = 0; i < num; i++)
if(nuidPICC[0] == record[i][0] && nuidPICC[1] == record[i][1] && nuidPICC[2] == record[i][2] && nuidPICC[3] == record[i][3])
right = true;
rfid.PICC_HaltA();
rfid.PCD_StopCrypto1();
if(right) openDoor();
else openWrong();
}
void setup()
{
digitalWrite(DOOR, HIGH);
digitalWrite(BG, HIGH);
digitalWrite(SD_VCC, LOW);
pinMode(DOOR, OUTPUT);
pinMode(BG, OUTPUT);
pinMode(SD_VCC, OUTPUT);
pinMode(ADMIN, INPUT_PULLUP);
pinMode(OPEN_INDOOR, INPUT_PULLUP);
lcd.begin(16, 2);
lcd.print("Please wait!");
for (byte i = 0; i < 6; i++) key.keyByte[i] = 0xFF;
SPI.begin();
rfid.PCD_Init();
getCard();
Serial.begin(9600);
lcdInit();
new_time = millis() / 1000;
}
void loop()
{
int ifAdmin = 1, ifIndoorOpen = 1;
ifAdmin = digitalRead(ADMIN);
ifIndoorOpen = digitalRead(OPEN_INDOOR);
if(ifIndoorOpen == 0) openDoor();
if(ifAdmin == 1) readCard();
if(ifAdmin == 0)
{
lcd.clear();
lcd.print("Administrator");
insertCard();
}
}