You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
409 lines
10 KiB
409 lines
10 KiB
#define PRINTER //uncomment for 3d-Printer (cooldown functions) |
|
|
|
#include <SPI.h> |
|
#include <LiquidCrystal.h> |
|
#include <EEPROM.h> |
|
#include <MFRC522.h> |
|
|
|
#ifdef PRINTER |
|
#define BTN_FANPROBE_R A3 |
|
#define BTN_FANPROBE_L A2 |
|
#define FANOFFVALUE 512 //adc value for fan. high value = fan off |
|
boolean flag_switchOff = false; //set true-> loop switches output off if possible |
|
#define SWITCHOFFTRYBLINKDELAY 500 //blink period time in millis |
|
long lastSwitchOffTryMillis=0; |
|
#define QUICKRESTARTHOLDTIME 1000 //time to hold button during fan waiting to quick restart printer |
|
#endif |
|
|
|
#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; |
|
boolean lcdbacklight = false; |
|
int displayLogIndex = -1; |
|
int displayLogIndexLast = -1; |
|
|
|
int displayCardsIndex = -1; |
|
int displayCardsIndexLast = -1; |
|
boolean cardsshow=false; |
|
|
|
|
|
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)); |
|
|
|
#ifdef PRINTER |
|
if (flag_switchOff && cardIndex>=0){ |
|
abortSwitchoff(); //abort automatic switchoff |
|
}else{ |
|
#endif |
|
|
|
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) { |
|
#ifdef PRINTER |
|
if (!flag_switchOff){ |
|
flag_switchOff=true; //set flag to turn off printer |
|
}else{ |
|
flag_switchOff=false; //cancel switchoff |
|
} |
|
#else |
|
set_output(false); |
|
#endif |
|
} 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("Hinzugefuegt"); |
|
lcd.setCursor(0, 1); |
|
lcd.print(""); |
|
lcd_print_uid(&(mfrc522.uid)); |
|
|
|
delay(500); |
|
while(!mfrc522.PICC_IsNewCardPresent() && !mfrc522.PICC_ReadCardSerial()){ |
|
delay(50); |
|
} |
|
lcd.setCursor(0, 0); |
|
lcd.print(" "); |
|
delay(200); |
|
|
|
} 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(); |
|
} |
|
} |
|
|
|
long lastPrint=0; |
|
|
|
void loop() { |
|
|
|
long currentMillis = millis(); |
|
|
|
handleCards(currentMillis); |
|
|
|
#ifdef PRINTER |
|
/*if (currentMillis>lastPrint+1000){ //TESTING |
|
int fanvalue=analogRead(BTN_FANPROBE_R); |
|
Serial.println(fanvalue); |
|
lastPrint=currentMillis; |
|
}*/ |
|
if (flag_switchOff){ |
|
|
|
if (readButtons()!=0){ //any buttons pressed |
|
long _buttonPressStart=millis(); |
|
while (readButtons()==1){ //select button |
|
delay(100); //wait for button to release |
|
} |
|
|
|
if (millis()-_buttonPressStart > QUICKRESTARTHOLDTIME) { //pressed button for long time |
|
quickRestart(); |
|
}else{ //just pressed short |
|
abortSwitchoff(); |
|
} |
|
|
|
} |
|
if (!fanActive()){ |
|
set_output(false); |
|
flag_switchOff=false; |
|
lcd_print_home(); |
|
}else{ //fan is active |
|
if (lastSwitchOffTryMillis+SWITCHOFFTRYBLINKDELAY < currentMillis){ |
|
lcd_backlight(!get_lcd_backlight()); //blink backlight |
|
lcd.clear(); |
|
lcd.print("Wartet auf"); |
|
lcd.setCursor(0, 1); |
|
lcd.print("Luefter"); |
|
lastSwitchOffTryMillis=currentMillis; |
|
} |
|
} |
|
} |
|
#endif |
|
|
|
|
|
|
|
if(readButtons() == 1 && !cardsshow) { //select button shows log, if not showing cards atm |
|
displayLogIndex++; |
|
displayLogIndex %= 10; |
|
lastActionMillis = currentMillis; |
|
delay(200); |
|
} |
|
|
|
// 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; |
|
} |
|
|
|
|
|
if(readButtons() == 3) { //down |
|
displayCardsIndex++; |
|
displayCardsIndex %= EEP_CLIENT_MAX; |
|
lastActionMillis = currentMillis; |
|
cardsshow=true; |
|
delay(200); |
|
} |
|
if(readButtons() == 4) { //up |
|
displayCardsIndex--; |
|
if (displayCardsIndex<0){ |
|
displayCardsIndex=EEP_CLIENT_MAX-1; |
|
} |
|
displayCardsIndex %= EEP_CLIENT_MAX; |
|
lastActionMillis = currentMillis; |
|
cardsshow=true; |
|
delay(200); |
|
} |
|
// saved cards display function |
|
if(displayCardsIndex != displayCardsIndexLast) { |
|
if(displayCardsIndex >= 0) { |
|
lcd_backlight(true); |
|
lcd.clear(); |
|
lcd.print("SLOT "); |
|
lcd.print(displayCardsIndex); |
|
if (displayCardsIndex==0){ |
|
lcd.print(" Master"); |
|
} |
|
lcd.setCursor(0, 1); |
|
MFRC522::Uid uid = get_uid(displayCardsIndex, EEP_ADDR_START); |
|
lcd_print_uid(&uid); |
|
} |
|
|
|
displayCardsIndexLast = displayCardsIndex; |
|
} |
|
//card removal |
|
if(readButtons() == 1 && cardsshow && unlocked) { //cards are shown, is unlocked an select pressed |
|
lastActionMillis = currentMillis; |
|
lcd.clear(); |
|
lcd.print("Karte"); |
|
lcd.setCursor(0, 1); |
|
lcd.print("entfernt"); |
|
delete_uid(displayCardsIndex, EEP_ADDR_START); |
|
delay(1000); |
|
} |
|
|
|
// timeout handling for returning to locked state |
|
if(unlocked && currentMillis - lastActionMillis > 30000) { |
|
unlocked = false; |
|
displayLogIndex = -1; |
|
displayCardsIndex = -1; |
|
cardsshow=false; |
|
lcd_backlight(false); |
|
|
|
if(cardWasPresent) { |
|
cardWasPresent = false; |
|
lcd_print_home(); |
|
} |
|
} |
|
} |
|
|
|
#ifdef PRINTER |
|
bool fanActive() |
|
{ |
|
int fanvalue_r=analogRead(BTN_FANPROBE_R); |
|
int fanvalue_l=analogRead(BTN_FANPROBE_L); |
|
if (fanvalue_l>FANOFFVALUE && fanvalue_r>FANOFFVALUE){ //fan value high = fan off |
|
return false; |
|
}else{ |
|
return true; |
|
} |
|
} |
|
|
|
void abortSwitchoff(){ |
|
lcd_backlight(true); |
|
if (flag_switchOff){ |
|
flag_switchOff=false; |
|
lcd.clear(); |
|
lcd.print("Ausschalten"); |
|
lcd.setCursor(0, 1); |
|
lcd.print("Abgebrochen"); |
|
delay(500); |
|
} |
|
} |
|
|
|
void quickRestart(){ |
|
lcd_backlight(true); |
|
flag_switchOff=false; |
|
lcd.clear(); |
|
lcd.print("SCHNELLER"); |
|
lcd.setCursor(0, 1); |
|
lcd.print("NEUSTART"); |
|
set_output(false); |
|
delay(500); |
|
set_output(true); |
|
} |
|
#endif |
|
|
|
|