2017-07-18 22:14:42 +00:00
|
|
|
#define PRINTER //uncomment for 3d-Printer (cooldown functions)
|
2017-07-11 22:26:47 +00:00
|
|
|
|
2016-10-31 09:34:20 +00:00
|
|
|
#include <SPI.h>
|
|
|
|
#include <LiquidCrystal.h>
|
|
|
|
#include <EEPROM.h>
|
|
|
|
#include <MFRC522.h>
|
|
|
|
|
2017-07-11 22:26:47 +00:00
|
|
|
#ifdef PRINTER
|
2017-07-18 22:14:42 +00:00
|
|
|
#define BTN_FANPROBE_R A3
|
|
|
|
#define BTN_FANPROBE_L A2
|
|
|
|
#define FANOFFVALUE 512 //adc value for fan. high value = fan off
|
2017-07-11 22:26:47 +00:00
|
|
|
boolean flag_switchOff = false; //set true-> loop switches output off if possible
|
2017-07-18 22:14:42 +00:00
|
|
|
#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
|
2017-07-11 22:26:47 +00:00
|
|
|
#endif
|
2016-10-31 09:34:20 +00:00
|
|
|
|
|
|
|
#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;
|
2017-07-18 22:14:42 +00:00
|
|
|
boolean lcdbacklight = false;
|
2016-10-31 09:34:20 +00:00
|
|
|
int displayLogIndex = -1;
|
|
|
|
int displayLogIndexLast = -1;
|
|
|
|
|
2016-11-17 21:48:57 +00:00
|
|
|
int displayCardsIndex = -1;
|
|
|
|
int displayCardsIndexLast = -1;
|
|
|
|
boolean cardsshow=false;
|
2016-10-31 09:34:20 +00:00
|
|
|
|
2017-07-11 22:26:47 +00:00
|
|
|
|
2016-10-31 09:34:20 +00:00
|
|
|
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()) {
|
2017-07-18 22:14:42 +00:00
|
|
|
|
2016-10-31 09:34:20 +00:00
|
|
|
|
2017-07-18 22:14:42 +00:00
|
|
|
|
2016-10-31 09:34:20 +00:00
|
|
|
mfrc522.PICC_HaltA();
|
|
|
|
|
|
|
|
cardWasPresent = true;
|
|
|
|
lastActionMillis = currentMillis;
|
|
|
|
|
|
|
|
lcd_backlight(true);
|
|
|
|
lcd.clear();
|
|
|
|
lcd_print_uid(&(mfrc522.uid));
|
|
|
|
|
|
|
|
int cardIndex = check_uid(&(mfrc522.uid));
|
|
|
|
|
2017-07-18 22:14:42 +00:00
|
|
|
#ifdef PRINTER
|
|
|
|
if (flag_switchOff && cardIndex>=0){
|
|
|
|
abortSwitchoff(); //abort automatic switchoff
|
|
|
|
}else{
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if(cardIndex == 0) { // card is master
|
2016-10-31 09:34:20 +00:00
|
|
|
lcd.setCursor(0, 1);
|
|
|
|
|
2017-07-18 22:14:42 +00:00
|
|
|
if(unlocked) {
|
|
|
|
unlocked = false;
|
|
|
|
lcd.print("Gesperrt");
|
2016-10-31 09:34:20 +00:00
|
|
|
} else {
|
2017-07-18 22:14:42 +00:00
|
|
|
lcd.print("Entsperrt");
|
|
|
|
unlocked = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
} else if(cardIndex > 0) { // card is client
|
2016-10-31 09:34:20 +00:00
|
|
|
|
2017-07-18 22:14:42 +00:00
|
|
|
if(unlocked) {
|
|
|
|
// if we are unlocked and detect a client card
|
|
|
|
// we remove this card from EEPROM
|
|
|
|
|
|
|
|
delete_uid(cardIndex, EEP_ADDR_START);
|
2016-10-31 09:34:20 +00:00
|
|
|
lcd.clear();
|
2017-07-18 22:14:42 +00:00
|
|
|
lcd.print("Karte wurde");
|
2016-10-31 09:34:20 +00:00
|
|
|
lcd.setCursor(0, 1);
|
2017-07-18 22:14:42 +00:00
|
|
|
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");
|
2016-11-17 21:48:57 +00:00
|
|
|
}
|
2016-10-31 09:34:20 +00:00
|
|
|
|
|
|
|
} else {
|
|
|
|
lcd.setCursor(0, 1);
|
2017-07-18 22:14:42 +00:00
|
|
|
lcd.print("Unbekannte Karte");
|
2016-10-31 09:34:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
delay(1000);
|
|
|
|
lcd_print_home();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-18 22:14:42 +00:00
|
|
|
long lastPrint=0;
|
|
|
|
|
2016-10-31 09:34:20 +00:00
|
|
|
void loop() {
|
|
|
|
|
|
|
|
long currentMillis = millis();
|
|
|
|
|
|
|
|
handleCards(currentMillis);
|
|
|
|
|
2017-07-18 22:14:42 +00:00
|
|
|
#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
|
|
|
|
|
|
|
|
|
2017-07-11 22:26:47 +00:00
|
|
|
|
2016-11-17 21:48:57 +00:00
|
|
|
if(readButtons() == 1 && !cardsshow) { //select button shows log, if not showing cards atm
|
2016-10-31 09:34:20 +00:00
|
|
|
displayLogIndex++;
|
|
|
|
displayLogIndex %= 10;
|
|
|
|
lastActionMillis = currentMillis;
|
2016-11-17 21:48:57 +00:00
|
|
|
delay(200);
|
2016-10-31 09:34:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// 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;
|
|
|
|
}
|
2016-11-17 21:48:57 +00:00
|
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
2016-10-31 09:34:20 +00:00
|
|
|
|
|
|
|
// timeout handling for returning to locked state
|
2017-07-18 22:14:42 +00:00
|
|
|
if(unlocked && currentMillis - lastActionMillis > 30000) {
|
2016-10-31 09:34:20 +00:00
|
|
|
unlocked = false;
|
|
|
|
displayLogIndex = -1;
|
2016-11-17 21:48:57 +00:00
|
|
|
displayCardsIndex = -1;
|
|
|
|
cardsshow=false;
|
2016-10-31 09:34:20 +00:00
|
|
|
lcd_backlight(false);
|
|
|
|
|
|
|
|
if(cardWasPresent) {
|
|
|
|
cardWasPresent = false;
|
|
|
|
lcd_print_home();
|
|
|
|
}
|
|
|
|
}
|
2017-07-11 22:26:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef PRINTER
|
|
|
|
bool fanActive()
|
|
|
|
{
|
2017-07-18 22:14:42 +00:00
|
|
|
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
|
2017-07-11 22:26:47 +00:00
|
|
|
return false;
|
|
|
|
}else{
|
|
|
|
return true;
|
|
|
|
}
|
2016-10-31 09:34:20 +00:00
|
|
|
}
|
|
|
|
|
2017-07-11 22:26:47 +00:00
|
|
|
void abortSwitchoff(){
|
2017-07-18 22:14:42 +00:00
|
|
|
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);
|
2017-07-11 22:26:47 +00:00
|
|
|
flag_switchOff=false;
|
|
|
|
lcd.clear();
|
2017-07-18 22:14:42 +00:00
|
|
|
lcd.print("SCHNELLER");
|
2017-07-11 22:26:47 +00:00
|
|
|
lcd.setCursor(0, 1);
|
2017-07-18 22:14:42 +00:00
|
|
|
lcd.print("NEUSTART");
|
|
|
|
set_output(false);
|
|
|
|
delay(500);
|
|
|
|
set_output(true);
|
2017-07-11 22:26:47 +00:00
|
|
|
}
|
|
|
|
#endif
|
2016-10-31 09:34:20 +00:00
|
|
|
|