ESP8266 WiFi RFID NFC RC522 PHP, HTML MySQL AJAX Bootstrap Arduino Ethernet ESP32 SigFox LoRa IoT Eagle

RFID systém so správou online - Vyskúšajte online TU!!!


Administrátor:


  • Spravuje webové rozhranie
  • V reálnom čase vidí aktivitu - priloženie karty vrátane jej adresy s časom jej priloženia s výsledkom overenia: OVERENÝ / NEOVERENÝ.
  • Hlávný prehľad ponúka 100 posledných priložení karty, má výlučne informatívny charakter.
  • V sekcii pridať kartu môže administrátor jedným kliknutím potvrdiť kartu - autorizovať ju, ktorá bola priložená, no nebola zatiaľ autorizovaná.
  • V prípade, že administrátor vie adresu karty, ktorá zatiaľ v systéme nefiguruje, môže ju do systému zadať aj manuálne.
  • Okrem zobrazenia posledných 5 priložení karty vidí administrátor všetky neautorizované doteraz priložené karty a autorizované karty vrátane dátumov a časov ich autorizácie.
  • V záložke odobrania karty je možné deautozizovať autorizovanú kartu - karta nebude figurovať ani v zozname neautozizovaných kariet, bude tam pridelená automaticky až po jej priložení.
  • V poslednej záložke - Program môže administrátor nahliadnuť do schémy zapojenia RFID čítačky s vývojovou doskou NodeMCU s čipom ESP8266, môže nahliadnuť a stiahnuť si zdrojový kód, ktorý je momentálne nahratý v mikrokontroléri.
  • Pre lepšiu prenositeľnosť programu pre NodeMCU je k dipozícii aj odkaz na knižnice RFID čítačky RC522, datasheet k čítačke a NodeMCU.
  • Možnosť prihlásenia, odhlásenia adminsitrátora, núdzové otvorenie dverí z webového prostredia v prípade straty karty a pod je dostupný iba v platenej verzii tohto softvéru.
  • Používateľ:


  • Využíva služby RFID čítačky fyzickým priložením NFC tagu, kľúčenky, karty, náramku.
  • V prípade overenia priloženého čipu mu NodeMCU odistí dvere na 5 sekúnd.
  • Pri neoverení používateľa z dôvodu neovereného čipu, prípadne nedostupnosti overenia webu mu zámok nie je odistený - nevtiahne sa.
  • Používateľ o neoverení svojho čipu ako takého nie je informovaný. Jeho pokus je zapísaný do databázy za predpokladu, že sa NodeMCU napojí na web, kde sa karta overuje.
  • Používateľ môže na overenie použiť aj svoju bankomatovú kartu, ISIC kartu, či zamestnaneckú kartu, ktorej fyzickú adresu čítačka dokáže prečítať, musí spĺňať štandard ISO/IEC 14443 A.
  • Princíp otvárania zámku:

    Technológie projektu:

  • PHP - funkčnosť systému - overenie čipu
  • HTML - grafické a funkčné prvky systému - tlačidlá, prekliky
  • AJAX - dynamické volania PHP scriptov - real-time dáta o priložení čipu k RFID čítačke
  • C - Wiring - programovací jazyk pre vývojovú dosku NodeMCU s čipom ESP8266.
  • Verzia zdarma (overenie karty, bez ďalších zabezpečovacích prvkov, bez supportu a garancie správnej funkčnosti):

    Hardvér pre projekt:

    ;
  • NodeMCU v2/v3 Lolin
  • RFID RC522 (13.56MHz)
  • Elektromagnetické relé - 5V
  • Solenoid pre zámok - 12V/24V - ovládané cez relé
  • NodeMCU - HTTPS - Core 2.5.0+: (2.3.0. Arduino core nefunkčné!)


    ESP8266 (NodeMCU) - HTTP


    /*|-------------------------------------------------------------|*/
    /*|SKETCH PRE RFID SYSTEM S WEB ADMINISTRACIOU                  |*/
    /*|VYHOTOVIL: MARTIN CHLEBOVEC                                  |*/
    /*|FB: https://www.facebook.com/martin.s.chlebovec              |*/
    /*|EMAIL: martinius96@gmail.com                                 |*/
    /*|Doska: ESP8266 Generic / NodeMCU / WEmos D1 Mini + NXP RC522 |*/
    /*|CORE: 2.7.4 compatible                                       |*/
    /*|Testovacie web rozhranie: http://arduino.clanweb.eu/rfid/    |*/
    /*|-------------------------------------------------------------|*/
    
    //#define OTA //odkomentuj pre OTA UPDATE CEZ LAN cez espota.py
    #include <ESP8266WiFi.h>
    #include <SPI.h>
    #include <RFID.h>
    
    #ifdef OTA
    #include <ESP8266mDNS.h>
    #include <WiFiUdp.h>
    #include <ArduinoOTA.h>
    #endif
    
    const char * ssid = "WIFI_NAME";
    const char * password = "WIFI_PASSWORD";
    
    const char * host = "arduino.clanweb.eu";
    const int httpPort = 80; //http port
    const int rele = 16; //GPIO16 == D0
    #define SS_PIN 4
    #define RST_PIN 5
    RFID rfid(SS_PIN, RST_PIN);
    unsigned long kod;
    WiFiClient client;
    void setup() {
      Serial.begin(9600);
      SPI.begin();
      rfid.init();
      pinMode(rele, OUTPUT);
      digitalWrite(rele, HIGH); //hotfix
      WiFi.begin(ssid, password);
      while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
      }
    #ifdef OTA 
      // Port defaults to 8266
      // ArduinoOTA.setPort(8266);
    
      // Hostname defaults to esp8266-[ChipID]
      // ArduinoOTA.setHostname("myesp8266");
    
      // No authentication by default
      // ArduinoOTA.setPassword((const char *)"123");
    
      ArduinoOTA.onStart([]() {
        Serial.println("Start");
      });
      ArduinoOTA.onEnd([]() {
        Serial.println("\nEnd");
      });
      ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
        Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
      });
      ArduinoOTA.onError([](ota_error_t error) {
        Serial.printf("Error[%u]: ", error);
        if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
        else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
        else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
        else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
        else if (error == OTA_END_ERROR) Serial.println("End Failed");
      });
      ArduinoOTA.begin();
    #endif  
      Serial.println("");
      Serial.println("WiFi uspesne pripojene");
      Serial.println("IP adresa: ");
      Serial.println(WiFi.localIP());
      Serial.println("Ready");
    }
    
    void loop() {
      if (WiFi.status() != WL_CONNECTED) {
        WiFi.begin(ssid, password);
      }
      while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
      }
    #ifdef OTA 
      ArduinoOTA.handle();
    #endif 
      if (rfid.isCard()) {
        if (rfid.readCardSerial()) {
          Serial.println(" ");
          Serial.println("Card found");
          kod = 10000 * rfid.serNum[4] + 1000 * rfid.serNum[3] + 100 * rfid.serNum[2] + 10 * rfid.serNum[1] + rfid.serNum[0];
          client.stop();
          String kodik = String(kod);
          String data = "kod=" + kodik;
          String url = "/rfid/karta.php";
          if (client.connect(host, httpPort)) {
            client.println("POST " + url + " HTTP/1.0");
            client.println("Host: " + (String)host);
            client.println("User-Agent: ESP8266");
            client.println("Connection: close");
            client.println("Content-Type: application/x-www-form-urlencoded;");
            client.print("Content-Length: ");
            client.println(data.length());
            client.println();
            client.println(data);
            while (client.connected()) {
              String line = client.readStringUntil('\n');
              if (line == "\r") {
                break;
              }
            }
            String line = client.readStringUntil('\n');
            if (line.indexOf("OK") > 0) {
              Serial.println(F("VSTUP POVOLENY"));
              Serial.println(F("DVERE ODOMKNUTE"));
              digitalWrite(rele, LOW); //invertovane spinane rele active LOW
              delay(5500);              //cas otvorenia dveri
              digitalWrite(rele, HIGH); //zatvor zamok
              Serial.println(F("DVERE ZAMKNUTE"));
            } else if (line.indexOf("NO") > 0) {
              Serial.println(F("VSTUP ZAMIETNUTY"));
            } else {
              Serial.println(F("Prosim pockajte s dalsim overenim karty 5 sekund!"));
            }
          }
        }
      }
    
      rfid.halt();
    }
    
    

    ESP32 - HTTP


    /*|--------------------------------------------------------|*/
    /*|Project: RFID remote database access webapp             |*/
    /*|ESP32 (DevKit, Generic), Arduino Core with FreeRTOS     |*/
    /*|Autor: Martin Chlebovec (martinius96)                   |*/
    /*|E-mail: martinius96@gmail.com                           |*/
    /*|Test web interface: http://arduino.clanweb.eu/rfid/     |*/
    /*|Usage license: MIT                                      |*/
    /*|Revision: 31. March 2022                                |*/
    /*|Tested stable ESP32 core: 2.0.2                         |*/
    /*|657 kB flash usage, 37 kB RAM usage                     |*/
    /*|--------------------------------------------------------|*/
    
    #include <WiFi.h>
    #include <SPI.h>
    #include <MFRC522.h>
    
    unsigned long code;
    const int rele = 17; //RELAY PIN
    #define SS_PIN 21 //CHIP SELECT PIN
    #define RST_PIN 22 //RESET PIN
    
    const char * ssid = "MY_WIFI"; //WiFi hotspot name
    const char * password = "MY_WIFI_PASSWORD"; //WiFi hotspot password
    const char* host = "arduino.clanweb.eu"; //domain - host
    String url = "/rfid/karta.php"; //URL behind host domain --> target PHP file
    
    
    
    TaskHandle_t Task1; //ULTRASONIC MEASUREMENT
    TaskHandle_t Task2; //WIFI HTTP SOCKET
    QueueHandle_t  q = NULL;
    
    WiFiClient client; //socket client object
    MFRC522 rfid(SS_PIN, RST_PIN);
    static void Task1code( void * parameter);
    static void Task2code( void * parameter);
    void dump_byte_array(byte *buffer, byte bufferSize);
    
    void setup() {
      Serial.begin(115200);
      SPI.begin();
      rfid.PCD_Init(); // Init MFRC522
      rfid.PCD_SetAntennaGain(112); // set antenna gain to max (00001110)
      rfid.PCD_DumpVersionToSerial(); //Write version of Firmware to UART
      pinMode(rele, OUTPUT);
      digitalWrite(rele, HIGH); //hotfix
      WiFi.begin(ssid, password); //pripoj sa na wifi siet s heslom
      while (WiFi.status() != WL_CONNECTED) {
        delay(1000);
        Serial.print(".");
      }
      Serial.println(F(""));
      Serial.println(F("Wifi connected with IP:"));
      Serial.println(WiFi.localIP());
      q = xQueueCreate(20, sizeof(unsigned long));
      if (q != NULL) {
        Serial.println(F("Queue FIFO buffer is created"));
        vTaskDelay(1000 / portTICK_PERIOD_MS); //wait for a second
        xTaskCreatePinnedToCore(
          Task1code,   /* Task function. */
          "Task1",     /* name of task. */
          10000,       /* Stack size of task */
          NULL,        /* parameter of the task */
          1,           /* priority of the task */
          &Task1,      /* Task handle to keep track of created task */
          1);          /* pin task to core 1 */
        Serial.println(F("RFID handler task started"));
        xTaskCreatePinnedToCore(
          Task2code,   /* Task function. */
          "Task2",     /* name of task. */
          10000,       /* Stack size of task */
          NULL,        /* parameter of the task */
          1,           /* priority of the task */
          &Task2,      /* Task handle to keep track of created task */
          0);          /* pin task to core 0 */
        Serial.println(F("HTTP Socket task started"));
      } else {
        Serial.println(F("Queue creation failed"));
      }
    }
    
    void loop() {
      if (WiFi.status() != WL_CONNECTED) {
        WiFi.begin(ssid, password); //pripoj sa na wifi siet s heslom
      }
      while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
      }
      yield();
    
    }
    
    static void Task1code( void * parameter) {
      unsigned long RFIDcode;
      if (q == NULL) {
        Serial.println(F("Queue in RFID handler task is not ready"));
        return;
      }
      while (1) {
        if (rfid.PICC_IsNewCardPresent() && rfid.PICC_ReadCardSerial()) {
          dump_byte_array(rfid.uid.uidByte, rfid.uid.size);
          rfid.PICC_HaltA();
          rfid.PCD_StopCrypto1();
          RFIDcode = code;
          xQueueSend(q, (void *)&RFIDcode, (TickType_t )0); //add RFID card UID to Queue
        }
      }
    }
    static void Task2code( void * parameter) {
      unsigned long RFIDcode;
      if (q == NULL) {
        Serial.println(F("Queue in HTTP socket task is not ready"));
        return;
      }
      while (1) {
        xQueueReceive(q, &RFIDcode, portMAX_DELAY); //read measurement value from Queue and run code below, if no value, WAIT until portMAX_DELAY
        String data = "kod=" + RFIDcode;
        client.stop();
        if (client.connect(host, 80)) {
          client.println("POST " + url + " HTTP/1.0");
          client.println("Host: " + (String)host);
          client.println("User-Agent: ESP32");
          client.println("Connection: close");
          client.println("Content-Type: application/x-www-form-urlencoded;");
          client.print("Content-Length: ");
          client.println(data.length());
          client.println();
          client.println(data);
          while (client.connected()) {
            String line = client.readStringUntil('\n');
            if (line == "\r") {
              break;
            }
          }
          String line = client.readStringUntil('\n');
          if (line.indexOf("OK") > 0) {
            Serial.println(F("ACCESS GAINED"));
            Serial.println(F("DOORS OPENED"));
            digitalWrite(rele, LOW); //inverted ACTIVE-LOW logic
            vTaskDelay(5500 / portTICK_PERIOD_MS); //duration of doors opened
            digitalWrite(rele, HIGH); //lock doors pack
            Serial.println(F("DOORS CLOSED"));
          } else if (line.indexOf("NO") > 0) {
            Serial.println(F("ACCESS REJECTED"));
          } else {
            Serial.println(F("WAIT 5 seconds before next attempt!"));
          }
        } else {
          Serial.println(F("Connection to webserver was not successful!"));
        }
        client.stop();
      }
    }
    
    void dump_byte_array(byte *buffer, byte bufferSize) {
      for (byte i = 0; i < bufferSize; i++) {
      }
      Serial.print(F("Detected UID (code) of RFID CARD: "));
      code = 10000 * buffer[4] + 1000 * buffer[3] + 100 * buffer[2] + 10 * buffer[1] + buffer[0]; //finalny kod karty
      //Serial.println(code);
    }
    
    

    Zapojenie:


    RC522 NodeMCU
    3.3V 3.3V
    RST D1 (GPIO5)
    GND GND
    MISO D6 (GPIO12)
    MOSI D7 (GPIO13)
    SCK D5 (GPIO14)
    SDA D2 (GPIO4)
    IRQ Nezapája sa

    Relé NodeMCU
    5V VIN / VUSB (Adaptér/USB napájanie)
    GND GND
    IN D0 (GPIO16)

    Relé Solenoid
    NO IN
    COM -
    NC 12/24 DC/AC

    RFID - schematics - ESP8266

    RFID vrátnik - schéma zapojenia: ESP8266 (NodeMCU) s čítačkou RC522

    RFID - schematics - ESP32

    RFID vrátnik - schéma zapojenia: ESP32 (Devkit) s čítačkou RC522