Bonjour et Bienvenue pour un nouveau billet de Blog pour le lecteur de Carte MiFare.
Dans l'actuel et le prochain billet de la Série, nous nous pencherons sur les Domaines de la Sécurité et de Flexibilité.
Nous voulons la Sécurité et la Flexibilité de notre Lecteur de lumière, ainsi que plus de Transparence dans les Kartenleseraktionen soucis. Un grand Manque, le précédent Parties de cette Série avaient été que, bien que le Mot de passe de connexion de l'Administrateur (admin) sur l'Interface web, de Lecteur de cartes Lecteur de cartes différence, ce Mot de passe n'est pas modifiable individuellement était.
Ce que nous voulons aujourd'hui de changer. Il est maintenant possible, sur les W
eboberfläche sous Système -> Sécurité d'une salle de Mot de passe pour l'Utilisateur "admin" à l'enregistrement.
Ce Mot de passe peut être entre 3 et 16 Caractères.
Peut être réglé de cette définie Zeichenspanne avec les Définitions PwMinLength et PwMaxLength dans le Code. Si plus courte ou plus longue Passwortgrenzen désiré, les Valeurs peuvent être adaptés individuellement.
La Procédure de changement de mot de passe de l'Utilisateur "admin" est:
• votre première connexion à l'Interface web à l'aide du nom d'Utilisateur "admin" et le Mot de passe composé de l'ESP ChipId. (Comme dans les Parties précédentes de la Série décrit précédemment)
• Navigation sous-Système -> Sécurité, puis 2x la même chose (nouveau) Mot de passe et Bouton ... appuyez sur.
• Déconnexion du Système> Déconnexion. Le nouveau Mot de passe est immédiatement valable.
Nous avons donc la Sécurité, ou au contraire augmente, de sorte que quelqu'un de notre Projet connaît et Accès à l'Interface série et sur le Réseau a, pas le valide mot de passe de connexion à comprendre.
Nous arrivons maintenant à un autre Point de la Rubrick de la Sécurité: Il serait de Sicherheitssicht souhaitable de savoir par qui, quand et avec quelle Carte nos Lecteur de cartes correctement ou n'est pas correctement utilisé. Pour ce faire, nous créons maintenant la Possibilité. Sous la nouvelle Rubrique "Journal des événements", nous voyons maintenant les différentes Entrées pour certains d'Actions ou d'Événements autour de nos Lecteurs.
Par exemple, nous voyons maintenant, dans le Journal des événements, toutes les Tentatives en cours de validité et carte non valide nos Lecteurs à une Action pour se déplacer.
La Capture d'écran suivante illustre cela de façon exemplaire:
Comme dans l'o. g la Capture d'écran est la Collection de l'Heure et de la Date, ni générique à un prix fixe de Valeur, puisque nous une source d'heure valide manquant. Cette Source, nous sommes dans l'une des prochaines Parties pour ajouter.
Essentiel pour le Journal d'événements de l'Initialisation correcte et d'une Utilisation interne, programme de stabilité électronique SPIFFS Filesystems. Pour cela, nous les Kompilieroptionen pour un de nos disponibles 4 MO de mémoire de programme 2 MO SPIFFS système de Fichiers sont formatés. Comment ce passe, j'ai déjà parlé dans un autre billet de Blog "ESP8266 – Tout SPIFFS ou quoi?" de moi à l'Établissement.
Important: Sans le bon SPIFFS Paramètre, le Code est bien compilé et sur le programme de stabilité électronique téléchargé, mais reste au Démarrage de l'ESP avec le Message "ATF:NOK" sur l'Interface série "accrocher" et les autres Initalisierung échoue. Cette SPIFFS devons-nous pour toutes les autres Parties suivantes de cette Série est conservée.
Le Code de notre aujourd'hui le Blog est:
#include <SPI.h> #include <MFRC522.h> #include <ESP8266WiFi.h> #include <ESP8266WebServer.h> #include <ESP8266mDNS.h> #include <EEPROM.h> #include <FS.h> // Include the SPIFFS library #define RST_PIN 5 // SPI Broche Reset (D1 Sortie) #define RELAIS_PIN 16 // Relais (D0 Sortie) [Active LOW] - Internes LED, à proximité du Port USB #define SS_PIN 15 // Broche de sélection esclave SPI #define RGBLED_R 2 // rouge (sortie D4) #define RGBLED_G 0 // Vert (sortie D3) - Également LED interne sur le module ESP #define RGBLED_B 4 // bleu (sortie D2) #define WiFiPwdLen 25 // Longueur maximale du mot de passe WiFi #define STANAMELEN 20 // Longueur maximale du SSID WiFi #define ESPHostNameLen 20 // Nombre maximum de caractères ESPHostName #define KEYA vrai // Définition du drapeau PICC #define KEYB faux // Définition du drapeau PICC #define LED_BUILTIN 16 #define PIN_WIRE_SDA 4 #define PIN_WIRE_SCL 5 #define PwMinLength 3 // Longueur minimale du mot de passe de connexion #define PwMaxLength 16 // Longueur maximale du mot de passe de connexion #define LoginNameMaxLength 16 // Longueur maximale du nom de connexion #define USED_Sector 1 // Secteur de carte utilisé pour les données d'authentification et de configuration (valide: 1 à 15) ADC_MODE(ADC_TOUT); // Configurez l'entrée analogique A0 sur externe. ADC_TOUT (pour tension externe), ADC_VCC (pour tension système). MFRC522 mfrc522(SS_PIN, RST_PIN); // Créer une instance du MFRC522 MFRC522::MIFARE_Key clé; ESP8266WebServer serveur(80); // Créer une instance de serveur Web Fichier monfichier; // crée une variable de gestion SPIFFS FSInfo fs_info; struct WiFiEEPromData // Longueur d'objet de 68 octets { char ESPHostName[ESPHostNameLen]; // 20 char APSTAName[STANAMELEN]; // Nom du point STATION / AP TO Connect, si défini 20 char WiFiPwd[WiFiPwdLen]; // WiFiPAssword, si défini 25 char ConfigValid[3]; // Si la configuration est Vaild, le tag "TK" est requis "3 }; struct MiFareClassicKeyTable { octet Key_A[6] = {0x22, 0x44, 0xFA, 0xAB, 0x90, 0x11}; // Veuillez changer la clé de la carte PICC. octet Key_B[6] = {0xFE, 0xE1, 0xAA, 0x3D, 0xDF, 0x37}; // Veuillez changer la clé de la carte PICC. char ConfigValid[3]; // Si Config est Vaild, le tag "TK" est requis " }; struct SysConf // { char LoginName[LoginNameMaxLength]; // 16 char LoginPassword[PwMaxLength]; // 16 bool PCD_Disabled; // 1 octet USED_PICC_Sector; // 1 char ConfigValid[3]; // Si Config est Vaild, le tag "TK" est requis "// 3 }; MiFareClassicKeyTable MiFareClassicKey; WiFiEEPromData MyWiFiConfig; SysConf SystemConfiguration; // Variables utilisées mondialement bool Résultat = faux; bool LearnNewCard = faux; bool EraseCard = faux; bool ExpirationDateActive = faux; bool PCD_Disabled = faux; String Nom de famille; String Givenname; String ExpirationDate; String temp; non signé longue SessionID; non signé longue PCD_ServiceCall_Handler = 0; non signé longue PCD_WatchDog_Handler = 0; uint8_t DataBuffer[18] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; nul configuration() { pinMode(RST_PIN, SORTIE); digitalWrite(RST_PIN, ÉLEVÉ); pinMode(RELAIS_PIN, SORTIE); pinMode(RGBLED_R, SORTIE); pinMode(RGBLED_G, SORTIE); pinMode(RGBLED_B, SORTIE); digitalWrite(RELAIS_PIN, ÉLEVÉ); // relais inactif SetRGBLed(255, 0, 255, faux); // La couleur LED pourpre commence l'initialisation Série.commencer(115200); // Initialise la communication série avec le PC avec 115200 bauds Série.println(F(" ")); temp = "ATSN:" + String(ESP.getChipId()); Série.println(temp); // Serial.print ("Valeur ADC:"); Serial.println (analogRead (A0)); SPI.commencer(); // Initialiser la communication SPI PCDHardReset(); SessionID = millis(); Résultat = loadSysConfig(); Résultat = InitalizeFileSystem(); Résultat = startWiFiClient(); InitalizeHTTPServer(); temp = "Démarrage du système:"; temp += String(ESP.getResetReason()); WriteToLog(temp, 0); temp = ""; ESP.wdtEnable(4000); // Démarrer le chien de garde SetRGBLed(0, 0, 255, faux); // L'initialisation de la couleur bleue de la LED est terminée } // ******************* Démarrer les fonctions d'aide / d'optimisation ************************ ******** nul SetRGBLed(octet RedValue, octet GreenValue, octet BlueValue, booléen SlowFade) // Fonction de contrôle de la led RGB { digitalWrite(RGBLED_R, LOW); digitalWrite(RGBLED_G, LOW); digitalWrite(RGBLED_B, LOW); if (RedValue == 255) { digitalWrite(RGBLED_R, HIGH); } if (GreenValue == 255) { digitalWrite(RGBLED_G, HIGH); } if (BlueValue == 255) { digitalWrite(RGBLED_B, HIGH); } } // ******************* Stop Helper/ Optimisation de Fonctions ********************************* // ******************* Démarrer Functions Serveur web ******************************************* //le Cookie Basisroutinen sont basés sur GIT est un Extrait: //https://github.com/esp8266/ESPWebServer/blob/master/examples/SimpleAuthentification/SimpleAuthentification.ino bool is_authentified() { if (serveur.hasHeader("Cookie")) { // Cookie trouvé temp = serveur.header("Cookie"); //Serial.println(temp); String SessionStr = String(ESP.getChipId()) + "=" + String(Idsession); rendement(); si (temp.indexOf(SessionStr) != -1) { // Web de l'Authentification erfolgreich temp = ""; de retour true; } } // Web de l'Authentification fehlgeschlagen temp = ""; SessionID = millis(); retour de faux; } vide handleLogin() { String msg; //Chaîne de cookie = server.l'en-tête("Cookie"); //Serial.println(cookie); si (le serveur.hasArg("DÉCONNECTER")) { //Déconnexion de Benutzers; SessionID = millis(); temp = Chaîne(ESP.getChipId()) + "= NA ; HttpOnly ; SameSite=Stricte"; serveur.sendHeader("Set-Cookie", temp); temp = "Abmeldung von Webinterface."; WriteToLog(temp, 0); temp = ""; PCD_Disabled = false; // PCD aktivieren nach déconnexion ; SetRGBLed(0, 0, 255, false); //Led Farbe Blau StandardModre serveur.sendHeader("Emplacement", "/login"); serveur.sendHeader("Cache-Control", "no-cache"); serveur d'.envoyer(301); serveur.envoyer(301); //yield(); } si (le serveur.hasArg("nom d'utilisateur") && serveur.hasArg("MOT de passe")) { temp = Chaîne(ESP.getChipId()); si (le serveur.arg("nom d'utilisateur") == SystemConfiguration.LoginName && serveur.arg("MOT de passe") == SystemConfiguration.LoginPassword ) { serveur.sendHeader("Emplacement", "/"); serveur.sendHeader("Cache-Control", "no-cache"); SessionID = millis(); temp = Chaîne(ESP.getChipId()) + "=" + Chaîne(SessionID) + "; HttpOnly ; SameSite=Stricte"; serveur.sendHeader("Set-Cookie", temp); temp = ""Anmeldung von " + serveur.arg("nom d'utilisateur") + " un Webinterface."; WriteToLog(temp, 0); temp = ""; serveur.envoyer(301); PCD_Disabled = vrai; // PCD deaktivieren, solange Par Web gearbeitet wird; SetRGBLed(255, 0, 255, false); //Led Couleur Lila dans Servicemode retour; } msg = "<script>alert('Falscher Benutzername oder falsches mot de passe !');</script>"; temp = "Fehlerhafter Anmeldeversuch von " + serveur.arg("nom d'utilisateur") + " un Webinterface. Mot de passe: " + serveur.arg("MOT de passe") ; WriteToLog(temp, 1); temp = ""; } CSS_Header_Template(); temp = "<head><title>Login</title></head><body><DIV ALIGN=CENTER>"; serveur.sendContent(temp); temp = "<h2> " Anmeldung un Kartenleser RC522</h2><corps><br><br><table border=0 bgcolor=black><tr><th><DIV ALIGN=RIGHT>"; serveur.sendContent(temp); temp = "<form action='/login' method='post'>Benutzername: <input type=text Name='nom d'utilisateur' Size=17 required><br>"; serveur.sendContent(temp); temp = "mot de passe: <input type=password Name= "PASSWORD" Size=17 required><br><br><br><button type= "submit""; serveur.sendContent(temp); temp = "nom='Login_Button' value='1' style='height: 30px; width: 100px' >Login</bouton><br></th></tr></form></DIV></table>"; serveur.sendContent(temp); temp = "<br><SMALL>Damit die " Anmeldung funktioniert, sind Cookies für diese Webseite zu erlauben.</SMALL>"; serveur.sendContent(temp); temp = msg + "</DIV></body></HTML>"; serveur.sendContent(temp); temp = ""; } vide handleNotFound() { SessionID = millis(); temp = "Page nicht gefunden.\n\n"; temp += "URI: "; temp += serveur.uri(); temp += "\nMethod: "; temp += (serveur.méthode() == HTTP_GET) ? "GET", : "POST"; temp += "\nArguments: "; temp += serveur.args(); temp += "\n"; pour (u_int8_t je = 0; je < serveur.args(); je++) { temp += " " + serveur.argName(je) + ": " + serveur.arg(i) + "\n"; } rendement(); serveur.envoyer(404, "text/plain", temp); temp = "Aufruf der ungültigen URL: " + serveur.uri() + " Paramètre: " + Chaîne de(serveur.args()) ; WriteToLog(temp, 2); temp = ""; } vide handleErasePICC() { si (!is_authentified()) { serveur.sendHeader("Emplacement", "/login"); serveur.sendHeader("Cache-Control", "no-cache"); serveur d'.envoyer(301); le rendement(); de retour; } CSS_Header_Template(); rendement(); temp = "<head><title>Kartenleser RC522</title></head><body>"; serveur.sendContent(temp); HtmlNavStructure(); temp = "<script>alert('Bitte JETZT die zu löschende Karte vor den Leser halten!');</script>"; serveur.sendContent(temp); rendement(); EraseCard = vrai; PCD_Disabled = faux; SetRGBLed(0, 255, 255, false); //Led Couleur cyan Programmierungsmodus temp = "</body></html>"; serveur.sendContent(temp); serveur.client().arrêter(); temp = ""; } vide handleSettings() { si (!is_authentified()) { serveur.sendHeader("Emplacement", "/login"); serveur.sendHeader("Cache-Control", "no-cache"); serveur d'.envoyer(301); retour; } CSS_Header_Template(); temp = "<head><title>Kartenleser RC522</title></head><body>"; serveur.sendContent(temp); HtmlNavStructure(); temp = "<br><br><br><div align=center><form method='post' action='/paramètres' method='post'>"; serveur.sendContent(temp); temp = "<p><label>Neues Anmeldepasswort</label><br / > <input type='mot de passe' nom= "newPassword'>"; serveur.sendContent(temp); temp = "</p><p><label>Wiederholung Anmeldepasswort</label><br / > <input type= "password" name='confirmNewPassword'><br><br><br>"; serveur.sendContent(temp); temp = "<button type='submit' name='Enregistrer' value='1' style='height: 30px; width: 200px' >Speichern</bouton></p></form></div>"; serveur.sendContent(temp); // temp = "</p><p><button type='submit' name='save'>Speichern</bouton></p></form></div></body></html>"; si (le serveur.hasArg("Enregistrer")) { si (serveur.arg("confirmNewPassword") == serveur.arg("newPassword")) { temp = serveur.arg("newPassword"); si ((temp.longueur() < PwMinLength ) | (temp.longueur() > PwMaxLength )) { temp = "<br><div align=center><br>Das Kennwort muss zwischen minimum "; serveur.sendContent(temp); temp = Chaîne(PwMinLength) + " und maximale " + Chaîne(PwMaxLength) + " Zeichen lang sein.</div>"; serveur.sendContent(temp); } d'autre { temp = serveur.arg("newPassword"); temp.toCharArray(SystemConfiguration.LoginPassword , PwMaxLength); saveSysConfig(); temp = "Das Anmeldekennwort von Benutzer " + Chaîne(SystemConfiguration.LoginName) + " wurde geändert."; WriteToLog(temp, 0); temp = "<script>alert ("Das Anmeldekennwort wurde erfolgreich geändert.');</script>"; serveur.sendContent(temp); } } d'autre { temp = "<br><div align=center><br>Die eingegebenen Kennwörter stimmen nicht überein. Bitte nochmals eingeben.</div>"; serveur.sendContent(temp); } } temp = "</body></html>"; serveur.sendContent(temp); serveur.client().arrêter(); temp = ""; } vide handleNewPICC() { si (!is_authentified()) { serveur.sendHeader("Emplacement", "/login"); serveur.sendHeader("Cache-Control", "no-cache"); serveur d'.envoyer(301); de retour; } si (serveur.hasArg("Nom de famille") && serveur.hasArg("Givenname")) { Nom = du serveur.arg("Nom de famille"); Givenname = serveur.arg("Givenname"); ExpirationDate = serveur.arg("ExpDate"); si (serveur.hasArg("ExpDateOption")) { ExpirationDateActive = vrai; } d'autre { ExpirationDateActive = faux; } temp = "Erstellung einer neuen Karte für: " + serveur.arg("Givenname") + ", " + serveur.arg("Nom de famille"); WriteToLog(temp, 0); PCD_Disabled = faux; LearnNewCard = vrai; CSS_Header_Template(); temp = "<head><title>Kartenleser RC522</title></head><body>"; serveur.sendContent(temp); HtmlNavStructure(); temp = "<script>alert('Bitte JETZT die neue Karte vor den Leser halten!');</script>"; serveur.sendContent(temp); temp = "</body></html>"; serveur.sendContent(temp); serveur.client().arrêter(); SetRGBLed(255, 255, 0, false); //Led Couleur Gelb Programmierungsmodus rendement(); de retour; } CSS_Header_Template(); temp = "<head><title>Kartenleser RC522</title></head><body>"; serveur.sendContent(temp); HtmlNavStructure(); temp = ""; temp = "<br><br><br><br><table border=0 ALIGN=CENTER><th>"; serveur.sendContent(temp); temp = "<table border=1 bgcolor = black><form action='/newPICC' method='post'>"; serveur.sendContent(temp); temp = "<tr><th>Karteninhaber:<br><div ALIGN=RIGHT>"; serveur.sendContent(temp); temp = "Vorname: <input type=text Name='Nom' Size=17 maxlenght=16 espace réservé='Max' required><br>"; serveur.sendContent(temp); temp = "Nachname: <input type=text Name='Prénom' Size=17 maxlenght=16 placeholder='Smith' required><br>"; serveur.sendContent(temp); temp = "</div></th><th>Kartenmetadaten:<br / ><DIV ALIGN=RIGHT>"; serveur.sendContent(temp); temp = "<input Name='ExpDateOption' TYPE=checkbox VALUE=1 >Ablaufdatum:<input type= "date" Name='ExpDate' Size = 17 >"; serveur.sendContent(temp); temp = "<br><th><tr><th></table><br>"; serveur.sendContent(temp); temp = "<button type='submit' name='NewCard' value='1' style='height: 30px; width: 200px' >Neue carte à puce erstellen</bouton>"; serveur.sendContent(temp); temp = "<br / ></form></tr></th></table>"; serveur.sendContent(temp); temp = "</body></html>"; serveur.sendContent(temp); serveur.client().arrêter(); temp = ""; } vide handleLog() { int Taille = 0; si (!is_authentified()) { serveur.sendHeader("Emplacement", "/login"); serveur.sendHeader("Cache-Control", "no-cache"); serveur d'.envoyer(301); de retour; } si (serveur.hasArg("ClearLog")) { si (SPIFFS.existe ("/usage_log.csv") ) //Prüfe ob Datei usage_log.csv exisiert. { SPIFFS.supprimer("/usage_log.csv"); //Lösche Datei Série.println(F("ATF:LogDelete")); temp = "Ereignisprotokollierungsdatei soient supprimés."; WriteToLog(temp, 0); temp = ""; } d'autre { Série.println(F("ATF:LogDelete_ERR")); } rendement(); } CSS_Header_Template(); rendement(); temp = "<head><title>Kartenleser RC522</title></head><body>"; serveur.sendContent(temp); HtmlNavStructure(); temp = "<br><br><br><br><table border=4 ALIGN=CENTER><th>"; serveur.sendContent(temp); temp = "<textarea rows='20' cols='110' warp=doux readonly>"; serveur.sendContent(temp); si (SPIFFS.existe ("/usage_log.csv")) //Prüfe ob Datei usage_log.csv exisiert. { myfile = SPIFFS.ouvrir("/usage_log.csv",, "r"); //Öffne die Datei usage_log.csv im Racine Verzeichnis zum lesen si (!myfile) { temp = "Interner Fehler: Logdatei usage_log.csv konnte nicht geöffnet werden !"; serveur.sendContent(temp); } d'autre { de la Taille du fichier = myfile.taille(); tandis que (myfile .position() < myfile.taille()) { temp = myfile.readStringUntil('\n'); temp.garniture(); temp += "\n"; // Ajouter un Caractère de saut de Ligne serveur.sendContent(temp); } myfile.proche(); } } d'autre { temp = "Interner Fehler: Logdatei usage_log.csv nicht gefunden !"; serveur.sendContent(temp); } temp = "</textarea></th></table><table border=0 ALIGN=CENTER>"; serveur.sendContent(temp); SPIFFS.info(fs_info); temp = "<br><div ALIGN=CENTER> Loggroesse " + Chaîne de(Taille) + " Octets.<br>"; serveur.sendContent(temp); temp = Chaîne(fs_info.usedBytes) + " Octets von " + Chaîne(fs_info.totalBytes) + " Octets belegt.</div>"; serveur.sendContent(temp); temp = "<th><form action='/log' method='post'><br><br>"; serveur.sendContent(temp); temp = "<button type='submit' name='RefreshLog' value='1' style='height: 30px; width: 100px' >Actualiser</bouton>"; serveur.sendContent(temp); temp = "<button type='submit' name='ClearLog' value='1' style='height: 30px; width: 100px' >Effacer Journal</bouton>"; serveur.sendContent(temp); temp = "</form></th></table></HTML>"; serveur.sendContent(temp); serveur.client().arrêter(); temp = ""; } vide handleRoot() { si (!is_authentified()) { serveur.sendHeader("Emplacement", "/login"); serveur.sendHeader("Cache-Control", "no-cache"); serveur d'.envoyer(301); de retour; } // Contenu HTML CSS_Header_Template(); rendement(); temp = "<head><title>Kartenleser RC522</title></head><body>"; serveur.sendContent(temp); HtmlNavStructure(); temp = "<div ALIGN=CENTER><br><br><br><br><BIG>Willkommen auf der Smartkartenleser RC522 Site.</BIG><br>"; serveur.sendContent(temp); temp = "Resetgrund: " + Chaîne(ESP.getResetReason()) + "<br>"; serveur.sendContent(temp); temp = "Freier Heapspeicher: " + Chaîne(ESP.getFreeHeap()) + " Octets<br>"; serveur.sendContent(temp); temp = "Int. Flash: " + Chaîne(ESP.getFlashChipRealSize()) + " Octets<br>"; serveur.sendContent(temp); Résultat = mfrc522.PCD_PerformSelfTest(); mfrc522.PCD_Init(); // Initialisiere MFRC522 Lesemodul mfrc522.PCD_SetAntennaGain(mfrc522.RxGain_max); // Setzt Antenne auf max. Empfang mfrc522.PCD_AntennaOn(); de rendement(); si le (Résultat) { temp = "RC522 PCD-Statut: OK<br>"; } d'autre { temp = "RC522 PCD-Statut: Fehler!<br>"; } serveur.sendContent(temp); temp = CPU ID: " + Chaîne(ESP.getChipId()) + " @ " + Chaîne(ESP.getCpuFreqMHz()) + " MHz<br>"; serveur.sendContent(temp); temp = "<br / >Sie sind erfolgreich angemeldet !<br>"; serveur.sendContent(temp); temp = "<br>Programmiert von <a href='mailto:tobias.kuch@googlemail.com'>Tobias Kuch</a><br></div></body></html>"; serveur.sendContent(temp); si (serveur.hasArg("Reboot") ) // Redémarrer le Système { temp = "<script>alert('Das System startet JETZT neu.');</script>"; serveur.sendContent(temp); serveur.client().arrêter(); de rendement(); temp = ""; ESP.réinitialiser le(); délai(4000); } de serveur de.client().arrêter(); temp = ""; } vide CSS_Header_Template() // Formatvorlage für alle internen ESP de nos sites web. https://wiki.selfhtml.org/wiki/CSS { serveur.setContentLength(CONTENT_LENGTH_UNKNOWN); temp = ""; serveur.envoyer (200, "text/html", temp); temp = "<!DOCTYPE HTML PUBLIC "- /- //W3C//DTD HTML 4.01 Transitional//EN "><html lang= " de " ><meta charset='UTF-8'>"; serveur.sendContent(temp); temp = "<style type='text/css'>*{margin: 0;padding: 0;}body{background:black;color:darkorchid;font-size: 16px;"; serveur.sendContent(temp); temp = "font-family: sans-serif,arial;}.nav{width: 1300px;height: 30px;margin: 0 auto;border-radius: 5px;}"; serveur.sendContent(temp); temp = "ul li{list-style: none;width: 200px;line-height: 60px;position: relative;fond: darkorchid;"; serveur.sendContent(temp); temp = "box-shadow: 0px 2px 5px 0px gris;text-align: center;float: left;background-color: #010000;}ul li ul{"; serveur.sendContent(temp); temp = "position: absolute;}.nav > ul > li:nth-of-type(1){border-radius: 5px 0px 0px 5px;}.nav > ul > li:nth-of-type(5)"; serveur.sendContent(temp); temp = "{border-radius: 0px 5px 5px 0px;}ul li a{color: rgb(182, 18, 18);width: 200px;height: 58px;display: inline-block;"; serveur.sendContent(temp); temp = "text-decoration: none;}ul li a:hover{font-weight: bold;border-bottom: 2px solid #fff;}ul li ul{display: none;}"; serveur.sendContent(temp); temp = ".nav ul li:hover ul{display: block;}.fa{margin-right: 5px;}.conteneur{width: 1000px;height: 200px;"; serveur.sendContent(temp); temp = "margin: 0 auto;padding:20px 20px;}@media screen and (max-width: 480px){header{width: 100%;}"; serveur.sendContent(temp); temp = ".nav{display: none;width: 100%;height: auto;}ul li{width: 100%;float: none;}ul li a{width: 100%;"; serveur.sendContent(temp); temp = "display: block;}ul li ul{position: static;}ul li ul li a{background: #222;}.fa-liste.modifier{display: block;}"; serveur.sendContent(temp); temp = ".conteneur{width: 100%;height: auto;}body{overflow-x:hidden;}}</style>"; serveur.sendContent(temp); temp = ""; } vide HtmlNavStructure() { temp = "<div class= "menu" ><nav class='nav'><ul>"; serveur.sendContent(temp); temp = "<li><a href='#'>Système</a>"; serveur.sendContent(temp); temp = "<ul><li><a href="/fr">d'Information</a></li>"; serveur.sendContent(temp); temp = "<li><a href="/fr/paramètres">Sicherheit</a></li>"; serveur.sendContent(temp); temp = "<li><a href="/fr/login?DÉBRANCHEZ=1">Abmelden</a></li>"; serveur.sendContent(temp); temp = "<li><a href="/fr/?Reboot=YES">Neustart</a></li>"; serveur.sendContent(temp); temp = "</ul>"; serveur.sendContent(temp); temp = "</li><li><a href='#'>CCIP</a>"; serveur.sendContent(temp); temp = "<ul><li><a href="/fr/newPICC">Neue Karte erstellen</a></li>"; serveur.sendContent(temp); temp = "<li><a href="/fr/erasePICC">Karte löschen</a></li></ul>"; serveur.sendContent(temp); temp = "</li>"; temp = "</li><li><a href="/log">Ereignisprotokoll</a></li>"; serveur.sendContent(temp); temp = "</ul></nav></div>"; serveur.sendContent(temp); temp = ""; } vide InitalizeHTTPServer() { bool initok = faux; const char * headerkeys[] = {"User-Agent", "Cookie"} ; //en-Tête zum Tracken size_t headerkeyssize = sizeof(headerkeys) / sizeof(char*); //en-Tête zum Tracken serveur.sur("/", handleRoot); serveur.sur("/login", handleLogin); serveur.sur("/newPICC", handleNewPICC); serveur.sur("/erasePICC", handleErasePICC); serveur.sur("/"paramètres, handleSettings); serveur.sur("/log", handleLog); serveur.onNotFound ( handleNotFound ); serveur.collectHeaders(headerkeys, headerkeyssize );// Serveur anweisen, diese zu Tracken serveur de.commencer(); / serveur Web/ start } // ******************* Fin des Fonctions de Serveur web ********************************************* // ******************* Les Fonctions De Démarrage Du Système De Fichiers ****************************************** boolean InitalizeFileSystem() { bool initok = faux; initok = SPIFFS.commencer(); retard(200); // Sans retard, j'ai vu l'adresse IP vide si (!(initok)) // Format SPIFS, de ne pas formaté. - Essayez 1 { Série.println(F("ATF:FRM")); SPIFFS.format(); initok = SPIFFS.commencer(); } si (!(initok)) // Format SPIFS, de ne pas formaté. - Essayez 2 { SPIFFS.format(); initok = SPIFFS.commencer(); } si (initok) { Série.println(F("ATF:OK")); } else { Série.println(F("ATF:NOK")); } retour initok; } boolean WriteToLog(Chaîne LogEntry, octet Logtype) { bool writeok = faux; SPIFFS.info(fs_info); si (fs_info.totalBytes - fs_info.usedBytes - 2000 > 1) // Speicherplatz überprüfen { myfile = SPIFFS.ouvrir("/usage_log.csv",, "a"); //Öffne die Datei usage_log.csv im Racine Verzeichnis zum schreiben si (!myfile) { myfile.près(); de Série.println(F("ATF:InitLog_ERR")); retour writeok; } temp = ""; temp += "01.01.1980 12:00:00 "; // noch EchtDatum hinzufügen commutateur (Logtype) { cas 0: temp += "Info: "le; saut de; cas 1: temp += "service warnung: "; casser; cas 2: temp += "Erreur: "; pause; par défaut: temp += "Info: "; pause; } temp += LogEntry; writeok = myfile.println(temp); si (!(writeok)) { Série.println(F("ATF:WriteLog_ERR")); } myfile.près(); temp = ""; } de retour writeok; } // ******************* Fin des Fonctions du système de fichiers ******************************************** // ******************* Les Fonctions De Démarrage WiFi De Gestion ************************************* // Funktion von https://www.az-delivery.de/blogs/azdelivery-blog-fur-arduino-und-raspberry-pi/wps-mit-dem-esp8266?ls=de bool startWPS() { bool wpsSuccess = WiFi.beginWPSConfig(); si (wpsSuccess) { // Muss nicht immer erfolgreich heißen! Nach einem Délai ist die SSID leer Chaîne newSSID = WiFi.SSID(); si (newSSID.longueur() > 0) { // Nur wenn eine SSID gefunden wurde waren wir erfolgreich rendement de la(); Série.println(F("ATWPS:OK")); saveCredentials(); // Enregistrer les informations d'Identification dans la mémoire EEPROM } d'autre { Série.println(F("ATWPS:NOK")); } } retour wpsSuccess; } bool startWiFiClient() { bool WiFiClientStarted = faux; size_t A0_ADCValue = 0; octet je = 0; octet connRes = 0; Série.setDebugOutput(false); // Zu Debugzwecken aktivieren. WiFi.nom d'hôte("CrdRdr41667"); WiFi.softAPdisconnect(vrai); WiFi.déconnecter(); le WiFi.en mode(WIFI_STA); si (loadCredentials()) { WiFi.commencer(MyWiFiConfig.APSTAName, MyWiFiConfig.WiFiPwd); tout (( connRes != 3 ) et ( connRes != 4 ) et (j' != 30)) //si connRes == 0 "IDLE_STATUS - changement Statius" { j'++; // Serial.print(F(".")); // Connexion vorgang auf der seriellen Schnittstelle beobachten //ESP.wdtFeed(); delay(500); rendement(); connRes = WiFi.waitForConnectResult(); } si (connRes == 4 ) { // si le mot de passe est incorrect Série.println(F("ATWIFI:PWDERR")); WiFi.déconnecter(); } si (connRes == 6 ) { // module n'est pas configuré en mode station de Série.println(F("ATWIFI:STAERR")); WiFi.déconnecter(); } } si (WiFi.statut() == WL_CONNECTED) { //ESP.wdtFeed(); Serial.print(F("de l'AIPRP:")); Série.println(WiFi.localIP()); WiFi.setAutoReconnect(vrai); // Définir si le module va tenter de vous reconnecter à un point d'accès dans le cas où il est déconnecté. // Le programme d'installation MDNS répondeur si (!MDNS.commencer("CrdRdr41667")) { Série.println(F("ATMDNS:NOK")); } d'autre { MDNS.addService("http",, "tcp", 80); } WiFiClientStarted = vrai; } d'autre { A0_ADCValue = analogRead(A0); //Wir waren nicht erfolgreich, daher starten wir WPS, wenn WPS Dégustateur un A0 während des Réinitialise gedrückt ist si (A0_ADCValue > 499) { si (startWPS()) { //ESP.wdtFeed(); delay(500); WiFi.déconnecter(); le WiFi.en mode(WIFI_STA); WiFi.commencer(WiFi.SSID().c_str(), WiFi.psk().c_str()); //ESP.wdtFeed(); WiFiClientStarted = vrai; } d'autre { WiFiClientStarted = faux; WiFi.déconnecter(); } } d'autre { WiFi.débrancher(); } } //WiFi.printDiag(de Série); // Zu Debugzwecken aktivieren. retour WiFiClientStarted; } // ******************* FIN des Fonctions WiFi de Gestion ************************************* // ******************* les Fonctions de Démarrage Store WiFi informations d'Identification dans la mémoire EEPROM ****************** bool loadCredentials() { bool RetValue; EEPROM.commencer(512); EEPROM.obtenir(0, MyWiFiConfig); EEPROM.fin(); si (la Chaîne(MyWiFiConfig.ConfigValid) == "SAVOIRS traditionnels") { RetValue = vrai; } d'autre { RetValue = false; // Paramètres WLAN nicht gefunden. } //ESP.wdtFeed(); retour RetValue; } vide saveCredentials() // Speichere WLAN informations d'identification de l'auf EEPROM { size_t je; pour (je = 0 ; je < sizeof(MyWiFiConfig) ; j'++) // Loeschen der alten Konfiguration { EEPROM.écrire(je, 0); } pour (je = 0 ; je < STANameLen ; j'++) // Loeschen der alten Konfiguration { MyWiFiConfig.WiFiPwd[je] = 0; } pour (je = 0 ; je < WiFiPwdLen ; j'++) // Loeschen der alten Konfiguration { MyWiFiConfig.APSTAName[je] = 0; } temp = WiFi.SSID().c_str(); je = temp.longueur de(); temp.toCharArray(MyWiFiConfig.APSTAName, je + 1); temp = WiFi.psk().c_str(); je = temp.longueur de(); temp.toCharArray(MyWiFiConfig.WiFiPwd, je + 1); temp = ""; strncpy(MyWiFiConfig.ConfigValid , "SAVOIRS traditionnels",, sizeof(MyWiFiConfig.ConfigValid) ); EEPROM.commencer(512); EEPROM.mettre(0, MyWiFiConfig); EEPROM.commettre(); EEPROM.fin(); //ESP.wdtFeed(); } void saveSysConfig() { octet je; strncpy(SystemConfiguration.ConfigValid , "SAVOIRS traditionnels",, sizeof(SystemConfiguration.ConfigValid) ); EEPROM.commencer(512); EEPROM.mettre(80, SystemConfiguration); EEPROM.commettre(); EEPROM.fin(); //ESP.wdtFeed(); } bool loadSysConfig() { bool RetValue; EEPROM.commencer(512); EEPROM.obtenir(80, SystemConfiguration); EEPROM.fin(); si (la Chaîne(SystemConfiguration.ConfigValid) == "SAVOIRS traditionnels") { RetValue = vrai; } d'autre { temp = Chaîne(ESP.getChipId()); temp.toCharArray(SystemConfiguration.LoginPassword , PwMaxLength); temp = ""; strncpy(SystemConfiguration.LoginName , , "admin",, sizeof(SystemConfiguration.LoginName) ); SystemConfiguration.PCD_Disabled = faux; SystemConfiguration.USED_PICC_Sector = 1; saveSysConfig(); RetValue = false; // Paramètres de configuration de nicht gültig //Standardinitalisierung ausführe } //ESP.wdtFeed(); return RetValue; } // ******************* FIN des Fonctions StoreCredentialsto EEPROM *************************** // ******************* les Fonctions de Démarrage CardServices ************************************* void PCDHardReset() { digitalWrite(RST_PIN, FAIBLE); retard(200); digitalWrite(RST_PIN, HAUTE); mfrc522.PCD_Reset(); mfrc522.PCD_Init(); // Initialisiere MFRC522 Lesemodul mfrc522.PCD_SetAntennaGain(mfrc522.RxGain_max); // Setzt Antenne auf max. Empfang mfrc522.PCD_AntennaOn(); } boolean CardAuthenticate(boolean ABKey, octet Secteur de l', octet ikey[6]) { const byte sectorkeytable [16] = {3, 7, 11, 15, 19, 23, 27, 31, 35, 39, 43, 47, 51, 55, 59, 63}; octet situation; situation = 0; pour (int un = 0; a < 6; une++) { clé.keyByte[un] = ikey[un]; } // la Clé Un si (ABKey) { situation = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, sectorkeytable[Secteur], &clé, &(mfrc522.uid)); si la (situation != MFRC522::STATUS_OK) { Série.println(F("ATAUTH:ERR_A")); return false; } } // Touche B d'autre si (pas ABKey) { situation = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_B, sectorkeytable[Secteur], &clé, &(mfrc522.uid)); si la (situation != MFRC522::STATUS_OK) { Série.println(F("ATAUTH:ERR_B")); return false; } } return true; } // WriteData . utilise la Variable Globale DataBuffer pour le Retour de Données boolean CardDataWrite(octet Secteur de l', octet du bloc, d'octets de la valeur[16]) { de l'octet d'état; octet writevector; octet sectorkeytable [16] = {3, 7, 11, 15, 19, 23, 27, 31, 35, 39, 43, 47, 51, 55, 59, 63}; writevector = Secteur de * 4 + bloc - 1 ; pour les (octets un = 0; un < 16; un++) { si (writevector == sectorkeytable[un]) { // Serial.println("NAK"); return false; } } statut = mfrc522.MIFARE_Write(writevector, valeur, 16); si (le statut de != MFRC522::STATUS_OK) { Série.println(F("ATPCD:W_ERR")); //Série".println(mfrc522.GetStatusCodeName(status)); return false; } else { // Serial.print(F("ATPCD:Write_Card_OK")); return true; } } // Lecture de Données utilise la Variable Globale DataBuffer pour le Retour de Données boolean CardDataRead(octet Secteur de l', octet du bloc) { d'octets statusi; octet readvector; const byte sectorkeytable [16] = {3, 7, 11, 15, 19, 23, 27, 31, 35, 39, 43, 47, 51, 55, 59, 63}; octets de taille = 18; readvector = Secteur de * 4 + bloc - 1 ; pour les (octets un = 0; un < 16; un++) { si (readvector == sectorkeytable[une]) { Série.println(F("ATPCD:R_ERR")); return false; } } statusi = mfrc522.MIFARE_Read(readvector, DataBuffer, &de taille); si (statusi != MFRC522::STATUS_OK) { Série.println(F("ATPCD:R_ERR")); return false; } else { return true; } } boolean ResetCardToDefault() { octet ikey[16]; octet d'état, je; octet writevector; const byte sectorkeytable [16] = {3, 7, 11, 15, 19, 23, 27, 31, 35, 39, 43, 47, 51, 55, 59, 63}; writevector = sectorkeytable[USED_Sector]; si (CardAuthenticate(KEYB, USED_Sector, MiFareClassicKey.Key_B)) // Secteur Autenticate pour l'Accès en ÉCRITURE { pour (je = 0; je <= 16; je++) { DataBuffer[je] = 0; } si (!(CardDataWrite(USED_Sector, 1, DataBuffer))) { retourner false; } pour (je = 0; je <= 16; je++) { DataBuffer[je] = 0; } si (!(CardDataWrite(USED_Sector, 2, DataBuffer))) { retourner false; } pour (je = 0; je <= 16; je++) { DataBuffer[je] = 0; } si (!(CardDataWrite(USED_Sector, 3, DataBuffer))) { retourner false; } } pour (byte i = 0; i <= 16; i++) { ikey[j'] = 255; //Chargement de la Clé par Défaut pour tous les Secteurs } ikey[6] = 0xFF; // Le Réglage par défaut pour l'Accès Bits ikey[7] = 0x07; // ikey[8] = 0x80; // ikey[9] = 0x69; statut = mfrc522.MIFARE_Write(writevector, ikey, 16); si (le statut de != MFRC522::STATUS_OK) { return false; } return true; } boolean SetSectorAccessControl (octet Secteur de l', octet Akey[6], octet Clef[6]) { octet ikey[16]; octet d'état; octet writevector; const byte sectorkeytable [16] = {3, 7, 11, 15, 19, 23, 27, 31, 35, 39, 43, 47, 51, 55, 59, 63}; writevector = sectorkeytable[Secteur]; ikey[0] = Akey[0]; ikey[1] = Akey[1]; ikey[2] = Akey[2]; ikey[3] = Akey[3]; ikey[4] = Akey[4]; ikey[5] = Akey[5]; ikey[6] = 0x78; // Bloc de Données 0 À 3 Conditions d'Accès: Touche B / écriture de la Clé de Lecture ikey[7] = 0x77; // la CLÉ UN & TOUCHE B & Acces Bits Écrire:B Clé / Clé d'Un Accès en Lecture Bits ikey[8] = 0x88; // Calculatrice: http://calc.gmss.ru/Mifare1k/ ikey[9] = 0x69; // Fixateur Wert - > par défaut hex 69 ikey[10] = Clef[0]; ikey[11] = Clef[1]; ikey[12] = Clef[2]; ikey[13] = Clef[3]; ikey[14] = Clef[4]; ikey[15] = Clef[5]; statut = mfrc522.MIFARE_Write(writevector, ikey, 16); si (le statut de != MFRC522::STATUS_OK) { Série.println(F("ATPCD:W_KEY_ERR")); return false; } else { return true; } } boolean CheckforDefaultCardKey () { octet tkey[6]; boolean CardResult; octet readvector; octet statusi; const byte sectorkeytable [16] = {3, 7, 11, 15, 19, 23, 27, 31, 35, 39, 43, 47, 51, 55, 59, 63}; octets de taille = 18; pour les (byte i = 0; i <= 6; i++) { tkey[j'] = 255; //Chargement de la Clé par Défaut pour tous les Secteurs } CardResult = vrai; si (!CardAuthenticate(KEYA, USED_Sector, tkey)) { CardResult = faux; }; readvector = sectorkeytable[USED_Sector]; statusi = mfrc522.MIFARE_Read(readvector, DataBuffer, &de taille); si (statusi != MFRC522::STATUS_OK) { CardResult = false; } //if (!((DataBuffer[7] = 0x07) & (DataBuffer[7] = 0x80))) { CardResult = false; }; retour CardResult; } boolean WriteNewMiFareClassicPICC () { octet tkey[6]; octet j'ai, un; booléen CardResult; si (CheckforDefaultCardKey()) { pour (je = 0; je <= 6; je++) { tkey[j'] = 255; //Chargement de la Clé par Défaut pour tous les Secteurs } pour (je = 0; je <= 16; je++) { DataBuffer[j'] = 0; // Effacer la Variable Tampon } CardResult = vrai; si (CardAuthenticate(KEYA, USED_Sector, tkey)) // Secteur Autenticate { // Serial.println("Auth Sec 0 OK"); si le (Nom de famille.de la longueur() > 15) { d'une = 15; } autre personne { un = Nom de famille.longueur(); } si le (Nom de famille.de la longueur() > 0) { pour (je = 0; je <= 16; je++) { DataBuffer[je] = 0; } pour (je = 0; je <= un; je++) { DataBuffer[je] = Nom[je]; } si (!(CardDataWrite(USED_Sector, 2, DataBuffer))) { CardResult = false; //Le secteur 0 du Bloc 2 Vorname mit la Clé Un schreiben } } si (Givenname.la longueur() > 15) { d'une = 15; } autre personne { un = Prénom.longueur(); } si (Givenname.la longueur() > 0) { pour (je = 0; je <= 16; je++) { DataBuffer[je] = 0; } pour (je = 0; je <= un; je++) { DataBuffer[je] = Givenname[je]; } si (!(CardDataWrite(USED_Sector, 3, DataBuffer))) { CardResult = false; //Le secteur 0 du Bloc 3 Nachname mit la Clé Un schreiben } } si (!(SetSectorAccessControl (USED_Sector, MiFareClassicKey.Key_A, MiFareClassicKey.Key_B))) { CardResult = false; // (octets par Secteur,byte Akey[6],byte Clef[6]) } } d'autre { CardResult = faux; retour CardResult; } } d'autre { CardResult = faux; retour CardResult; } si (CardResult) { //Serial.println("PICC écrite"); CardResult = true; } else { //Serial.println("PICC n'est pas vide"); CardResult = faux; } rendement(); de retour CardResult; } boolean ReadMiFareClassicPICC () { boolean CardResult; octet je ; CardResult = vrai; si (CardAuthenticate(KEYA, USED_Sector, MiFareClassicKey.Key_A)) // Secteur Autenticate avec la Touche de LECTURE d'Un { Givenname = " "; //espace Réservé Nom de famille = " "; //espace Réservé pour (je = 0; je < 18; je++) { DataBuffer[j'] = 0; // Effacer la Variable Tampon } si (CardDataRead(USED_Sector, 2)) // Feld Vorname auslesen { pour (je = 0; je < 16; je++) { Nom[je] = char(DataBuffer[j']); } } else { return false; } pour (je = 0; je < 18; je++) { DataBuffer[j'] = 0; // Effacer la Variable Tampon } si (CardDataRead(USED_Sector, 3)) // Feld Nachname auslesen { pour (je = 0; je < 16; je++) { Givenname[j'] = char(DataBuffer[j']); } } else { return false; } } else { return false; } return true; } vide CardServer() { byte i ; #define PCD_Poll_Interval 400 #define PCD_Watchdog_Interval 60000 si (millis() - PCD_ServiceCall_Handler >= PCD_Poll_Interval) { PCD_ServiceCall_Handler = millis(); si (mfrc522.PICC_IsNewCardPresent()) // CCIP = proximité integrated circuit card = kontaktlose Chipkarte { mfrc522.PICC_ReadCardSerial(); rendement(); // Unterscheidung nach Kartentyp // 0x08 für MIFARE Classic 1K // 0x18 für MIFARE Classic 4K // 0x11 für MIFARE PLUS si (mfrc522.uid.sak == 0x08 || mfrc522.uid.sak == 0x18) { // MiFare_Classic_Processor DÉMARRER (mfrc522.uid.sak); // Nur ausführen wenn Eine Mifare Classic Karte vor den Leser gehalten wurde. octet tkey[6]; pour (byte i = 0; i <= 6; i++) { tkey[j'] = 255; //Chargement de la Clé par Défaut pour tous les Secteurs } si (LearnNewCard) // neue Karte soll angelernt werden. { si (WriteNewMiFareClassicPICC()) { SetRGBLed(0, 255, 0, faux); LearnNewCard = faux; } d'autre { SetRGBLed(255, 0, 0, faux); LearnNewCard = faux; } } sinon si (EraseCard) // KartenDaten sollen soient supprimés werden. { si (ResetCardToDefault()) { SetRGBLed(0, 255, 0, faux); EraseCard = faux; } d'autre { SetRGBLed(255, 0, 0, faux); EraseCard = faux; } } sinon { si (ReadMiFareClassicPICC()) { // Karte gültig ! Série.d'impression (F("ATAUTH_S:")); Série.println (Nom); de Série.d'impression (F("ATAUTH_G:")); Série.println (Givenname); temp = "Gültige Karte. Benutzer: "; pour le (je = 0; je < 16; je++) { si (Givenname[je] == 0) { pause; } temp += char(Givenname[je]); } temp += ", "; pour (je = 0; je < 16; je++) { si (Nom[je] == 0) { pause; } temp += char(Nom de famille[je]); } temp += " - UUID der Karte: "; pour (byte i = 0; i < 4; i++) { temp += Chaîne(mfrc522.uid.uidByte[je], HEX) + " "; } WriteToLog(temp, 0); temp = " "; //Faire des actions si elle est bonne Carte est détectée bool PinState = digitalRead(RELAIS_PIN); PinState = !PinState; digitalWrite(RELAIS_PIN, PinState); SetRGBLed(0, 255, 0, false); //Led Grün temp = ""; } d'autre { SetRGBLed(255, 0, 0, faux); temp = ""; pour (byte i = 0; i < 4; i++) { temp += Chaîne(mfrc522.uid.uidByte[je], HEX) + " "; } temp = "Unbekannte MiFare Classic Karte. UUID der Karte: " + temp ; WriteToLog(temp, 1); temp = ""; } } LearnNewCard = faux; // MiFare_Classic_Processor STOP (mfrc522.uid.sak); } else if (mfrc522.uid.sak == 0x00) // Mifare Ultralight { SetRGBLed(255, 0, 0, false); temp = ""; for (octets i = 0; i < 7; i++) { temp += String(mfrc522.uid.uidByte[i], HEX) + " "; } temp = "Mifare UltraLight Carte ne prend pas en charge. UUID de la Carte: " + temp; WriteToLog(temp, 1); temp = ""; } else { SetRGBLed(255, 0, 0, false); temp = ""; for (octets i = 0; i < mfrc522.uid.size; i++) { temp += String(mfrc522.uid.uidByte[i], HEX) + " "; } temp = "Carte Inconnue et le type de carte. La référence: " + String(mfrc522.uid.sak) + " UUID de la Carte: " + temp ; WriteToLog(temp, 1); temp = ""; } mfrc522.PCD_StopCrypto1(); mfrc522.PICC_HaltA(); delay(2000); SetRGBLed(0, 0, 255, false); //Led Couleur Bleu Lecteur est en État } } if (millis() - PCD_WatchDog_Handler >= PCD_Watchdog_Interval) { PCD_WatchDog_Handler = millis(); Result = mfrc522.PCD_PerformSelfTest(); yield(); mfrc522.PCD_Init(); // on Initialise MFRC522 module de lecture de nouveau mfrc522.PCD_SetAntennaGain(mfrc522.RxGain_max); // Définit l'Antenne de max. Réception mfrc522.PCD_AntennaOn(); yield(); if (!(Result)) { PCDHardReset(); Serial.println(F("ATPCD:ERR_H")); } } } // ******************* Stop Functions CardServices ************************************* void loop() // Boucle principale { server.handleClient(); // Webserveranfragen modifier if (!(PCD_Disabled) | !(SystemConfiguration.PCD_Disabled)) { CardServer(); // Lecteur de carte et les Demandes spécifiques de modifier } ESP.wdtFeed(); // Watchdog remise à zéro. Désactiver "wdt_disable();" }
Je vous souhaite beaucoup de Plaisir et beaucoup de Succès lors de la reconstruction à l'identique du Projet et jusqu'à la prochaine Fois.
3 commentaires
Markus
Hallo,
vielen Dank für das wunderbare Projekt.
Ich habe es mir einmal durchgelesen und bin gespannt wie es funktionieren wird.
Freundliche Grüße!
Martin Kurth
Leider hat Tobias dieses Projekt nicht weiter verfolgt oder veröffentlicht. Ich würde es wirklich gerne einsetzen. Aber leider hat er wohl keine Zeit mehr dafür.
Martin Kurth
Ich bekomme die Fehler nicht weg. IDE 1.8.10.
G:\BOX.heidelberg.projekt\MiFare_CardReader-master\CardReader_ESP8266_-Teil_5\CardReader_ESP8266_-Teil_5.ino:27:0: warning: "PINWIRESDA" redefined [enabled by default]
#define PIN_WIRE_SDA 4 ^In file included from C:\Users\Martin\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.2\cores\esp8266/Arduino.h:302:0,
from sketch\CardReader_ESP8266_-_Teil_5.ino.cpp:1:C:\Users\Martin\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.2\variants\nodemcu/pins_arduino.h:29:0: note: this is the location of the previous definition
#define PIN_WIRE_SDA (4) ^G:\BOX.heidelberg.projekt\MiFare_CardReader-master\CardReader_ESP8266_-Teil_5\CardReader_ESP8266_-Teil_5.ino:28:0: warning: "PINWIRESCL" redefined [enabled by default]
#define PIN_WIRE_SCL 5 ^In file included from C:\Users\Martin\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.2\cores\esp8266/Arduino.h:302:0,
from sketch\CardReader_ESP8266_-_Teil_5.ino.cpp:1:C:\Users\Martin\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.2\variants\nodemcu/pins_arduino.h:30:0: note: this is the location of the previous definition
#define PIN_WIRE_SCL (5) ^G:\BOX.heidelberg.projekt\MiFare_CardReader-master\CardReader_ESP8266_-Teil_5\CardReader_ESP8266_-_Teil5.ino: In function ‘void saveCredentials()’:
G:\BOX.heidelberg.projekt\MiFare_CardReader-master\CardReader_ESP8266_-Teil_5\CardReader_ESP8266_-_Teil5.ino:806:34: warning: iteration 20u invokes undefined behavior [-Waggressive-loop-optimizations]
MyWiFiConfig.APSTAName[i] = 0; ^G:\BOX.heidelberg.projekt\MiFare_CardReader-master\CardReader_ESP8266_-Teil_5\CardReader_ESP8266_-_Teil5.ino:804:3: note: containing loop
for (i = 0 ; i < WiFiPwdLen ; i++) // Loeschen der alten Konfiguration ^In file included from C:\Users\Martin\Documents\Arduino\libraries\MFRC522\src\MFRC522Extended.cpp:8:0:
C:\Users\Martin\Documents\Arduino\libraries\MFRC522\src\MFRC522Extended.h: In constructor ‘MFRC522Extended::MFRC522Extended(uint8_t)’:
C:\Users\Martin\Documents\Arduino\libraries\MFRC522\src\MFRC522Extended.h:81:44: warning: ‘MFRC522::MFRC522’ is deprecated (declared at C:\Users\Martin\Documents\Arduino\libraries\MFRC522\src\MFRC522.h:339): use MFRC522 [-Wdeprecated-declarations]
MFRC522Extended(uint8_t rst) : MFRC522 {}; ^C:\Users\Martin\Documents\Arduino\libraries\MFRC522\src\MFRC522.cpp: In member function ‘bool MFRC522::MIFARE_SetUid(byte*, byte, bool)’:
C:\Users\Martin\Documents\Arduino\libraries\MFRC522\src\MFRC522.cpp:1853:39: warning: ‘bool MFRC522::MIFARE_OpenUidBackdoor(bool)’ is deprecated (declared at C:\Users\Martin\Documents\Arduino\libraries\MFRC522\src\MFRC522.cpp:1709): will move to extra class in next version [-Wdeprecated-declarations]
if (!MIFARE_OpenUidBackdoor(logErrors)) { ^C:\Users\Martin\Documents\Arduino\libraries\MFRC522\src\MFRC522.cpp: In member function ‘bool MFRC522::MIFARE_UnbrickUidSector(bool)’:
C:\Users\Martin\Documents\Arduino\libraries\MFRC522\src\MFRC522.cpp:1882:34: warning: ‘bool MFRC522::MIFARE_OpenUidBackdoor(bool)’ is deprecated (declared at C:\Users\Martin\Documents\Arduino\libraries\MFRC522\src\MFRC522.cpp:1709): will move to extra class in next version [-Wdeprecated-declarations]
MIFARE_OpenUidBackdoor(logErrors); ^