added project to git
This commit is contained in:
commit
aca4178b69
Binary file not shown.
After Width: | Height: | Size: 223 KiB |
|
@ -0,0 +1,242 @@
|
||||||
|
#include <SPI.h>
|
||||||
|
#include <LiquidCrystal.h>
|
||||||
|
#include <EEPROM.h>
|
||||||
|
#include <MFRC522.h>
|
||||||
|
|
||||||
|
|
||||||
|
#define BTN_PIN A0 // lcd buttons are Voltage-Divider analog
|
||||||
|
#define LCD_BACKLIGHT 10
|
||||||
|
#define LCD_RS 8
|
||||||
|
#define LCD_EN 9
|
||||||
|
#define LCD_D4 4
|
||||||
|
#define LCD_D5 5
|
||||||
|
#define LCD_D6 6
|
||||||
|
#define LCD_D7 7
|
||||||
|
|
||||||
|
#define MIFARE_SELECT 2
|
||||||
|
#define MIFARE_RESET 3
|
||||||
|
|
||||||
|
#define EEP_CLIENT_MAX 40 // how many UID we can store
|
||||||
|
#define EEP_ADDR_UID_INCREMENT 12 // address increment value (size of a UID)
|
||||||
|
#define EEP_ADDR_START 20 // start of cards address
|
||||||
|
#define EEP_ADDR_LOG_START 620 // start of Log address
|
||||||
|
#define EEP_ADDR_LOG_LENGTH 10 // how many log items we can store
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
MFRC522 mfrc522(MIFARE_SELECT, MIFARE_RESET);
|
||||||
|
MFRC522::MIFARE_Key key;
|
||||||
|
|
||||||
|
LiquidCrystal lcd(LCD_RS, LCD_EN, LCD_D4, LCD_D5, LCD_D6, LCD_D7);
|
||||||
|
boolean cardWasPresent = true;
|
||||||
|
long lastActionMillis = 0;
|
||||||
|
|
||||||
|
boolean unlocked = false;
|
||||||
|
boolean outputOn = false;
|
||||||
|
int displayLogIndex = -1;
|
||||||
|
int displayLogIndexLast = -1;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
pinMode(10, OUTPUT); // LCD backlight
|
||||||
|
pinMode(A4, OUTPUT); // relais 1
|
||||||
|
pinMode(A5, OUTPUT); // relais 2
|
||||||
|
set_output(false);
|
||||||
|
digitalWrite(A5, HIGH);
|
||||||
|
|
||||||
|
Serial.begin(115200);
|
||||||
|
SPI.begin();
|
||||||
|
|
||||||
|
mfrc522.PCD_Init();
|
||||||
|
|
||||||
|
lcd_backlight(true);
|
||||||
|
lcd.begin(16, 2);
|
||||||
|
lcd.print("hello, world!");
|
||||||
|
|
||||||
|
// Prepare the security key for the read and write functions
|
||||||
|
// all six key bytes are set to 0xFF at chip delivery from the factory.
|
||||||
|
// we do not use the security key feature
|
||||||
|
for (byte i = 0; i < 6; i++) {
|
||||||
|
key.keyByte[i] = 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if we already have a master key
|
||||||
|
MFRC522::Uid masterUid = get_uid(0, EEP_ADDR_START);
|
||||||
|
|
||||||
|
if(masterUid.size == 0 || masterUid.size == 0xff) {
|
||||||
|
// we don't have one, so we request it
|
||||||
|
lcd.clear();
|
||||||
|
lcd.print("Kein Masterkey");
|
||||||
|
lcd.setCursor(0, 1);
|
||||||
|
|
||||||
|
while(true) {
|
||||||
|
if(mfrc522.PICC_IsNewCardPresent()) {
|
||||||
|
if(mfrc522.PICC_ReadCardSerial()) {
|
||||||
|
lcd.clear();
|
||||||
|
lcd.print("Karte ID:");
|
||||||
|
lcd.setCursor(0, 1);
|
||||||
|
lcd_print_uid(&(mfrc522.uid));
|
||||||
|
|
||||||
|
save_master_uid(&(mfrc522.uid));
|
||||||
|
delay(500);
|
||||||
|
lcd.clear();
|
||||||
|
lcd.print("OK!");
|
||||||
|
delay(1000);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lcd_print_home();
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Serial.println("storage dump:");
|
||||||
|
dump_uid(EEP_CLIENT_MAX +1, EEP_ADDR_START);
|
||||||
|
Serial.println("log dump:");
|
||||||
|
dump_uid(EEP_ADDR_LOG_LENGTH, EEP_ADDR_LOG_START);
|
||||||
|
*/
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void lcd_print_home() {
|
||||||
|
displayLogIndex = -1;
|
||||||
|
lcd.clear();
|
||||||
|
lcd.print("Karte Bitte");
|
||||||
|
|
||||||
|
if(unlocked) {
|
||||||
|
lcd.setCursor(15, 0);
|
||||||
|
lcd.print("U");
|
||||||
|
} else {
|
||||||
|
lcd.setCursor(0, 1);
|
||||||
|
lcd.print("Ausgang: ");
|
||||||
|
lcd.print(outputOn ? "AN": "AUS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void handleCards(long currentMillis) {
|
||||||
|
if(mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial()) {
|
||||||
|
|
||||||
|
mfrc522.PICC_HaltA();
|
||||||
|
|
||||||
|
cardWasPresent = true;
|
||||||
|
lastActionMillis = currentMillis;
|
||||||
|
|
||||||
|
lcd_backlight(true);
|
||||||
|
lcd.clear();
|
||||||
|
lcd_print_uid(&(mfrc522.uid));
|
||||||
|
|
||||||
|
int cardIndex = check_uid(&(mfrc522.uid));
|
||||||
|
|
||||||
|
if(cardIndex == 0) { // card is master
|
||||||
|
lcd.setCursor(0, 1);
|
||||||
|
|
||||||
|
if(unlocked) {
|
||||||
|
unlocked = false;
|
||||||
|
lcd.print("Gesperrt");
|
||||||
|
} else {
|
||||||
|
lcd.print("Entsperrt");
|
||||||
|
unlocked = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if(cardIndex > 0) { // card is client
|
||||||
|
|
||||||
|
if(unlocked) {
|
||||||
|
// if we are unlocked and detect a client card
|
||||||
|
// we remove this card from EEPROM
|
||||||
|
|
||||||
|
delete_uid(cardIndex, EEP_ADDR_START);
|
||||||
|
lcd.clear();
|
||||||
|
lcd.print("Karte wurde");
|
||||||
|
lcd.setCursor(0, 1);
|
||||||
|
lcd.print("geloescht");
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// if we are locked, we switch out Output
|
||||||
|
|
||||||
|
if(outputOn) {
|
||||||
|
set_output(false);
|
||||||
|
} else {
|
||||||
|
add_log(&(mfrc522.uid));
|
||||||
|
set_output(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
lcd.setCursor(0, 1);
|
||||||
|
lcd.print("Ausgang: ");
|
||||||
|
lcd.print(outputOn ? "AN": "AUS");
|
||||||
|
}
|
||||||
|
|
||||||
|
} else { // card is neither master nor slave
|
||||||
|
|
||||||
|
if(unlocked) {
|
||||||
|
if(save_client_uid(&(mfrc522.uid))) {
|
||||||
|
lcd.clear();
|
||||||
|
lcd.print("Karte wurde");
|
||||||
|
lcd.setCursor(0, 1);
|
||||||
|
lcd.print("hinzugefuegt");
|
||||||
|
|
||||||
|
} else {
|
||||||
|
lcd.clear();
|
||||||
|
lcd.print("Fehler beim");
|
||||||
|
lcd.setCursor(0, 1);
|
||||||
|
lcd.print("hinzufuegen");
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
lcd.setCursor(0, 1);
|
||||||
|
lcd.print("Unbekannte Karte");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
delay(1000);
|
||||||
|
lcd_print_home();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
|
||||||
|
long currentMillis = millis();
|
||||||
|
|
||||||
|
handleCards(currentMillis);
|
||||||
|
|
||||||
|
if(readButtons() == 1) {
|
||||||
|
displayLogIndex++;
|
||||||
|
displayLogIndex %= 10;
|
||||||
|
lastActionMillis = currentMillis;
|
||||||
|
delay(500);
|
||||||
|
}
|
||||||
|
|
||||||
|
// log display function
|
||||||
|
if(displayLogIndex != displayLogIndexLast) {
|
||||||
|
if(displayLogIndex >= 0) {
|
||||||
|
lcd_backlight(true);
|
||||||
|
lcd.clear();
|
||||||
|
lcd.print("Log ");
|
||||||
|
lcd.print(displayLogIndex);
|
||||||
|
lcd.setCursor(0, 1);
|
||||||
|
MFRC522::Uid uid = get_uid(displayLogIndex, EEP_ADDR_LOG_START);
|
||||||
|
lcd_print_uid(&uid);
|
||||||
|
}
|
||||||
|
|
||||||
|
displayLogIndexLast = displayLogIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// timeout handling for returning to locked state
|
||||||
|
if(currentMillis - lastActionMillis > 11000) {
|
||||||
|
unlocked = false;
|
||||||
|
displayLogIndex = -1;
|
||||||
|
lcd_backlight(false);
|
||||||
|
|
||||||
|
if(cardWasPresent) {
|
||||||
|
cardWasPresent = false;
|
||||||
|
lcd_print_home();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,172 @@
|
||||||
|
|
||||||
|
// this function ready the Display Buttons (analog pin)
|
||||||
|
// the values from analogRead are due tu a Voltage Divider
|
||||||
|
inline byte readButtons() {
|
||||||
|
int c = analogRead(BTN_PIN);
|
||||||
|
|
||||||
|
if(c > 1000) {
|
||||||
|
return 0;
|
||||||
|
} else if(c < 650 && c > 630) {
|
||||||
|
return 1; // select
|
||||||
|
} else if(c < 420 && c > 370) {
|
||||||
|
return 2; // left
|
||||||
|
} else if(c < 280 && c > 200) {
|
||||||
|
return 3; // down
|
||||||
|
}
|
||||||
|
|
||||||
|
return 4; // up
|
||||||
|
}
|
||||||
|
|
||||||
|
// switch the output Relaid on/off
|
||||||
|
void set_output(boolean on) {
|
||||||
|
if(on) {
|
||||||
|
digitalWrite(A4, LOW);
|
||||||
|
} else {
|
||||||
|
digitalWrite(A4, HIGH);
|
||||||
|
}
|
||||||
|
outputOn = on;
|
||||||
|
}
|
||||||
|
|
||||||
|
// switch the LDC Backlight on/off
|
||||||
|
void lcd_backlight(boolean on) {
|
||||||
|
if(on) {
|
||||||
|
digitalWrite(LCD_BACKLIGHT, HIGH);
|
||||||
|
} else {
|
||||||
|
digitalWrite(LCD_BACKLIGHT, LOW);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// print a Mifare UID at current LDC position
|
||||||
|
void lcd_print_uid(MFRC522::Uid *uid) {
|
||||||
|
for (byte i=0; i < uid->size; i++) {
|
||||||
|
lcd.print(uid->uidByte[i] < 0x10 ? " 0" : " ");
|
||||||
|
lcd.print(uid->uidByte[i], HEX);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// gives index of stored card uid if any, otherwise -1
|
||||||
|
int check_uid(MFRC522::Uid *uid) {
|
||||||
|
MFRC522::Uid uid2;
|
||||||
|
|
||||||
|
for(byte i=0; i < 1+EEP_CLIENT_MAX; i++) {
|
||||||
|
uid2 = get_uid(i, EEP_ADDR_START);
|
||||||
|
|
||||||
|
if(compare_uids(uid, &uid2)) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean compare_uids(MFRC522::Uid *uid1, MFRC522::Uid *uid2) {
|
||||||
|
|
||||||
|
if(uid1->size != uid2->size) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(byte j=0;j<uid1->size;j++) {
|
||||||
|
if(uid1->uidByte[j] != uid2->uidByte[j]) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get a uid from EEPROM at given index + start Address
|
||||||
|
MFRC522::Uid get_uid(byte index, int startAddress) {
|
||||||
|
MFRC522::Uid uid;
|
||||||
|
|
||||||
|
int address = startAddress + index * EEP_ADDR_UID_INCREMENT;
|
||||||
|
uid.size = 0;
|
||||||
|
EEPROM.get(address, uid);
|
||||||
|
return uid;
|
||||||
|
}
|
||||||
|
|
||||||
|
// delete a UID at the given index + start Address
|
||||||
|
void delete_uid(int index, int startAddress) {
|
||||||
|
|
||||||
|
int address = startAddress + index * EEP_ADDR_UID_INCREMENT;
|
||||||
|
|
||||||
|
for(byte i=0; i < EEP_ADDR_UID_INCREMENT; i++) {
|
||||||
|
EEPROM.write(address+i, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// store the master UID at first address of EEPROM
|
||||||
|
void save_master_uid(MFRC522::Uid *uid) {
|
||||||
|
EEPROM.put(EEP_ADDR_START, *uid);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
boolean save_client_uid(MFRC522::Uid *uid) {
|
||||||
|
byte index = EEP_CLIENT_MAX;
|
||||||
|
|
||||||
|
// try to find a free slot in EEPROM
|
||||||
|
for(byte i=0; i<EEP_CLIENT_MAX; i++) {
|
||||||
|
|
||||||
|
// we rely on the fact that uid.size is the first byte of the struct, so we can scan faster
|
||||||
|
byte value = EEPROM.read(EEP_ADDR_START + (i+1)*EEP_ADDR_UID_INCREMENT);
|
||||||
|
|
||||||
|
// a empty slot is found if size is 0 or 0xff which is EEPROM default value
|
||||||
|
if(value == 0 || value == 0xff) {
|
||||||
|
index = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(index == EEP_CLIENT_MAX) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// address is START + Master Slot + Index*Increment
|
||||||
|
int address = EEP_ADDR_START + EEP_ADDR_UID_INCREMENT + index * EEP_ADDR_UID_INCREMENT;
|
||||||
|
EEPROM.put(address, *uid);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void add_log(MFRC522::Uid *uid) {
|
||||||
|
|
||||||
|
MFRC522::Uid temp;
|
||||||
|
|
||||||
|
//TODO: rather than moving the log every time around, we could
|
||||||
|
// use a pointer the the start index and just increment this and append
|
||||||
|
// the log a position startindex-1 und decrement the index
|
||||||
|
|
||||||
|
// move all entries one back
|
||||||
|
for(byte i=EEP_ADDR_LOG_LENGTH - 1; i> 0; i--) {
|
||||||
|
temp.size = 0;
|
||||||
|
|
||||||
|
EEPROM.get(EEP_ADDR_LOG_START + (i - 1) * EEP_ADDR_UID_INCREMENT, temp);
|
||||||
|
|
||||||
|
if(temp.size != 0 && temp.size != 255) {
|
||||||
|
EEPROM.put(EEP_ADDR_LOG_START + i * EEP_ADDR_UID_INCREMENT, temp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EEPROM.put(EEP_ADDR_LOG_START, *uid);
|
||||||
|
}
|
||||||
|
|
||||||
|
// a debug function for showing all UID from EEPROM over Serial
|
||||||
|
void dump_uid(byte count, int address) {
|
||||||
|
MFRC522::Uid uid;
|
||||||
|
|
||||||
|
for(byte i=0; i< count; i++) {
|
||||||
|
uid = get_uid(i, address);
|
||||||
|
|
||||||
|
Serial.print("slot ");
|
||||||
|
if(i < 10) Serial.print(" ");
|
||||||
|
Serial.print(i);
|
||||||
|
Serial.print(":");
|
||||||
|
for (byte j=0;j<10;j++) {
|
||||||
|
Serial.print(uid.uidByte[j] < 0x10 ? " 0" : " ");
|
||||||
|
Serial.print(uid.uidByte[j], HEX);
|
||||||
|
}
|
||||||
|
Serial.println(" ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
After Width: | Height: | Size: 113 KiB |
Loading…
Reference in New Issue