//*******************************libraries********************************
//ESP32----------------------------
#include <Arduino.h>
#include <WiFi.h>
#include <HTTPClient.h>
#include <time.h>
#include <driver/ledc.h>
//RFID-----------------------------
#include <SPI.h>
#include <MFRC522.h>
//OLED-----------------------------
#include <Wire.h>
#include <Adafruit_GFX.h>          //https://github.com/adafruit/Adafruit-GFX-Library
#include <Adafruit_SSD1306.h>      //https://github.com/adafruit/Adafruit_SSD1306
//************************************************************************
#define SS_PIN 5
#define RST_PIN 27
#define SCK_PIN 18
#define MISO_PIN 19
#define MOSI_PIN 23
#define BUZZER_PIN 12
#define GREEN_LED_PIN 13
#define RED_LED_PIN 14
#define RELAY_PIN 15
#define BUTTON_PIN 2
#define ledR 25  // Pin para el LED Rojo
#define ledG 26  // Pin para el LED Verde
#define ledB 27  // Pin para el LED Azul
//Inicializamos las variables de la salida pwm
int canal=0, frec=2000, resolucion=8;

int buttonState = 0;
bool buttonPressed = false;
unsigned long buttonPressStartTime = 0;
bool accesoConcedido = false;
unsigned long accessStartTime = 0;

// Declaration for SSD1306 display connected using software I2C pins are(22 SCL, 21 SDA)
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET     0 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

//************************************************************************
MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance.
//************************************************************************
/* Set these to your desired credentials. */
const char *ssid = "Wokwi-GUEST";
const char *password = "";
const char* device_token  = "d435346d9482a5dd";
//************************************************************************
int timezone = -5 * 3600;   //Replace "x" your timezone.
int time_dst = 0;
String getData, Link;
String OldCardID = "";
unsigned long previousMillis1 = 0;
unsigned long previousMillis2 = 0;
String URL = "http://192.168.1.20/rfidattendance/getdata.php"; //computer IP or the server domain
//*************************Biometric Icons*********************************
const uint8_t PROGMEM Logo_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x0F, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xC0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xC0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xBB, 0x7F, 0xF0, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x80, 0x38, 0x03, 0xFE, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xF8, 0x00, 0x70, 0x00, 0x1F, 0x80, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xC0, 0x00, 0xE0, 0x00, 0x03, 0xE0, 0x00,
0xB0, 0x70, 0x63, 0x44, 0x03, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xF8, 0x00,
0xC8, 0x19, 0x84, 0xC4, 0xC4, 0x80, 0x00, 0x00, 0x78, 0x00, 0x01, 0xC0, 0x00, 0x00, 0x3E, 0x00,
0x84, 0x49, 0x08, 0x44, 0xCC, 0xC0, 0x00, 0x01, 0xF0, 0x00, 0x03, 0x80, 0x00, 0x00, 0x0F, 0x00,
0x84, 0x99, 0x08, 0x44, 0x48, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x07, 0x80,
0x88, 0x99, 0x84, 0xC4, 0xC4, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x03, 0xC0,
0xF0, 0x60, 0x03, 0xC7, 0x03, 0x80, 0x00, 0x07, 0x80, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x01, 0xE0,
0x80, 0x00, 0x00, 0x40, 0x00, 0x00, 0x18, 0x07, 0x80, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0xF0,
0x80, 0x00, 0x00, 0x40, 0x00, 0x00, 0x3C, 0x07, 0x80, 0x03, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x78,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x07, 0xE0, 0x1F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x78,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x03, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x01, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x3F, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E,
0x00, 0xF0, 0x00, 0x00, 0x00, 0x20, 0x1C, 0x03, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x0E,
0x03, 0xF8, 0x00, 0x00, 0x00, 0x78, 0x1C, 0x07, 0xC0, 0x00, 0x00, 0x1F, 0xF0, 0x00, 0x00, 0x0E,
0x07, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0x1C, 0x0F, 0xE0, 0x18, 0x20, 0x7F, 0xF0, 0x00, 0x00, 0x0F,
0x0F, 0x9C, 0x00, 0x00, 0x01, 0xFC, 0x1C, 0x0F, 0xF0, 0x38, 0xF0, 0xFC, 0xF0, 0x00, 0x00, 0x0F,
0x1E, 0x1C, 0x30, 0x02, 0x01, 0xEE, 0x1C, 0x1E, 0xF8, 0x39, 0xF1, 0xF0, 0x78, 0x00, 0x00, 0x0F,
0x1E, 0x3C, 0x7C, 0x0F, 0x01, 0xCE, 0x1C, 0x1E, 0x78, 0x3F, 0xC1, 0xE0, 0xF8, 0x00, 0x00, 0x0F,
0x1C, 0x78, 0x3F, 0x1F, 0x03, 0xCE, 0x1C, 0x1E, 0x3C, 0x3F, 0x83, 0xC0, 0xF8, 0x00, 0x00, 0x0F,
0x3C, 0xF8, 0x1F, 0xFE, 0x03, 0xCF, 0x1C, 0x1C, 0x3C, 0x3F, 0x03, 0x81, 0xFC, 0x00, 0x00, 0x0E,
0x1D, 0xF0, 0x07, 0xF8, 0x03, 0x8F, 0x1C, 0x1C, 0x1C, 0x3E, 0x03, 0x81, 0xFC, 0x00, 0x00, 0x1E,
0x7F, 0xE0, 0x01, 0xF8, 0x03, 0x8E, 0x1C, 0x1C, 0x1C, 0x3E, 0x07, 0x83, 0xDE, 0x00, 0x00, 0x1E,
0xFF, 0xC0, 0x01, 0xFE, 0x03, 0x8E, 0x1C, 0x1C, 0x1C, 0x3E, 0x07, 0x87, 0x8F, 0x00, 0x00, 0x3C,
0x7E, 0x00, 0x03, 0xDF, 0x87, 0x9E, 0x1C, 0x1C, 0x1E, 0x3E, 0x03, 0x8F, 0x0F, 0x00, 0x00, 0x7C,
0x1E, 0x00, 0x07, 0xC7, 0xE7, 0xBC, 0x1E, 0x1C, 0x1C, 0x3E, 0x03, 0xDF, 0x07, 0x80, 0x00, 0xF8,
0x0F, 0x00, 0x0F, 0x81, 0xFF, 0xF8, 0x1E, 0x1E, 0x1C, 0x1E, 0x03, 0xFE, 0x03, 0xE0, 0x01, 0xF8,
0x07, 0x80, 0x1E, 0x00, 0xFF, 0xF0, 0x1E, 0x1E, 0x3C, 0x1E, 0x01, 0xFC, 0x01, 0xF8, 0x0F, 0xF0,
0x03, 0xE0, 0xFC, 0x00, 0x1F, 0xC0, 0x0E, 0x0F, 0x7C, 0x1E, 0x00, 0xF0, 0x00, 0xFF, 0xFF, 0xC0,
0x01, 0xFF, 0xF8, 0x00, 0x07, 0x00, 0x0F, 0x0F, 0xF8, 0x1E, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x80,
0x00, 0xFF, 0xE0, 0x00, 0x07, 0x00, 0x07, 0x87, 0xE0, 0x0C, 0x00, 0x00, 0x00, 0x07, 0xFC, 0x00,
0x00, 0x1F, 0x00, 0x00, 0x07, 0x00, 0x07, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
#define Logo_width 128
#define Logo_height 64

#define Wifi_start_width 54
#define Wifi_start_height 49
const uint8_t PROGMEM Wifi_start_bits[] = {
  0x00,0x00,0x00,0x00,0x00,0x00,0x00
,0x00,0x00,0x00,0x00,0x00,0x00,0x00
,0x00,0x00,0x00,0x00,0x00,0x00,0x00
,0x00,0x00,0x00,0x00,0x00,0x00,0x00
,0x00,0x00,0x00,0x00,0x00,0x00,0x00
,0x00,0x00,0x1f,0xf0,0x00,0x00,0x00
,0x00,0x03,0xff,0xff,0x80,0x00,0x00
,0x00,0x1f,0xf0,0x1f,0xf0,0x00,0x00
,0x00,0x7e,0x00,0x00,0xfc,0x00,0x00
,0x01,0xf0,0x00,0x00,0x1f,0x00,0x00
,0x03,0xc0,0x00,0x00,0x07,0xc0,0x00
,0x0f,0x00,0x00,0x00,0x01,0xe0,0x00
,0x1c,0x00,0x00,0x00,0x00,0x70,0x00
,0x38,0x00,0x07,0xc0,0x00,0x38,0x00
,0x70,0x00,0xff,0xfe,0x00,0x1e,0x00
,0xe0,0x03,0xfc,0x7f,0xc0,0x0e,0x00
,0x00,0x1f,0x80,0x03,0xf0,0x00,0x00
,0x00,0x3c,0x00,0x00,0x78,0x00,0x00
,0x00,0xf0,0x00,0x00,0x1c,0x00,0x00
,0x01,0xe0,0x00,0x00,0x0c,0x00,0x00
,0x03,0x80,0x00,0x00,0x00,0x00,0x00
,0x03,0x00,0x00,0x00,0x00,0x00,0x00
,0x00,0x00,0x3f,0xf8,0x07,0x1e,0x00
,0x00,0x00,0xff,0xfe,0x1f,0xbf,0x80
,0x00,0x03,0xe0,0x04,0x7f,0xff,0xc0
,0x00,0x07,0x80,0x00,0xff,0xff,0xe0
,0x00,0x0e,0x00,0x00,0xff,0xff,0xe0
,0x00,0x0c,0x00,0x00,0x7f,0xff,0xc0
,0x00,0x00,0x00,0x00,0xfe,0x07,0xe0
,0x00,0x00,0x00,0x03,0xf8,0x03,0xf8
,0x00,0x00,0x07,0xe7,0xf9,0xf1,0xfc
,0x00,0x00,0x1f,0xe7,0xf1,0xf9,0xfc
,0x00,0x00,0x1f,0xe7,0xf3,0xf9,0xfc
,0x00,0x00,0x3f,0xe7,0xf3,0xf9,0xfc
,0x00,0x00,0x3f,0xe7,0xf1,0xf1,0xfc
,0x00,0x00,0x3f,0xe3,0xf8,0xe3,0xfc
,0x00,0x00,0x3f,0xf3,0xfc,0x07,0xf8
,0x00,0x00,0x1f,0xf0,0x7f,0x0f,0xc0
,0x00,0x00,0x0f,0xe0,0x7f,0xff,0xe0
,0x00,0x00,0x07,0xc0,0xff,0xff,0xe0
,0x00,0x00,0x00,0x00,0x7f,0xff,0xe0
,0x00,0x00,0x00,0x00,0x3f,0xff,0x80
,0x00,0x00,0x00,0x00,0x1f,0xbf,0x00
,0x00,0x00,0x00,0x00,0x03,0x18,0x00
,0x00,0x00,0x00,0x00,0x00,0x00,0x00
,0x00,0x00,0x00,0x00,0x00,0x00,0x00
,0x00,0x00,0x00,0x00,0x00,0x00,0x00
,0x00,0x00,0x00,0x00,0x00,0x00,0x00
,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};
#define Wifi_connected_width 63
#define Wifi_connected_height 49
const uint8_t PROGMEM Wifi_connected_bits[] = {
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
,0x00,0x00,0x03,0xff,0xff,0x80,0x00,0x00
,0x00,0x00,0x3f,0xff,0xff,0xf8,0x00,0x00
,0x00,0x01,0xff,0xff,0xff,0xff,0x00,0x00
,0x00,0x0f,0xff,0xff,0xff,0xff,0xe0,0x00
,0x00,0x3f,0xff,0xc0,0x07,0xff,0xf8,0x00
,0x00,0xff,0xf8,0x00,0x00,0x3f,0xfe,0x00
,0x03,0xff,0x80,0x00,0x00,0x03,0xff,0x80
,0x07,0xfe,0x00,0x00,0x00,0x00,0xff,0xc0
,0x1f,0xf8,0x00,0x00,0x00,0x00,0x3f,0xf0
,0x3f,0xe0,0x01,0xff,0xff,0x00,0x0f,0xf8
,0x7f,0x80,0x0f,0xff,0xff,0xe0,0x03,0xfc
,0xff,0x00,0x7f,0xff,0xff,0xfc,0x01,0xfe
,0xfc,0x01,0xff,0xff,0xff,0xff,0x00,0x7e
,0x78,0x07,0xff,0xc0,0x07,0xff,0xc0,0x3c
,0x00,0x0f,0xfc,0x00,0x00,0x7f,0xe0,0x00
,0x00,0x1f,0xf0,0x00,0x00,0x1f,0xf0,0x00
,0x00,0x3f,0xc0,0x00,0x00,0x07,0xf8,0x00
,0x00,0x7f,0x00,0x01,0x00,0x01,0xfc,0x00
,0x00,0x7e,0x00,0x7f,0xfc,0x00,0xfc,0x00
,0x00,0x3c,0x03,0xff,0xff,0x80,0x78,0x00
,0x00,0x00,0x07,0xff,0xff,0xc0,0x00,0x00
,0x00,0x00,0x1f,0xff,0xff,0xf0,0x00,0x00
,0x00,0x00,0x3f,0xf0,0x1f,0xf8,0x00,0x00
,0x00,0x00,0x3f,0x80,0x03,0xf8,0x00,0x00
,0x00,0x00,0x3f,0x00,0x01,0xf8,0x00,0x00
,0x00,0x00,0x1c,0x00,0x00,0x70,0x00,0x00
,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00
,0x00,0x00,0x00,0x0f,0xe0,0x00,0x00,0x00
,0x00,0x00,0x00,0x1f,0xf0,0x00,0x00,0x00
,0x00,0x00,0x00,0x3f,0xf8,0x00,0x00,0x00
,0x00,0x00,0x00,0x3f,0xf8,0x00,0x00,0x00
,0x00,0x00,0x00,0x3f,0xf8,0x00,0x00,0x00
,0x00,0x00,0x00,0x3f,0xf8,0x00,0x00,0x00
,0x00,0x00,0x00,0x1f,0xf0,0x00,0x00,0x00
,0x00,0x00,0x00,0x0f,0xe0,0x00,0x00,0x00
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};
//************************************************************************

void setup() {

   //Inicializamos la salida del pwm
  ledcSetup(canal,frec,resolucion);
  //Declaramos pin donde se conecta el zumbador
  ledcAttachPin(BUZZER_PIN, 0);

  pinMode(BUZZER_PIN, OUTPUT);
  pinMode(GREEN_LED_PIN, OUTPUT);
  pinMode(RED_LED_PIN, OUTPUT);
  pinMode(RELAY_PIN, OUTPUT);
  pinMode(BUTTON_PIN, INPUT_PULLUP); // Usa la resistencia interna para activar la resistencia pull-up
  pinMode(ledR, OUTPUT);
  pinMode(ledG, OUTPUT);
  pinMode(ledB, OUTPUT);

  digitalWrite(GREEN_LED_PIN, LOW); // Apaga el LED verde
  digitalWrite(RED_LED_PIN, LOW); // Apaga el LED rojo
  digitalWrite(RELAY_PIN, LOW); // Apaga el relé

  delay(1000);
  Serial.begin(115200);
  SPI.begin(SCK_PIN, MISO_PIN, MOSI_PIN); // Iniciar bus SPI
  mfrc522.PCD_Init(); // Init MFRC522 card
  //-----------initiate OLED display-------------
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
    Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
  }
  // Display the logo
  display.clearDisplay();
  display.drawBitmap(0, 0, Logo_bits, Logo_width, Logo_height, WHITE);
  display.display();
  delay(2000);
  display.clearDisplay();
  //---------------------------------------------
  connectToWiFi();
  //---------------------------------------------
  configTime(timezone, time_dst, "pool.ntp.org","time.nist.gov");
}

//************************************************************************
void loop() {

  if (WiFi.status() == WL_CONNECTED) {
    // WiFi está conectado, mostrar LED en azul
    digitalWrite(ledR, LOW);
    digitalWrite(ledG, LOW);
    digitalWrite(ledB, HIGH);
  }

  delay(1000); // Pausa de 1 segundo entre actualizaciones

  display.setTextSize(2);             // Normal 2:2 pixel scale
  display.setTextColor(WHITE);        // Draw white text
  buttonState = digitalRead(BUTTON_PIN);

  if (buttonState == LOW && !buttonPressed) {
    display.clearDisplay();
    buttonPressed = true;
    buttonPressStartTime = millis();
    display.setCursor(15,0);
    display.println("Pulsador");
    display.setCursor(12,20);
    display.println("Activado");
    ledcWriteTone(0, 400); // Play a 1000 Hz tone
    delay(3000); // Play for 1 second
    digitalWrite(GREEN_LED_PIN, HIGH); // Enciende el LED verde
    digitalWrite(RED_LED_PIN, LOW); // Apaga el LED rojo
    digitalWrite(RELAY_PIN, HIGH); // Enciende el relé
  }

  if (buttonPressed && millis() - buttonPressStartTime >= 7000) {
    // Han pasado 7 segundos desde que se presionó el botón
    digitalWrite(GREEN_LED_PIN, LOW); // Apaga el LED verde
    digitalWrite(RELAY_PIN, LOW); // Apaga el relé
    ledcWriteTone(0, 0); // Stop the tone by setting frequency to 0
    buttonPressed = false; // Reinicia el estado del botón
  }

  display.display();
  delay(200); // Pequeño retardo para evitar rebotes en el botón

  //check if there's a connection to Wi-Fi or not
  if(!WiFi.isConnected()){
    connectToWiFi();    //Retry to connect to Wi-Fi
  }
  //---------------------------------------------
  if (millis() - previousMillis1 >= 5000) {
    previousMillis1 = millis();
    display.clearDisplay();
    
    time_t now = time(nullptr);
    struct tm* p_tm = localtime(&now);
    display.setTextSize(1);             // Normal 2:2 pixel scale
    display.setTextColor(WHITE);        // Draw white text
    display.setCursor(10,0);
    Serial.println(p_tm);
    display.setTextSize(4);             // Normal 2:2 pixel scale
    display.setTextColor(WHITE);        // Draw white text
    display.setCursor(0,21);
    if ((p_tm->tm_hour)<10) {display.print("0");display.print(p_tm->tm_hour);}
    else display.print(p_tm->tm_hour);
    display.print(":");
    if ((p_tm->tm_min)<10) {display.print("0");display.println(p_tm->tm_min);}
    else display.println(p_tm->tm_min);
    display.display();
  }
  //---------------------------------------------
  if (millis() - previousMillis2 >= 15000) {
    previousMillis2 = millis();
    OldCardID="";
  }
  delay(50);
  //---------------------------------------------
  //look for new card
  if ( ! mfrc522.PICC_IsNewCardPresent()) {
    return;//got to start of loop if there is no card present
  }
  // Select one of the cards
  if ( ! mfrc522.PICC_ReadCardSerial()) {
    return;//if read card serial(0) returns 1, the uid struct contians the ID of the read card.
  }
  String CardID ="";
  for (byte i = 0; i < mfrc522.uid.size; i++) {
    CardID += mfrc522.uid.uidByte[i];
  }
  //---------------------------------------------
  if( CardID == OldCardID ){
    return;
  }
  else{
    OldCardID = CardID;
  }
  //---------------------------------------------
//  Serial.println(CardID);
  SendCardID(CardID);
  delay(1000);
  display.clearDisplay();
}

//************send the Card UID to the website*************
void SendCardID( String Card_uid ){
  Serial.println("Sending the Card ID");
  if(WiFi.isConnected()){
    HTTPClient http;    //Declare object of class HTTPClient
    //GET Data
    getData = "?card_uid=" + String(Card_uid) + "&device_token=" + String(device_token); // Add the Card ID to the GET array in order to send it
    //GET methode
    Link = URL + getData;
    http.begin(Link); //initiate HTTP request   //Specify content-type header
    
    int httpCode = http.GET();   //Send the request
    String payload = http.getString();    //Get the response payload

//    Serial.println(Link);   //Print HTTP return code
    Serial.println(httpCode);   //Print HTTP return code
    Serial.println(Card_uid);     //Print Card ID
    Serial.println(payload);    //Print request response payload

    if (httpCode == 200) {
      if (payload.substring(0, 5) == "Acceso Concedido: ") {
        String user_name = payload.substring(5);
    //  Serial.println(user_name);
        display.clearDisplay();
        display.setTextSize(2);             // Normal 2:2 pixel scale
        display.setTextColor(WHITE);        // Draw white text
        display.setCursor(15,0);             // Start at top-left corner
        display.print(F("Bienvenido"));
        display.setCursor(12,20);
        display.print(user_name);
        display.display();
        ledcWriteTone(0, 1000); // Play a 1000 Hz tone
        delay(1000); // Play for 1 second
        digitalWrite(GREEN_LED_PIN, HIGH); // Enciende el LED verde
        digitalWrite(RED_LED_PIN, LOW); // Apaga el LED rojo
        digitalWrite(RELAY_PIN, HIGH); // Enciende el relé

      accesoConcedido = true;
      accessStartTime = millis();
      }
       if (accesoConcedido && millis() - accessStartTime >= 10000) {
    // Han pasado 10 segundos desde que se concedió el acceso
    digitalWrite(GREEN_LED_PIN, LOW); // Apaga el LED verde
    digitalWrite(RED_LED_PIN, LOW); // Apaga el LED rojo
    digitalWrite(RELAY_PIN, LOW); // Apaga el relé
    ledcWriteTone(0, 0); // Stop the tone by setting frequency to 0
    accesoConcedido = false; // Reinicia el estado del acceso
      }
      else if (payload.substring(0, 6) == "Acceso Denegado") {
        String user_name = payload.substring(6);
    //  Serial.println(user_name);
        display.clearDisplay();
        display.setTextSize(2);             // Normal 2:2 pixel scale
        display.setTextColor(WHITE);        // Draw white text
        display.setCursor(15,0);             // Start at top-left corner
        display.print(F("Acceso Denegado"));
        display.setCursor(12,20);
        display.print(user_name);
        display.display();
        ledcWriteTone(0, 500); // Play a 1000 Hz tone
        delay(1000); // Play for 1 second
        digitalWrite(GREEN_LED_PIN, LOW); // Apaga el LED verde
        digitalWrite(RED_LED_PIN, HIGH); // Enciende el LED rojo
        digitalWrite(RELAY_PIN, LOW); // Apaga el relé
      }
      else if (payload == "succesful") {
        display.clearDisplay();
        display.setTextSize(2);             // Normal 2:2 pixel scale
        display.setTextColor(WHITE);        // Draw white text
        display.setCursor(5,0);             // Start at top-left corner
        display.print(F("New Card"));
        display.display();
      }
      else if (payload == "available") {
        display.clearDisplay();
        display.setTextSize(2);             // Normal 2:2 pixel scale
        display.setTextColor(WHITE);        // Draw white text
        display.setCursor(5,0);             // Start at top-left corner
        display.print(F("Free Card"));
        display.display();
      }
      delay(100);
      http.end();  //Close connection
    }
  }
}
//********************connect to the WiFi******************
void connectToWiFi(){
    WiFi.mode(WIFI_OFF);        //Prevents reconnection issue (taking too long to connect)
    delay(1000);
    WiFi.mode(WIFI_STA);
    Serial.print("Connecting to ");
    Serial.println(ssid);
    WiFi.begin(ssid, password);

    while (WiFi.status() != WL_CONNECTED) {
    digitalWrite(ledR, HIGH);
    digitalWrite(ledG, LOW);
    digitalWrite(ledB, LOW);
    delay(500);

    digitalWrite(ledR, LOW);
    digitalWrite(ledG, LOW);
    digitalWrite(ledB, LOW);
    delay(500);

    Serial.println("Conectando a WiFi...");
  }

  Serial.println("Conectado a WiFi");

    display.clearDisplay();
    display.setTextSize(1);             // Normal 1:1 pixel scale
    display.setTextColor(WHITE);        // Draw white text
    display.setCursor(0, 0);             // Start at top-left corner
    display.print(F("Connecting to \n"));
    display.setCursor(0, 50);   
    display.setTextSize(2);          
    display.print(ssid);
    display.drawBitmap( 73, 10, Wifi_start_bits, Wifi_start_width, Wifi_start_height, WHITE);
    display.display();
    
    while (WiFi.status() != WL_CONNECTED) {
      delay(500);
      Serial.print(".");
    }
    Serial.println("");
    Serial.println("Connected");
    
    display.clearDisplay();
    display.setTextSize(2);             // Normal 1:1 pixel scale
    display.setTextColor(WHITE);        // Draw white text
    display.setCursor(8, 0);             // Start at top-left corner
    display.print(F("Connected \n"));
    display.drawBitmap( 33, 15, Wifi_connected_bits, Wifi_connected_width, Wifi_connected_height, WHITE);
    display.display();
    
    Serial.print("IP address: ");
    Serial.println(WiFi.localIP());  //IP address assigned to your ESP
    
    delay(1000);
}
//=======================================================================
NOCOMNCVCCGNDINLED1PWRRelay Module