Soluções voltadas a segurança de sistemas são parte da realidade de muitas pessoas atualmente, afinal, quem nunca se deparou com um leitor biométrico, câmeras de vigilância, etc. Componentes como RC522, são aplicados a construção de Interfaces de acesso, monitorando informações referentes a usuários ou objetos através da leitura de cartões, etiquetas ou chaveiros, com a capacidade de emitir sinais de radiofrequência. Este tipo de tecnologia poderá ser encontrada tanto em catracas de transportes públicos, debitando valores digitalmente, quanto em soluções domótica, servindo como chave de acesso a determinados cômodos, desbloqueio de alarmes, e até mesmo para o acionamento de outros componentes eletrônicos. Neste post, iremos explorar o funcionamento deste tipo de tecnologia controlado por placas ESP32, descobrindo inicialmente como ler e armazenar informações em um determinado dispositivo, finalizando com uma transmissão de informações via Telegram, explorando o desenvolvimento de um sistema de monitoramento mobile.
Circuito Elétrico
Para concluir as atividades desse post, tenha em mãos os seguintes componentes:
- Placa DOIT ESP32 - ESP-WROOM-32 - WiFi / Bluetooth;
- Led Difuso RGB - 5mm;
- Resistor 1K - 1/4W - 5%;
- Kit Jumper Macho Macho;
- Protoboard 400 Pontos;
- Kit RFID - RC522;
- Fonte 12V - 5V/3,3V p/ Protoboard;
- Conversor AC/DC 90~240 VAC - 5VDC/1A - JP4;
Você pode compra-los clicando nos links acima ou visitando nosso site: www.curtocircuito.com.br.
O funcionamento do leitor RFID será baseado no chip MF-RC522 da empresa NXP, que opera com uma frequência de 13,56 MHz , classificada como ultra-alta frequência (UHF), possibilitando a leitura e o armazenamento de informações em cartões do padrão Mifare. A comunicação entre o leitor e o microcontrolador será obtida através da interface SPI, correspondendo aos pinos MISO (GPIO19), MOSI (GPIO23), CLK (GPIO18) e SCO (GPIO5) do ESP32. A ordem de conexão será apresentada na imagem abaixo:
O leitor deverá se restringir a 3,3V, o pino RQ deverá permanecer desconectado, e RST será declarado na programação, portanto, poderá ser conectado a qualquer outro pino, no caso do exemplo acima, optamos por conecta-lo ao pino VP (GPIO36). No desenvolvimento com aplicativos como o Telegram será necessário conectar-se a internet, exigindo a aplicação de uma alimentação externa ao circuito elétrico. Como forma mais simplificada e segura, optamos por inserir uma fonte para protoboar, juntamente a um conversor AC/DC 9V, mas esta parte do circuito será opcional.
Em alguns dos exercícios a seguir iremos utilizar um LED RGB, portanto, encaixe o LED no Protoboard, conectando os resistores de 1KΩ entre os pinos menores do LED e as portas digitais D15, D2 e D4 do ESP32, e alimente o pino maior de acordo com o tipo, se for anodo conectar ao positivo, e catodo ao negativo.
Leitura de ID
Os objetos utilizados para a comunicação RFID serão conhecidos como Transponders, que são dispositivos de comunicação com o objetivo de transmitir, receber ou ampliar sinais de radiofrequência. Esse tipo de componente poderá ser classificado como passivo ou ativo, sendo que os ativos possuem uma fonte de alimentação própria, enquanto os passivos utilizam a energia do sinal do leitor para emitir respostas, e normalmente possuem algumas informações pré-definidas, no caso do chaveiro ou o cartão presente no Kit RFID, serão encontrados valores de ID e algumas informações referentes ao fabricante. O ID represeenta um número de identificação exclusivo atribuido a cada transpoder, e descobri-lo será de grande importância em projetos futuros, afinal, com o registro de um determinado componente torna-se possível distingui-lo dos demais, atribuindo funções e comandos específicos. Antes de mais nada, instale as bibliotecas MFRC522.h e SPI.h, e transfira a programação a seguir ao ESP32.
/* Projeto Curto Circuito - ESP32 & RFID: Leitura de ID */
/* ---- Bibliotecas ---- */
#include <SPI.h> /* https://github.com/PaulStoffregen/SPI */
#include <MFRC522.h> /*https://github.com/miguelbalboa/rfid */
/*---- Declara a Pinagem RST e SDA ---- */
#define SDA 5 /* Conectado ao pino D5 do ESP32 */
#define RST 36 /* Conectado ao pino VP do ESP32 */
/* ---- LED ---- */
int LED = 2; /* LED presente no próprio ESP32 */
MFRC522 mfrc522(SDA, RST);/* Cria uma instância MFRC522. */
void setup()
{
Serial.begin(9600); /* Inicia a comunicação serial com o PC */
SPI.begin(); /* Inicia SPI */
mfrc522.PCD_Init(); /* Inicia MFRC522 */
Serial.println("Encoste o cartao ou chaveiro no leitor");
Serial.println();
pinMode(LED, OUTPUT);
}
void loop()
{
if ( ! mfrc522.PICC_IsNewCardPresent())
{ /* Procura por novos cartões */
return;
}
if ( ! mfrc522.PICC_ReadCardSerial())
{ /* Reenicia a leitura */
return;
}
Serial.print("ID do objeto:"); /* Mostra o valor de ID */
String conteudo = "";
byte letra;
/* Rotina para despejar a matriz de bytes com os valores hexadecimais para Serial. */
for (byte i = 0; i < mfrc522.uid.size; i++)
{
Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
Serial.print(mfrc522.uid.uidByte[i], HEX);
conteudo.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "));
conteudo.concat(String(mfrc522.uid.uidByte[i], HEX));
}
Serial.println();
digitalWrite (LED, HIGH);
conteudo.toUpperCase(); /* Converte a String em Letras maiúsculas */
delay(100);
digitalWrite (LED, LOW);
}
Após transferir a programação, abra o monitor serial e encoste o chaveiro ou cartão próximo ao leitor RFID, em seguida, observe que o valor impresso será similar ao exibido na imagem abaixo.
A leitura e armazenamento de informações será constituído por valores em Hexadecimal, que se trata de um sistema numérico composto por uma combinação de caracteres de 0-9 e A-F. No exemplo de leitura apresentado acima, o valor de identificação exclusiva do objeto é : E7 4F 7D 89.
A biblioteca MFRC522.h será inserida com a finalidade de simplicar o uso do Leitor RFID, atuando em conjunto com o SPI.h, que, como o próprio nome sugere, irá inserir o protocolo de comunicação SPI. A função MFRC522 mfrc522(SDA, RST) cria um objeto com o nome mfrc522, que irá se comunicar com base nos pinos delarados em SDA e RST, e mfrc522.PCD_Init() inicia o funcionamento do Leitor.
Os comandos mfrc522.PICC_IsNewCardPresent() e mfrc522.PICC_ReadCardSerial() irão construir um loop de leitura contínuo, buscando sempre por uma nova TAG, enquanto a rotina for (byte i = 0; i < mfrc522.uid.size; i++) será responsável por imprimir os valores Hexadecimais no Monitor Serial.
Leitura e Armazenamento de Informações
O desafio princiapal para quem utiliza tecnologias RFID, será o armazenamento personalizado de informações em transpoders, registrando dados importantes como nomes, saldos e números de indentificação. O registro de anotações pessoais irá exigir um cartão ou chaveiro programável, afinal, nem todos os modelos terão este tipo de opção, na verdade, é até muito comum encontrar alguns que servirão apenas para a leitura. No caso do kit RFID fornecido por nós, ambos os componentes permitirão o registro de informações, com uma memória de 1KB EEPROM (768 bytes livre), e até 100.000 ciclos de durabilidade de escrita.
Na programação a serguir iremos desenvolver um teste simples através do monitor serial do Arduino IDE, gravando duas variáveis com um nome e RG fictícios no cartão RFID, e em seguida realizando uma leitura das informações armazenadas no mesmo. O circuito elétrico será similar ao utilizado nos exemplos anteriores.
/* Projeto Curto Circuito – ESP32 & RFID: Leitura e Armazenamento */
/* ------ Bibliotecas -------- */
#include <SPI.h>
#include <MFRC522.h>
/*-------- SPI configuração do pinos do Leitor----------- */
#define SDA 5 /* Conectado ao pino D5 do ESP32 */
#define RST 36 /* Conectado ao pino VP do ESP32 */
MFRC522 mfrc522(SDA, RST);
/*-------- LED RGB----------- */
int RED = 15;
int BLUE = 2;
int GREEN = 4;
void setup()
{
Serial.begin(115200);
pinMode(RED, OUTPUT); /* RED D15 do ESP32 */
pinMode(GREEN, OUTPUT); /* GREEN D4 do ESP32 */
pinMode(BLUE, OUTPUT); /* BLUE D2 do ESP32 */
SPI.begin(); /* Inicia o protocolo SPI */
mfrc522.PCD_Init(); /* Inicia o Leitor */
Serial.println("Aproxime o cartão/chaveiro e Digite: 1 - Leitura ou 2 - Armazenamento");
}
void loop()
{
digitalWrite(RED, LOW); /* Desliga LED Red */
digitalWrite(GREEN, LOW); /* Desliga LED Green */
digitalWrite(BLUE, HIGH); /* Liga LED Blue */
/* Armazena os caracteres escritos no Monitor Serial */
char choice = Serial.read();
if (choice == '1')
{ /* Se receber 1 */
Serial.println("Opção 1: Leitura de informações");
leitor(); /* Função Leitor */
}
else if (choice == '2')
{ /* Se receber 2 */
Serial.println("Opção 2: Armazenamento de informações");
escritor(); /* Função Gravador */
}
}
void leitor()
{
digitalWrite(BLUE, LOW); /* Desliga LED Blue*/
digitalWrite(GREEN, HIGH); /* Liga LED Green*/
/* Prepara chave de segurança no formato FFFFFFFFFFFFh */
MFRC522::MIFARE_Key key;
for (byte i = 0; i < 6; i++) key.keyByte[i] = 0xFF;
/* Procura por novos cartões*/
if ( ! mfrc522.PICC_IsNewCardPresent())
{
return;
}
/* Reenicia a leitura */
if ( ! mfrc522.PICC_ReadCardSerial())
{
return;
}
/*Variável para controlar os blocos de memórias */
byte block;
/*Variável para acessar as linhas */
byte len;
/*Verifica o status de leitura */
MFRC522::StatusCode status;
/* Quando encontrar alguma informação escreve no monitor serial */
Serial.println(F("----Informações Encontradas----"));
mfrc522.PICC_DumpDetailsToSerial(&(mfrc522.uid));
/*---Variável 1: Nome --- */
byte buffer1[18];
/* Direciona a leitura ao bloco 4 */
block = 4;
len = 18;
Serial.print(F("Nome: "));
/* Coleta as informações armazenadas no bloco 4 */
status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, 4, &key, &(mfrc522.uid));
status = mfrc522.MIFARE_Read(block, buffer1, &len);
/* Escreve as informações no monitor serial */
for (uint8_t i = 0; i < 16; i++)
{
if (buffer1[i] != 32)
{
Serial.write(buffer1[i]);
}
}
Serial.print(" ");
/*---Variável 2: RG --- */
byte buffer2[18];
/* Direciona a leitura ao bloco 1 */
block = 1;
/* Coleta as informações armazenadas no bloco 1 */
status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, 1, &key, &(mfrc522.uid)); /* line 834 */
status = mfrc522.MIFARE_Read(block, buffer2, &len);
Serial.print(F("RG: "));
/* Escreve as informações no monitor serial */
for (uint8_t i = 0; i < 16; i++) {
Serial.write(buffer2[i] );
}
Serial.println(F("\n----Fim----\n"));
delay(1000);
/* Se tiver finalizado a leitura */
mfrc522.PICC_HaltA();
mfrc522.PCD_StopCrypto1();
setup(); /* Retorna ao void Setup */
}
void escritor()
{
digitalWrite(BLUE, LOW); /* Desliga LED Blue */
digitalWrite(RED, HIGH); /*Liga LED Red */
/* Prepara chave de segurança no formato FFFFFFFFFFFFh */
MFRC522::MIFARE_Key key;
for (byte i = 0; i < 6; i++) key.keyByte[i] = 0xFF;
/* Procura por novos cartões*/
if ( ! mfrc522.PICC_IsNewCardPresent())
{
return;
}
/* Reenicia a leitura */
if ( ! mfrc522.PICC_ReadCardSerial())
{
return;
}
Serial.print(F("ID:")); /* Indica o valor de ID (UID) */
for (byte i = 0; i < mfrc522.uid.size; i++) {
Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
Serial.print(mfrc522.uid.uidByte[i], HEX);
}
Serial.print(F(" Tipo: ")); /* Tipo */
MFRC522::PICC_Type piccType = mfrc522.PICC_GetType(mfrc522.uid.sak);
Serial.println(mfrc522.PICC_GetTypeName(piccType));
byte buffer[34];
byte block;
MFRC522::StatusCode status;
byte len;
/* Aguarda até 20 segundo pelas informações */
Serial.setTimeout(20000L) ;
/* Variável 1: RG, finalize o Valor desejado com */
Serial.println(F("Escreva o RG, finalizando com #"));
len = Serial.readBytesUntil('#', (char *) buffer, 30) ; /* Le o nome para a serial */
for (byte i = len; i < 30; i++) buffer[i] = ' ';
/* Direciona as informações ao bloco 1 */
block = 1;
status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, block, &key, &(mfrc522.uid));
/* Escreve no bloco 1 */
status = mfrc522.MIFARE_Write(block, buffer, 16);
Serial.println(F("Valores armazenados no bloco 1"));
/* Variável 2: Nome, finalize o nome desejado com #; */
Serial.println(F("Escreva o nome, finalizando com #"));
len = Serial.readBytesUntil('#', (char *) buffer, 20) ;
for (byte i = len; i < 20; i++) buffer[i] = ' ';
/* Direciona as informações ao bloco 4 */
block = 4;
status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, block, &key, &(mfrc522.uid));
/* Escreve no bloco 4 */
status = mfrc522.MIFARE_Write(block, buffer, 16);
Serial.println(F("Valores armazenados no bloco 4"));
Serial.println(F(" "));
Serial.println(F("Informações Armazenadas com Sucesso."));
Serial.println(" ");
/* Ao finalizar */
mfrc522.PICC_HaltA();
mfrc522.PCD_StopCrypto1();
setup();/* Retorna ao void Setup */
}
Como foi dito anteriormente, os dispositivos Mifare presente no kit são EEPROM 1KB, e, segundo o datasheet do fabricante, a memória será organizada em 16 setores (de 0 á 15), e 4 blocos (de 0 á 3) composto por 16 Bytes cada. O bloco 0 do setor 0 será protegido contra gravações, pois este contem informações referentes ao fabricante, assim como o número de série exclusivo do componente (UID).
Para simplificar a programação construimos a variável byte block , cuja função será direcionar a leitura e o armazenamento de informação a alguns blocos de memória específicos. Abra o monitor serial, aproxime o cartão ou chaveiro no leitor RFID, e envie o caractere 1.
Ao enviar o valor "1", será iniciada a leitura dos dados armazenados no dispositivo, direcionando-a diretamente aos blocos de memória 1 e 4. No caso da imagem a seguir, o cartão utilizado não contém quaisquer informações armazenadas nos blocos específicos, exibindo apenas o número de série (UID) e as variáveis "nome" e "RG" vazias.
Envie o número "2" para habilitar o modo de armazenamento do programa. A função MFRC522::PICC_Type piccType = mfrc522.PICC_GetType(mfrc522.uid.sak), será responsável por coletar as informações referente ao fabricante, Serial.println(mfrc522.PICC_GetTypeName(piccType)) irá imprimir tal valor no monitor serial, enquanto a rotina for (byte i = 0; i < mfrc522.uid.size; i++) será responsável por indicar o ID exclusivo do dispositivo em Hexadecimais.
O comando status = mfrc522.PCD_Authenticate (MFRC522::PICC_CMD_MF_AUTH_KEY_A, block, &key, &(mfrc522.uid)) irá direcionar as informações a seus devidos blocos, enquanto status = mfrc522.MIFARE_Write(block, buffer, 16) terá o papel de grava-los. Antes de enviar os valores desejados, finalize-os com "#" como mostra o exemplo a seguir.
Após preencher as variáveis, realize outra leitura para verificar se os valores escritos foram salvos corretamente.
Serial.setTimeout(20000L), descrita na programação, terá a função de limitar a espera das informações a serem armazenadas, aguardando apenas 20 segundos. Se desejar apagar alguma informação, por exemplo, basta aguardar o tempo limite, deixando de preencher as variáveis RG, NOME ou ambas.
Controle de Acesso via Telegram
A aplicação mais comum a este tipo de componente, será localizada em sistemas de segurança, controlando o horário de transição em portarias e empresas por meio do registro de cartões/Tags RFID. Com base nisso, iremos explorar o desenvolvimento de um sistema de monitoramento de acesso, visualizando o horário de entrada e saída de um determinado indivíduo através do Telegram, que trata-se de um aplicativo para troca de mensagens instantâneas baseado na nuvem.
Diferente te outras ferramentas como Whatsapp, Mensseger, o Telegram facilita a construção de sistemas como Internet of Things, possibilitando um controle para componentes através da troca de mensagens entre plataformas mobile como smartphones ou tablets, e microcontroladores como ESP32, NodeMCU, etc. E, de forma simples, esse aplicativo disponibiliza a seus usuários uma inteligência artificial (IA) capaz de auxilia-lo na construção de seu próprio robô virtual (Bot), que, no caso do projeto proposto, servirá no controle de acesso, visualizando o horário de entrada/saída de cada usuário registrado. Para criar seu próprio chatBot, abra a tela inicial do aplciativo e pesquise por : @BotFather.
O comando irá direciona-lo a um chat particular com o "Father", o robô virtual do Telegram, que apresentará diversas ferramentas e funções exclusivas. Clique em "Iniciar", inicie a conversa com o comando "/newbot", solicitando a construção de um novo chatBot. Como resposta, o Father irá lhe solicitar um nome para o novo Bot, e um usuário finalizado com a palavra "bot", este será utilizado como forma de localiza-lo na barra de pesquisa, que, no caso da imagem a seguir, seria : @Curtocircuitobot.
Na confirmação da construção do novo auxiliar virtual, será enviado um Token de acesso, uma chave de API composta por diversas letras e números, com a função de estabelecer conexão entre seu chat particular no Telegram e o ESP32.
Procure por seu novo chatBot na barra de pesquisa, por exemplo: @Curtocircuitobot.
Na programação a seguir, iremos utilizar o protocolo de comunicação NTP, abordado em outras postagens, como meio de indicar o horário preciso do acesso no leitor RFID. A transmissão da hora correta, assim como a troca de mensagens via Telegram irá exigir que o ESP32 esteja conectado a uma rede Wi-Fi, portanto, antes de transferir o programa substitua os valores de "ssid" e "password" por um usuário e senha de uma rede conhecida, adicione o valor de token fornecido pelo "Father" na variável BOTtoken, e adicione as bibliocas UniversalTelegramBot e NTPClient.
/* Projeto Curto Circuito – ESP32 & RFID: Controle via Telegram */
/* ------ Bibliotecas -------- */
#include <WiFi.h>
#include <NTPClient.h> /* https://github.com/arduino-libraries/NTPClient */
#include <SPI.h>
#include <MFRC522.h>
#include <WiFiClientSecure.h>
#include <UniversalTelegramBot.h> /* https://github.com/witnessmenow/Universal-Arduino-Telegram-Bot */
/* -------- SPI configuração do pinos do Leitor----------- */
#define SDA 5 /* Conectado ao pino D5 do ESP32 */
#define RST 36 /* Conectado ao pino VP do ESP32 */
MFRC522 mfrc522(SDA, RST);
/*-------- Configurações de relógio on-line----------- */
WiFiUDP udp;
NTPClient ntp(udp, "a.st1.ntp.br", -3 * 3600, 60000); /*Cria um objeto "NTP" com as configurações.utilizada no Brasil */
String hora; /* Variável que armazena */
/* -------- Configurações de Wi-Fi----------- */
const char* ssid = "NOME_DA_REDE;
const char* password = "SENHA";
/* -------- Token de acesso Telegram----------- */
#define BOTtoken " Token:Insira a sequência completa de números e letras" /* Token do telegram */
/* -------- LED----------- */
#define BLUE 2
#define RED 15
/*------- Variáveis lógicas ---------- */
int i = 0;
String sit ;
unsigned long temp;
/* ------- Registro de Usuários ---------- */
String cartao = "E7 4F 7D 89"; /* Insira um valor ID conhecido */
String chaveiro = "00 0E B8 73"; /*Insira um valor de ID conhecido */
int id = 0;
int id2 = 0;
WiFiClientSecure client;
UniversalTelegramBot bot(BOTtoken, client);
void setupWifi()
{ /* BConectando ao Wi-Fi */
Serial.begin(115200); /* Transmissão em 115200 */
delay(2000); /* Aguarda 2 segundos. */
ntp.begin(); /* Inicia o protocolo NTP */
/* Indica o Wi-Fi ao qual se conectou */
Serial.print("Conectando ao Wifi: ");
Serial.println(ssid);
/* Tenta se Conectar aos valores armazenados em ssid e password */
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED)
{ /* Enquanto estiver desconectado */
Serial.print(".");
delay(500);
}
ntp.forceUpdate(); /* Atualização do horário */
Serial.println("");
Serial.println("Wi-Fi conectado");
Serial.print("Endereço de IP: ");
Serial.println(WiFi.localIP());
}
void setup()
{
Serial.begin(115200); /* Transmissão em 115200 */
SPI.begin(); /* Inicia o protocolo SPI */
mfrc522.PCD_Init(); /* Inicia o Leitor */
pinMode(RED, OUTPUT); /* LED Vermelho */
pinMode(BLUE, OUTPUT); /* LED Verde */
setupWifi();
}
void loop()
{
if (millis() > 1500)
{ /* Cria um intervalo de tempo entre as leituras */
rfid();
}
/* Armazena o horário atual. */
hora = ntp.getFormattedTime();
}
void rfid()
{
/* ---------- Armazenando informações ------- */
String chat_id = String(bot.messages[i].chat_id);/* Armazena o ID */
String text = bot.messages[i].text; /*Armazena o texto */
int NewMessages = bot.getUpdates(bot.last_message_received + 1); /* Atualiza as mensagens */
if ( ! mfrc522.PICC_IsNewCardPresent())
{ /* Procura por novos cartões */
return;
}
if ( ! mfrc522.PICC_ReadCardSerial())
{ /* Reenicia a leitura */
return;
}
MFRC522::MIFARE_Key key;
MFRC522::StatusCode status;
for (byte i = 0; i < 6; i++) key.keyByte[i] = 0xFF;
/*---------- Leitura do ID ------- */
Serial.print("ID do objeto:"); /* Mostra o valor de ID */
String conteudo = "";
/* Rotina para despejar a matriz de bytes com os valores hexadecimais na Serial. */
for (byte i = 0; i < mfrc522.uid.size; i++)
{
Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
Serial.print(mfrc522.uid.uidByte[i], HEX);
conteudo.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "));
conteudo.concat(String(mfrc522.uid.uidByte[i], HEX));
}
Serial.println();
conteudo.toUpperCase(); /* Converte a String em Letras maiúsculas */
/*---------- Leitura do Nome ------- */
String conteudo2 = "";
/* Variável para controlar os blocos de memórias */
byte block;
/* Variável para acessar as linhas */
byte len;
byte buffer2[18];
/* Direciona a leitura ao bloco 1 */
block = 4;
len = 18;
status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, 4, &key, &(mfrc522.uid));
status = mfrc522.MIFARE_Read(block, buffer2, &len);
for (uint8_t i = 0; i < 16; i++) {
if (buffer2[i] != 32)
{
Serial.write(buffer2[i]);
conteudo2.concat(char(buffer2[i]));
}
}
Serial.println();
conteudo2.toUpperCase(); /* Converte a String em Letras maiúscula s */
/* ---------- Leitura do RG ------- */
String conteudo3 = "";
byte buffer1[18];
/* Direciona a leitura ao bloco 1 */
block = 1;
status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, 1, &key, &(mfrc522.uid));
status = mfrc522.MIFARE_Read(block, buffer1, &len);
for (uint8_t i = 0; i < 16; i++) {
if (buffer1[i] != 32)
{
Serial.write(buffer1[i]);
conteudo3.concat(char(buffer1[i]));
}
}
Serial.println();
conteudo3.toUpperCase(); /* Converte a String em Letras maiúsculas */
if (conteudo.substring(1) == cartao || conteudo.substring(1) == chaveiro)
{
digitalWrite(RED, 1);
if (conteudo.substring(1) == cartao)
{
id = !id;
if (id == 1)
{
sit = "Entrada";
}
else
{
sit = "Saída";
}
}
if (conteudo.substring(1) == chaveiro)
{
id2 = !id2;
if (id2 == 1)
{
sit = "Entrada";
}
else
{
sit = "Saída";
}
}
}
else
{
Serial.println("Cartão desconhecido");
digitalWrite(BLUE, 1);
}
/*---------- Transmitindo ao Telegram------- */
Serial.println("Cartão on"); /* Cartão ON */
/* Envia ao Telegram o horário, nome e status Entrando */
String msg = "\nSituação: " + sit;
msg += "\n Nome: " + conteudo2;
msg += "\n Horário:" + hora; /* Horário */
msg += "\n ID:" + conteudo;
msg += "\n RG:" + conteudo3;
bot.sendMessage(chat_id, msg, "");
delay(10);
digitalWrite(RED, 0);
digitalWrite(BLUE, 0);
mfrc522.PICC_HaltA();
mfrc522.PCD_StopCrypto1();
loop();
}
Todas as informações armazenadas na String msg serão enviadas ao Telegram através do comando bot.sendMessage(chat_id, msg, ""), porém, antes de visualizar qualquer mensagem, será necessário iniciar a comunicação entre o ESP32 e o aplicativo, portanto, abra seu chatbot exclusivo e envie o comando "/start", em seguida, aproxime um cartão ou chaveiro cujo valor esteja registrado nas variáveis String cartao e String chaveiro, o LED D2 irá acender indicando a leitura de um dispositivo conhecido, enquanto D15 será voltado a leituras de Tags desconhecidas.
A hora correta será coletada através do protocolo NTP, que tem como função coletar um determinado horário com base em servidores na internet. A configuração de um padrão regional irá depender das informações adicionadas na variável NTPClient, que será utilizada como ponte na comunicação entre um servidor externo e o ESP32, ajustando o relógio de acordo com o valor fornecido.
NTPClient ntp(udp, "a.st1.ntp.br", -3 * 3600, 60000);
NTPClient: Função que configura o fuso horário
ntp: Armazena os valores configurados;
udp:Estabelece uma comunicação entre o ESP32 e um cliente externo, no caso desse exemplo, o NTP.
a.st1.ntp.br: Endereço on-line utilizado na coleta da hora correta no servidor.
-3 : Fuso brasileiro segundo o Meridiano de Greenwich.
3600 : Multiplica pelo fuso formatando a leitura em segundos.
60000: Intervalo entre cada atualização (1 minuto)
As funções ntp.forceUpdate() e ntp.begin() serão responsáveis por manter a leitura do horário ativa e atualizada, enquanto o ntp.getFormattedTime() ajusta o formato do horário em hora/minuto/segundo (00:00:00). Para conhecer os servidores brasileiros disponíveis, ou ajustar a leitura para o horário de verão, acesse o site oficial da NTP.
Ao abrir o monitor serial serão exibidas duas informações iniciais, o nome da rede ao qual o ESP32 tentará conectar-se através do comando Serial.println(ssid), e ao conectar irá imprimir o endereço de IP através de Serial.println(WiFi.localIP()). Após estabelecer conexão, será exibido o valor de ID de qualquer transponders que se aproxime do leitor RFID, com um intervalo de 1,5 segundos entre cada leitura, determinado na função if (millis() > 1500).
A função conteudo.substring(1) será a responsável por registrar o acesso de transpoders conhecidos, de acordo com os valores de ID registrados em String cartao e String chaveiro, para ajustar a um valor de Tag específico de sua preferência, basta substituir o valor registrado entre aspas nas variáveis String cartao = "E7 4F 7D 89" e String chaveiro = "00 0E B8 73". Quaisquer outros dispositivos que não possuam o valor declarado na programação, serão exibidos no monitor serial como "desconhecido", exibindo as informações dos blocos de memória 1 e 4.
O comando id = !id, será responsável por avaliar o status de acesso de usuários conhecidos, invertendo o valor armazenado a cada acesso autorizado, sendo eles 1 na condição de entrada, e 0 na saída. Nas funções status = mfrc522.PCD_Authenticate (MFRC522::PICC_CMD_MF_AUTH_KEY_A, 4, &key, &(mfrc522.uid)) e status = mfrc522.MIFARE_Read(block, buffer2, &len), os valores armazenados em block, buffer e len, serão utilizados para direcionar a leitura a determinados setores de memória do transpoder, imprimindo as informações coletadas através de Serial.write(buffer2[i]), no monitor serial, e conteudo2.concat(char(buffer2[i])), no Telegram.
Considerações Finais
Tecnologias RFID são aplicadas a sistemas de segurança desde os anos 60, servindo como um importante aliado em metodologias de identificação automática, através da transmissão de dados por sinais de radiofrequência. O registro de informações em etiquetas, cartãos, entre outros dispositivos, simplifica a identificação de pessoas ou objetos, agilizando processos de controle e segurança. Integrar esse tipo de tecnologia a plataformas como o Telegram irá simplificar a construção de muitos projetos, visto que o aplicativo em questão, por exemplo, possui um sistema de comunicação integrado a nuvem, possibilitando utiliza-lo como um banco de dados, e realizar a troca mensagens entre o softwarer e o ESP32 de forma praticamente instantânea.
Didática e nível de detalhes estavam incríveis
Estou com diversas linhas de erro que seguem o seguinte modelo:
error: cannot convert 'const char*' to 'const __FlashStringHelper*' in return
#define F(string_literal) (string_literal)
Parece ser referente a biblioteca do leitor RFID, porém já fiz várias mudanças nas versões da mesma, tanto atualizando quanto pegando versão mais antiga.
Alguém saberia me ajudar?
Desde ja obrigado
Este erro está relacionado á biblioteca do esp32. Na versão do Core 2.0.8 presente na biblioteca do ESP32, esse erro ocorre pois ouve mudança na forma em que as funções são chamadas no código.
Faça um downgrade da versão do Core de 2.0.8 para a versão 2.0.7, com isso, esse erro deixará de aparecer.
Caso o seu TCC for de uma faculdade, você não pode citar o conteúdo de blogs para seu trabalho acadêmico. Você precisaria encontrar conteúdos mais técnicos.
O chat funciona com um Token específico e com isso não há possibilidade de colocar mais de um Token de uma vez.
ets Jul 29 2019 12:21:46
rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:1216
ho 0 tail 12 room 4
load:0x40078000,len:10944
load:0x40080400,len:6388
entry 0x400806b4
E não acontece nada, o que poderia ser?
Att.
Sugiro que você atualize a sua IDE do Arduino para uma versão mais recente, além disso, certifique-se de selecionar a placa correta na sua IDE. Espero que isso resolva o seu problema! :)
Abraços