#define PRINTER //uncomment for 3d-Printer (cooldown functions) #include #include #include #include #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