Alarmanlage mit RFID deaktivieren

Ich mir ein Steuerung für meine Alarmanlage gebaut. Ich verwende dazu ein 1.8" TFT Display und einen PN532 an einem NodeMCU.
Auf dem Display wird die Uhrzeit, der Status der Alarmanlage und die das Ergebnis des RFID Auslesens angezeigt.
Funktioniert alles soweit jedoch wird die Uhrzeit und der Status nur alle 20 sec. aktualisiert. Da die Uhrzeit mit Sekunden angezeigt werden soll ist es natürlich nicht so toll. auch wenn der RFID als richtig erkannt wird, wird die Alarmanlage sofort deaktiviert, doch der Status ändert sich erst nach den 20 sec. Leider sind meine Kenntnisse noch nicht so weit, dass ich das Problem beheben kann. Ich hoffe ihr könnt mir helfen.

Hier mein Sketch:

#include <SPI.h>
#include <TFT_eSPI.h>       // Hardware-specific library
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <Adafruit_GFX.h>
#include <WiFiUdp.h>
#include <NTPClient.h>
#include <PN532_I2C.h>
#include <PN532.h>
#include <NfcAdapter.h>
  
  PN532_I2C pn532i2c(Wire);
  PN532 nfc(pn532i2c);

const char* SSID = "XXXXXX";
const char* PSK = "XXXXXX";
const char* MQTT_BROKER = "XXXXX";
const long utcOffsetInSeconds = 3600;

WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "de.pool.ntp.org", utcOffsetInSeconds);

TFT_eSPI tft = TFT_eSPI();  

WiFiClient espClient;
PubSubClient client(espClient);

void setup() {
  Serial.begin(115200);
  setup_wifi();
  timeClient.begin();
  client.setServer(MQTT_BROKER, 1886);
  client.setCallback(callback);
  nfc.begin();
  uint32_t versiondata = nfc.getFirmwareVersion();
  if (! versiondata) {
    Serial.print("Didn't find PN53x board");
    while (1); // halt
  }
  Serial.print("Found chip PN5"); Serial.println((versiondata>>24) & 0xFF, HEX); 
  Serial.print("Firmware ver. "); Serial.print((versiondata>>16) & 0xFF, DEC); 
  Serial.print('.'); Serial.println((versiondata>>8) & 0xFF, DEC);
  nfc.setPassiveActivationRetries(0xFF);
  nfc.SAMConfig();
  Serial.println("Waiting for an ISO14443A card");

  tft.init();
  tft.fillScreen(TFT_BLACK);
  tft.setRotation(1);
  tft.setCursor(65, 0, 2);
  tft.print("SmartHome");
  tft.drawLine(0, 17, 160, 17, TFT_WHITE);
  tft.setCursor(8, 25, 4);
  tft.setTextColor(TFT_WHITE, TFT_BLACK);
  tft.println("Alarmanlage");
  tft.setCursor(20, 60, 4);
  tft.setTextColor(TFT_RED, TFT_BLACK);
  //tft.println(msg);
}

void setup_wifi() {
   WiFi.begin(SSID, PSK);
   while (WiFi.status() != WL_CONNECTED){
     delay(500);
     Serial.print(".");
   }
   Serial.println(WiFi.localIP());    
 }

void loop() {
  if (!client.connected()) {
    while (!client.connected()) {
      client.connect("ESPTFT");
      client.subscribe("/Alarmanlage/OLED/ausgabe");
      delay(100);
    }
  }
  client.loop();
  timeClient.update();
  Serial.print(timeClient.getFormattedTime());
  tft.setCursor(0, 0, 2);
  tft.setTextColor(TFT_WHITE, TFT_BLACK);
  tft.print(timeClient.getFormattedTime());
  delay(1000);
  boolean success;
  uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 };  // Buffer to store the returned UID
  uint8_t uidLength;                        // Length of the UID (4 or 7 bytes depending on ISO14443A card type)
  uint8_t compare[] = {0xCA, 0x0B, 0x20, 0x58};
  uint8_t compare1[] = {0x43, 0xE0, 0x57, 0x05};
  
  success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, &uid[0], &uidLength);
  
  if (success) {
    Serial.println("Found a card!");
    Serial.print("UID Length: ");Serial.print(uidLength, DEC);Serial.println(" bytes");
    Serial.print("UID Value: ");
    for (uint8_t i=0; i < uidLength; i++) 
     {
      Serial.print(" 0x");Serial.print(uid[i], HEX); 
     }
    Serial.println("");
    Serial.print("Card Status    :"); 
    //erste RFID-Chip
     if (memcmp(uid, compare, 4) == 0)
     {
      Serial.println("Card Accepted");
  tft.setCursor(0, 95, 4);
  tft.setTextColor(TFT_GREEN, TFT_BLACK);
  tft.println("Key Accepted");
  client.publish("/Alarmanlage/OLED/rfid", "correct");
        delay(5000);
      tft.setCursor(0, 95, 4);
      tft.setTextColor(TFT_BLACK, TFT_BLACK);
      tft.println("Key Accepted");
     }
     else
     {
      //zweite RFID-Chip
     if (memcmp(uid, compare1, 4) == 0)
     {
      Serial.println("Card Accepted");
      tft.setCursor(0, 95, 4);
      tft.setTextColor(TFT_GREEN, TFT_BLACK);
      tft.println("Key Accepted");
      client.publish("/Alarmanlage/OLED/rfid", "correct");
      delay(5000);
      tft.setCursor(0, 95, 4);
      tft.setTextColor(TFT_BLACK, TFT_BLACK);
      tft.println("Key Accepted");
      }
       else
        {
         Serial.println("Access denied");
         tft.setCursor(0, 95, 4);
         tft.setTextColor(TFT_BLACK, TFT_BLACK);
         tft.println("Key Accepted");
         tft.setCursor(15, 95, 4);
         tft.setTextColor(TFT_RED, TFT_BLACK);
         tft.println("Wrong Key");
         client.publish("/Alarmanlage/OLED/rfid", "wrong");
         delay(5000);
         tft.setCursor(15, 95, 4);
         tft.setTextColor(TFT_BLACK, TFT_BLACK);
         tft.println("Wrong Key");
        }
      }
    // Wait 1 second before continuing
    delay(1000);
  }
  else
  {
    // PN532 probably timed out waiting for a card
    Serial.println("Wait for RFID");
  }

}
void callback(char* topic, byte* payload, unsigned int length) {
    String msg;
    for (byte i = 0; i < length; i++) {
        char tmp = char(payload[i]);
        msg += tmp;
    }
    Serial.println(msg);
    tft.setCursor(20, 60, 4);
    tft.setTextColor(TFT_RED, TFT_BLACK);
    tft.println(msg);
}

Wie gesagt es funktioniert eigentlich alles, außer das es der Status und die Uhrzeit nicht jede Sekunde erneuert wird.

Vielen Dank für Eure Hilfe

delay
delay
delay
delay
delay
delay

überleg mal,
was ein delay macht
was das Beispiel "BlinkWithoutDelay" besser macht

und ob es nicht für NTP lange schon bessere Varianten gäbe.
Z.B.: ESP8266 NTP Abfrage mit Sommerzeit / Winterzeit (NodeMCU, Wemos D1)

Leider sind meine Kenntnisse noch nicht so weit, dass ich das Problem beheben kann. Ich hoffe ihr könnt mir helfen.

Eine Arlarmanlage ist eine sehr kritische Anwendung. Wenn Du nicht gut Programmieren kannst dann laß es lieber.
Grüße Uwe

uwefed:
Eine Arlarmanlage ist eine sehr kritische Anwendung. Wenn Du nicht gut Programmieren kannst dann laß es lieber.
Grüße Uwe

Es geht hier ja nicht um die Alarmanlage. ih möchte sie ja nur über den RFID chip steuern und eine Ausgabe auf ein display erzeugen.

noiasca:
delay
delay
delay
delay
delay
delay

überleg mal,
was ein delay macht
was das Beispiel "BlinkWithoutDelay" besser macht

ok also wenn ich das richtig verstehe muss ich die Delays durch die millis ersetzen wie im beispiel "BlinkWithoutDelay" beschrieben ist?

Es geht hier ja nicht um die Alarmanlage. ih möchte sie ja nur über den RFID chip steuern und eine Ausgabe auf ein display erzeugen.

Aha, Du kannst also keine Fehler machen und das Ding ausschalten wenn sie eingeschaltet sein soll oder einschalten wenn Leute im Raum sind?

Grüße Uwe

hoeced:
... also wenn ich das richtig verstehe muss ich die Delays durch die millis ersetzen wie im beispiel "BlinkWithoutDelay" beschrieben ist?

Ja. Sobald Du mehrere Dinge quasi parallel erledigen möchtest, musst Du das mit einem „endlichen Automaten“ tun. Die „Pausen-Denke“ ist hierbei eine vollkommen Andere. Evtl. hilft das hier.

Gruß

Gregor

So habe mal versucht die Delays aus den Loop zu entfernen. leider klappt es noch nicht. es muss ja an dem RFID_loop liegen denn wenn ich diesen deaktiviere läuft die Uhr sauber. Hier nochmal der geänderte Code:

#include <ESP8266WiFi.h>           
#include <time.h> 
#include <SPI.h>
#include <TFT_eSPI.h> 
#include <Adafruit_GFX.h>  
#include <PN532_I2C.h>
#include <PN532.h>
#include <NfcAdapter.h>   

#define MY_NTP_SERVER "de.pool.ntp.org"           
#define MY_TZ "CET-1CEST,M3.5.0/02,M10.5.0/03"   

const char* SSID = "UPC938849C";
const char* PSK = "jf3zpnjvcrGE1234";
unsigned long prevMillies;

time_t now;                         
tm tm;       
TFT_eSPI tft = TFT_eSPI();  
PN532_I2C pn532i2c(Wire);
PN532 nfc(pn532i2c);                      

void setup() {
  Serial.begin(115200);
  Serial.println("\nNTP TZ DST - bare minimum");
  setup_wifi();
  configTime(MY_TZ, MY_NTP_SERVER);
  tft_setup();
  RFID_setup();
}

void loop() {
  if (millis() - prevMillies >= 1000){   //Uhrzeit
    prevMillies = millis();
    showTime();
  }
  RFID_loop();
}


void setup_wifi() {
   WiFi.begin(SSID, PSK);
   while (WiFi.status() != WL_CONNECTED){
     delay(500);
     Serial.print(".");
   }
   Serial.println(WiFi.localIP());
 }

void showTime() {
  time(&now);                      
  localtime_r(&now, &tm);  
if (tm.tm_hour <= 9){
  Serial.print("0");
  Serial.print(tm.tm_hour);
  tft.setCursor(0, 0, 2);
  tft.setTextColor(TFT_WHITE, TFT_BLACK);
  tft.print("0");
  tft.print(tm.tm_hour);}
  else{
  Serial.print(tm.tm_hour);
  tft.setCursor(0, 0, 2);
  tft.setTextColor(TFT_WHITE, TFT_BLACK);
  tft.print(tm.tm_hour);}         
    Serial.print(":");
  tft.setCursor(18, 0, 2);
  tft.setTextColor(TFT_WHITE, TFT_BLACK);
  tft.print(":");
  
  if (tm.tm_min <= 9){
    Serial.print("0");
    Serial.print(tm.tm_min);
    tft.setCursor(23, 0, 2);
    tft.setTextColor(TFT_WHITE, TFT_BLACK);
    tft.print("0");
    tft.print(tm.tm_min);}
  else{
    Serial.print(tm.tm_min);
    tft.setCursor(23, 0, 2);
    tft.setTextColor(TFT_WHITE, TFT_BLACK);
    tft.print(tm.tm_min);
  }
  Serial.print(":");
    tft.setCursor(40, 0, 2);
  tft.setTextColor(TFT_WHITE, TFT_BLACK);
  tft.print(":");
  if (tm.tm_sec <= 9){
  Serial.print("0");
  Serial.println(tm.tm_sec);
  tft.setCursor(45, 0, 2);
  tft.setTextColor(TFT_WHITE, TFT_BLACK);
  tft.print("0");
  tft.print(tm.tm_sec);}
  else{
  Serial.println(tm.tm_sec);
  tft.setCursor(45, 0, 2);
  tft.setTextColor(TFT_WHITE, TFT_BLACK);
  tft.print(tm.tm_sec);}
}

void tft_setup() {
  tft.init();
  tft.fillScreen(TFT_BLACK);
  tft.setRotation(1);
  tft.setCursor(65, 0, 2);
  tft.print("SmartHome");
  tft.drawLine(0, 17, 160, 17, TFT_WHITE);
  tft.setCursor(8, 25, 4);
  tft.setTextColor(TFT_WHITE, TFT_BLACK);
  tft.println("Alarmanlage");
}

void RFID_loop() {
  boolean success;
  uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 };  // Buffer to store the returned UID
  uint8_t uidLength;                        // Length of the UID (4 or 7 bytes depending on ISO14443A card type)
  uint8_t compare[] = {0xCA, 0x0B, 0x20, 0x58};
  uint8_t compare1[] = {0x43, 0xE0, 0x57, 0x05};
  
  success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, &uid[0], &uidLength);
  
  if (success) {
    Serial.println("Found a card!");
    Serial.print("UID Length: ");Serial.print(uidLength, DEC);Serial.println(" bytes");
    Serial.print("UID Value: ");
    for (uint8_t i=0; i < uidLength; i++) {
      Serial.print(" 0x");Serial.print(uid[i], HEX); }
    Serial.println("");
    Serial.print("Card Status    :");  
    if (memcmp(uid, compare, 4) == 0 || memcmp(uid, compare1, 4) == 0){
      Serial.println("Card Accepted");
      //client.publish("/Alarmanlage/OLED/rfid", "correct");
      }
     else{
         Serial.println("Access denied");
     //client.publish("/Alarmanlage/OLED/rfid", "wrong");
     }
    
  }
  else
  {
    // PN532 probably timed out waiting for a card
    Serial.println("Wait for RFID");
  }
}

void RFID_setup() {
  nfc.begin();
  uint32_t versiondata = nfc.getFirmwareVersion();
  if (! versiondata) {
    Serial.print("Didn't find PN53x board");
    while (1); 
  }
  Serial.print("Found chip PN5"); Serial.println((versiondata>>24) & 0xFF, HEX); 
  Serial.print("Firmware ver. "); Serial.print((versiondata>>16) & 0xFF, DEC); 
  Serial.print('.'); Serial.println((versiondata>>8) & 0xFF, DEC);
  nfc.setPassiveActivationRetries(0xFF);
  nfc.SAMConfig();
  Serial.println("Waiting for RFID");
}

Vielleicht bekomme ich ja noch den ein oder anderen Tipp von euch

hab schon länger nichts mit dem reader gemacht, aber blockiert der Read nicht so lange - bis du was liest?

ergänze/ändere mal im Setup ein

  // get the reader to exit its continuous loop when a card wasn't present
  nfc.setPassiveActivationRetries(0x02); // 2 tries

dann sollte er eigentlich aus der Funktion wieder aussteigen können...

Super vielen Dank! jetzt funktioniert es soweit werde es später mal verfeinern

hoeced:
... verfeinern

Au ja! Mit Maggi und viel Ketchup!

SCNR

Gregor

so hier ist nun der funktionierende Code. Für Anregungen wie man etwas verbessern kann bin ich weiterhin dankbar

#include <ESP8266WiFi.h>           
#include <time.h> 
#include <SPI.h>
#include <TFT_eSPI.h> 
#include <Adafruit_GFX.h>  
#include <PN532_I2C.h>
#include <PN532.h>
#include <NfcAdapter.h>   
#include <PubSubClient.h>

#define MY_NTP_SERVER "de.pool.ntp.org"           
#define MY_TZ "CET-1CEST,M3.5.0/02,M10.5.0/03"   

const char* SSID = "xxxxx";
const char* PSK = "xxxxxxxx";
const char* MQTT_BROKER = "192.168.178.10";
unsigned long prevMillies;

time_t now;                         
tm tm;       
TFT_eSPI tft = TFT_eSPI();  
PN532_I2C pn532i2c(Wire);
PN532 nfc(pn532i2c); 
WiFiClient espClient;
PubSubClient client(espClient);                     

void setup() {
  Serial.begin(115200);
  Serial.println("\nNTP TZ DST - bare minimum");
  setup_wifi();
  configTime(MY_TZ, MY_NTP_SERVER);
  tft_setup();
  RFID_setup();
  MQTT();
}

void loop() {
	if (millis() - prevMillies >= 1000){  
		prevMillies = millis();
		showTime();}
	
	unsigned long RFIDMillis;
	if (millis() - RFIDMillis >= 500) {  
		RFIDMillis = millis();
		RFID_loop();}
		
	if (!client.connected()) {   
    while (!client.connected()) {
      client.connect("ESPTFT");
      client.subscribe("/Alarmanlage/OLED/ausgabe");
    }
  }
	client.loop();
}

void setup_wifi() {
   WiFi.begin(SSID, PSK);
   while (WiFi.status() != WL_CONNECTED){
	   delay(500);
	   Serial.print(".");
   }
   Serial.println(WiFi.localIP());
 }

void showTime() {
  time(&now);                      
  localtime_r(&now, &tm);  
if (tm.tm_hour <= 9){
	Serial.print("0");
	Serial.print(tm.tm_hour);
	tft.setCursor(0, 0, 2);
	tft.setTextColor(TFT_WHITE, TFT_BLACK);
	tft.print("0");
	tft.print(tm.tm_hour);}
	else{
	Serial.print(tm.tm_hour);
	tft.setCursor(0, 0, 2);
	tft.setTextColor(TFT_WHITE, TFT_BLACK);
	tft.print(tm.tm_hour);}         
    Serial.print(":");
	tft.setCursor(18, 0, 2);
	tft.setTextColor(TFT_WHITE, TFT_BLACK);
	tft.print(":");
	
  if (tm.tm_min <= 9){
	  Serial.print("0");
	  Serial.print(tm.tm_min);
	  tft.setCursor(23, 0, 2);
	  tft.setTextColor(TFT_WHITE, TFT_BLACK);
	  tft.print("0");
	  tft.print(tm.tm_min);}
  else{
	  Serial.print(tm.tm_min);
	  tft.setCursor(23, 0, 2);
	  tft.setTextColor(TFT_WHITE, TFT_BLACK);
	  tft.print(tm.tm_min);
	}
  Serial.print(":");
  	tft.setCursor(40, 0, 2);
	tft.setTextColor(TFT_WHITE, TFT_BLACK);
	tft.print(":");
  if (tm.tm_sec <= 9){
  Serial.print("0");
  Serial.println(tm.tm_sec);
  tft.setCursor(45, 0, 2);
  tft.setTextColor(TFT_WHITE, TFT_BLACK);
  tft.print("0");
  tft.print(tm.tm_sec);}
  else{
  Serial.println(tm.tm_sec);
  tft.setCursor(45, 0, 2);
  tft.setTextColor(TFT_WHITE, TFT_BLACK);
  tft.print(tm.tm_sec);}
}

void tft_setup() {
  tft.init();
  tft.fillScreen(TFT_BLACK);
  tft.setRotation(1);
  tft.setCursor(65, 0, 2);
  tft.print("SmartHome");
  tft.drawLine(0, 17, 160, 17, TFT_WHITE);
  tft.setCursor(8, 25, 4);
  tft.setTextColor(TFT_WHITE, TFT_BLACK);
  tft.println("Alarmanlage");
}

void RFID_loop() {
	boolean success;
	uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 };  
	uint8_t uidLength;                        
	uint8_t compare[] = {0xCA, 0x0B, 0x20, 0x58};
	uint8_t compare1[] = {0x43, 0xE0, 0x57, 0x05};
  
	success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, &uid[0], &uidLength);
  
	if (success) {
		Serial.println("Found a card!");
		Serial.print("UID Length: ");Serial.print(uidLength, DEC);Serial.println(" bytes");
		Serial.print("UID Value: ");
		for (uint8_t i=0; i < uidLength; i++) {
			Serial.print(" 0x");Serial.print(uid[i], HEX); }
		Serial.println("");
		Serial.print("Card Status    :");  
		if (memcmp(uid, compare, 4) == 0 || memcmp(uid, compare1, 4) == 0){
			Serial.println("Card Accepted");
			client.publish("/Alarmanlage/OLED/rfid", "correct");
			tft.setCursor(0, 95, 4);
			tft.setTextColor(TFT_GREEN, TFT_BLACK);
			tft.println("Key Accepted");
			unsigned long tftmillis;
			delay(2500);
			tft.setCursor(0, 95, 4);
			tft.setTextColor(TFT_BLACK, TFT_BLACK);
			tft.println("Key Accepted");			
			}
     else{
			Serial.println("Access denied");
			client.publish("/Alarmanlage/OLED/rfid", "wrong");
			tft.setCursor(20, 95, 4);
			tft.setTextColor(TFT_RED, TFT_BLACK);
			tft.println("Key wrong");
			unsigned long tftmillis2;
			delay(2500);
			tft.setCursor(20, 95, 4);
			tft.setTextColor(TFT_BLACK, TFT_BLACK);
			tft.println("Key wrong");			
		 }
    delay(1000);
  }
  else
  {
    Serial.println("Wait for RFID");
	delay(500);
  }
}

void RFID_setup() {
  nfc.begin();
  uint32_t versiondata = nfc.getFirmwareVersion();
  if (! versiondata) {
    Serial.print("Didn't find PN53x board");
    delay (1000); 
  }
  Serial.print("Found chip PN5"); Serial.println((versiondata>>24) & 0xFF, HEX); 
  Serial.print("Firmware ver. "); Serial.print((versiondata>>16) & 0xFF, DEC); 
  Serial.print('.'); Serial.println((versiondata>>8) & 0xFF, DEC);
  nfc.setPassiveActivationRetries(0xFF);
  nfc.SAMConfig();
  Serial.println("Waiting for RFID");
  nfc.setPassiveActivationRetries(0x02);
}

void MQTT() {
	client.setServer(MQTT_BROKER, 1886);
	client.setCallback(callback);
}

void callback(char* topic, byte* payload, unsigned int length) {
    String msg;
    for (byte i = 0; i < length; i++) {
        char tmp = char(payload[i]);
        msg += tmp;
    }
    Serial.println(msg);
    tft.setCursor(20, 60, 4);
    tft.setTextColor(TFT_RED, TFT_BLACK);
    tft.println(msg);
}

Ich möchte mich nochmal für die Hilfe bei allen beteiligten bedanken.

Jetzt habe ich doch noch eine Frage :confused: :confused: :confused:
wie kann ich es hinbekommen, dass die RFID Keys

	uint8_t compare[] = {0xCA, 0x0B, 0x20, 0x58};
	uint8_t compare1[] = {0x43, 0xE0, 0x57, 0x05};
	uint8_t compare2[] = {0x4, 0x91, 0x83, 0x92, 0x91, 0x5B, 0x81};

über MQTT abgefragt werden?
Wäre für die weitere Administration sehr hilfreich.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.