Introdução
Olá tudo bem, hoje faremos um sistema de cadastramento utilizando ESP8266 um leitor RFID . Iremos aprender como conectar e utilizar o leitor RFID MFRC522 Mifare ao ESP8266 e a criar um pequeno webserver que servirá de interface para o usuário que irá cadastrar novas tags RFID. Você poderá utilizar para controle de acesso de algum cômodo da sua casa. por exemplo.
Visão Geral do Projeto
Nosso sistema será capaz de realizar algumas tarefas básicas:
- Cadastrar um usuário a partir de uma tag RFID – O usuário deve aproximar o cartão ou tag do leitor, informar um dado adicional como nome ou CPF e se cadastrar como novo usuário. Esse cadastro ficará salvo localmente na flash do ESP8266;
- Excluir um usuário – O sistema permitirá a exclusão de um usuário do registro local;
- Reconhecer tags cadastradas – O sistema deverá fazer a leitura e identificação de tags cadastradas. Ao reconhecer uma tag um led verde será acionado, e um vermelho em casos de tags não registradas.
Além disso não será possível cadastrar a mesma tag duas vezes. O campo de informações sobre o usuário também não poderá ser duplicado. Todo o processo de cadastro será feito através utilizando uma interface web.
Figura 1 – Interface do Sistema de Cadastro.
Conhecendo os Componentes
Leitor RFID MFRC522 Mifare
O leitor MFRC522 Mifare é um leitor de tags RFID de 13,56MHz com interface SPI para troca de dados com microcontroladores. RFID (acrônimo para Radio-Frequency IDentification) é uma tecnologia de identificação por radiofrequência, geralmente de curto alcance muito utilizada em controle de acesso, sistemas de bilhetes de transporte público, identificação de produtos, etc.
Figura 2 – Sistema de RFID no transporte público.
Geralmente composta por dois elementos, uma tag ou etiqueta RFID que possui um id único e um leitor RFID que faz a leitura e, dependendo do casos, pode fazer escrita de alguma informação na tag. O leitor MFRC522 Mifare também pode fazer escrita em tags, mas não será o foco neste projeto. Abaixo algumas características desse leitor.
- Tipos de cartões suportados: Mifare1 S50, S70 Mifare1, Mifare UltraLight, Mifare Pro, Mifare Desfire;
- Frequência de operação: 13,56MHz;
- Corrente de trabalho: 13-26mA / DC 3.3V;
- Taxa de transferência: 10 Mbit/s;
- Interface: SPI.
Para utilizarmos o leitor MFRC522 Mifare no nosso precisamos adicionar a biblioteca MFRC522.h. Ela pode ser encontrada no gerenciador de bibliotecas da Arduino IDE.
Figura 3 – Biblioteca MFRC522.h.
Sistema de arquivos SPIFFS
Um recurso presente no ESP8266 que será bastante útil no nosso projeto será o Sistema de Arquivos Flash de Interface Periférica Serial ou SPIFFS, que é um sistema de arquivos que permite escrita e leitura de dados na flash de forma simplificada. Ele pode ser usado para armazenar arquivos de configuração, arquivos com leituras colhidas periodicamente, páginas html para serem carregadas posteriormente.
O tamanho reservado para o sistema de arquivos vai depender do chip de memória flash on-board do ESP8266 em questão.
Figura 4 – Tabela de placas ESP8266 com respectivos espaços disponíveis para SPIFFS.
Antes de prosseguir verifique se você já possui as placas ESP8266 configuradas na Arduino IDE. Consulte este post caso ainda não tenha feito a instalação. Usaremos neste post a biblioteca FS.h para trabalhar com o SPIFFS. Ela é instalada automaticamente no momento em que as placas ESP8266 são adicionadas à Arduino IDE.
Instalando o Arduino ESP8266 Filesystem Uploader
Neste projeto precisamos várias páginas html. Como já foi dito anteriormente podemos usar o SPIFFS para armazenar nossas páginas HTML. Podemos gravar esses arquivos diretamente na memória flash utilizando o plugin ESP8266 Filesystem Uploader.
Para obtê-lo entre na página de releases e clique no arquivo ESP8266FS-0.5.0.zip para fazer o download.
Descompacte a pasta .zip baixada para a pasta Ferramentas . Você deve ter uma estrutura de pastas semelhante:
<home_dir>/Arduino-<version>/tools/ESP8266FS/tool/esp8266fs.jar
Após isso abra a Arduino IDE e verifique se a ferramenta está disponível no menu Ferramentas.
Figura 5 – ESP8266 Filesystem Uploader instalado na Arduino IDE.
Mãos à Obra – Desenvolvimento do projeto
Componentes necessários
- 1x ESP8266 NodeMcu;
- 1x LED Verde;
- 1x LED Vermelho;
- 1x Leitor RFID MFRC522 Mifare;
- 2x Resistor de 390R;
- 1x Protoboard;
- Fios Jumper.
Bibliotecas necessárias
Além da biblioteca para o leitor MFRC522, serão necessárias as bibliotecas ESPAsyncWebServer e ESPAsyncTCP que nos ajudarão a implementar o servidor do projeto.
Com a Arduino IDE aberta, selecione o menu Sketch -> Incluir Bibliotecas -> Adicionar Biblioteca .ZIP.
Figura 6 – Instalando bibliotecas a partit de arquivos .zip.
Navegue até a pasta da biblioteca, selecione o arquivo .zip e em seguida clique em Abrir.Se tudo ocorrer bem a Arduino IDE mostrará uma mensagem de êxito.
Figura 7 – Mensagem de confirmação .
Montando o Projeto – Fritzing
O leitor RFID MFRC522 Mifare possui 8 pinos que serão ligados na seguinte sequência ao ESP8266.
- Pino SDA – ligado na porta D2 do ESP8266 NodeMcu;
- Pino SCK – ligado na porta D5 do ESP8266 NodeMcu;
- Pino MOSI – ligado na porta D7 do ESP8266 NodeMcu;
- Pino MISO – ligado na porta D6 do ESP8266 NodeMcu;
- Pino NC – Não conectado;
- Pino GND – ligado no pino GND do ESP8266 NodeMcu;
- Pino RST -ligado na porta D1 do ESP8266 NodeMcu;
- Pino 3.3 – ligado ao pino 3.3 V do ESP8266 NodeMcu.
A montagem deste projeto, pode ser feita seguindo a ordem dos fios mostrada na imagem abaixo.
Figura 8 – Montagem do circuito.
Programando
Baixe o projeto nesse link com todos os arquivos necessários para esse post. Você encontrará os arquivos que serão gravados via SPIFFS numa pasta com nome “data” dentro da pasta do seu sketch arduino. Em seguida você pode fazer o upload desses arquivos através da ferramenta ESP8266 Filesystem Uploader, no menu ferramentas da Arduino IDE. Atenção! O sketch é compilado e gravado normalmente como qualquer outro sketch, somente os arquivos da pasta “data” serão gravados via ESP8266 Filesystem Uploader.
Segue abaixo o sketch do nosso sistema de cadastro.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 | #include <ESP8266WiFi.h> #include <ESPAsyncTCP.h> #include <ESPAsyncWebServer.h> #include <FS.h> #include <SPI.h> #include <MFRC522.h> #include <vector> #define SS_PIN 4 //D2 #define RST_PIN 5 //D1 #define FILENAME "/Cadastro.txt" #define LED_RED 0 //D3 #define LED_GREEN 2 //D4 using namespace std; const char* ssid = "****"; const char* password = "****"; String info_data; //Informação sobre o usuario.Ex nome, cpf, etc. String id_data; //Id para o usuario. int index_user_for_removal = -1; String rfid_card = ""; //UID RFID obtido pelo Leitor String sucess_msg = ""; String failure_msg = ""; // Cria um objeto MFRC522. MFRC522 mfrc522(SS_PIN, RST_PIN); // Cria um objeto AsyncWebServer que usará a porta 80 AsyncWebServer server(80); void notFound(AsyncWebServerRequest *request) { request->send(404, "text/plain", "Not found"); } //Inicializa o sistema de arquivos. bool initFS() { if (!SPIFFS.begin()) { Serial.println("Erro ao abrir o sistema de arquivos"); return false; } Serial.println("Sistema de arquivos carregado com sucesso!"); return true; } //Lista todos os arquivos salvos na flash. void listAllFiles() { String str = ""; Dir dir = SPIFFS.openDir("/"); while (dir.next()) { str += dir.fileName(); str += " / "; str += dir.fileSize(); str += "\r\n"; } Serial.print(str); } //Faça a leitura de um arquivo e retorne um vetor com todas as linhas. vector <String> readFile(String path) { vector <String> file_lines; String content; File myFile = SPIFFS.open(path.c_str(), "r"); if (!myFile) { myFile.close(); return {}; } Serial.println("###################### - FILE- ############################"); while (myFile.available()) { content = myFile.readStringUntil('\n'); file_lines.push_back(content); Serial.println(content); } Serial.println("###########################################################"); myFile.close(); return file_lines; } //Faça a busca de um usuario pelo ID e pela INFO. int findUser(vector <String> users_data, String id, String info) { String newID = "<td>" + id + "</td>"; String newinfo = "<td>" + info + "</td>"; for (int i = 0; i < users_data.size(); i++) { if (users_data[i].indexOf(newID) > 0 || users_data[i].indexOf(newinfo) > 0) { return i; } } return -1; } //Adiciona um novo usuario ao sistema bool addNewUser(String id, String data) { File myFile = SPIFFS.open(FILENAME, "a+"); if (!myFile) { Serial.println("Erro ao abrir arquivo!"); myFile.close(); return false; } else { myFile.printf("<tr><td>%s</td><td>%s</td>\n", id.c_str(), data.c_str()); Serial.println("Arquivo gravado"); } myFile.close(); return true; } //Remove um usuario do sistema bool removeUser(int user_index) { vector <String> users_data = readFile(FILENAME); if (user_index == -1)//Caso usuário não exista retorne falso return false; File myFile = SPIFFS.open(FILENAME, "w"); if (!myFile) { Serial.println("Erro ao abrir arquivo!"); myFile.close(); return false; } else { for (int i = 0; i < users_data.size(); i++) { if (i != user_index) myFile.println(users_data[i]); } Serial.println("Usuário removido"); } myFile.close(); return true; } //Esta função substitui trechos de paginas html marcadas entre % String processor(const String& var) { String msg = ""; if (var == "TABLE") { msg = "<table><tr><td>RFID Code</td><td>User Info</td><td>Delete</td></tr>"; vector <String> lines = readFile(FILENAME); for (int i = 0; i < lines.size(); i++) { msg += lines[i]; msg += "<td><a href=\"get?remove=" + String(i + 1) + "\"><button>Excluir</button></a></td></tr>"; //Adiciona um botão com um link para o indice do usuário na tabela } msg += "</table>"; } else if (var == "SUCESS_MSG") msg = sucess_msg; else if (var == "FAILURE_MSG") msg = failure_msg; return msg; } void setup() { Serial.begin(115200); pinMode(LED_GREEN, OUTPUT); pinMode(LED_RED, OUTPUT); digitalWrite(LED_GREEN, LOW); digitalWrite(LED_RED, LOW); SPI.begin(); mfrc522.PCD_Init(); // Inicia MFRC522 // Inicialize o SPIFFS if (!initFS()) return; listAllFiles(); readFile(FILENAME); // Conectando ao Wi-Fi WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(1000); Serial.println("Conectando WiFi.."); } Serial.println(WiFi.localIP()); //Rotas. server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) { rfid_card = ""; request->send(SPIFFS, "/home.html", String(), false, processor); }); server.on("/home", HTTP_GET, [](AsyncWebServerRequest * request) { rfid_card = ""; request->send(SPIFFS, "/home.html", String(), false, processor); }); server.on("/sucess", HTTP_GET, [](AsyncWebServerRequest * request) { request->send(SPIFFS, "/sucess.html", String(), false, processor); }); server.on("/warning", HTTP_GET, [](AsyncWebServerRequest * request) { request->send(SPIFFS, "/warning.html"); }); server.on("/failure", HTTP_GET, [](AsyncWebServerRequest * request) { request->send(SPIFFS, "/failure.html"); }); server.on("/deleteuser", HTTP_GET, [](AsyncWebServerRequest * request) { if (removeUser(index_user_for_removal)) { sucess_msg = "Usuário excluido do registro."; request->send(SPIFFS, "/sucess.html", String(), false, processor); } else request->send(SPIFFS, "/failure.html", String(), false, processor); return; }); server.on("/stylesheet.css", HTTP_GET, [](AsyncWebServerRequest * request) { request->send(SPIFFS, "/stylesheet.css", "text/css"); }); server.on("/rfid", HTTP_GET, [](AsyncWebServerRequest * request) { request->send_P(200, "text/plain", rfid_card.c_str()); }); server.on("/get", HTTP_GET, [] (AsyncWebServerRequest * request) { vector <String> users_data = readFile(FILENAME); if (request->hasParam("info")) { info_data = request->getParam("info")->value(); info_data.toUpperCase(); Serial.printf("info: %s\n", info_data.c_str()); } if (request->hasParam("rfid")) { id_data = request->getParam("rfid")->value(); Serial.printf("ID: %s\n", id_data.c_str()); } if (request->hasParam("remove")) { String user_removed = request->getParam("remove")->value(); Serial.printf("Remover o usuário da posição : %s\n", user_removed.c_str()); index_user_for_removal = user_removed.toInt(); index_user_for_removal -= 1; request->send(SPIFFS, "/warning.html"); return; } if(id_data == "" || info_data == ""){ failure_msg = "Informações de usuário estão incompletas."; request->send(SPIFFS, "/failure.html", String(), false, processor); return; } int user_index = findUser(users_data, id_data, info_data); if (user_index < 0) { Serial.println("Cadastrando novo usuário"); addNewUser(id_data, info_data); sucess_msg = "Novo usuário cadastrado."; request->send(SPIFFS, "/sucess.html", String(), false, processor); } else { Serial.printf("Usuário numero %d ja existe no banco de dados\n", user_index); failure_msg = "Ja existe um usuário cadastrado."; request->send(SPIFFS, "/failure.html", String(), false, processor); } }); server.on("/logo.jpg", HTTP_GET, [](AsyncWebServerRequest *request){ request->send(SPIFFS, "/logo.jpg", "image/jpg"); }); server.onNotFound(notFound); // Inicia o serviço server.begin(); } void loop() { // Procure por novos cartões. if (!mfrc522.PICC_IsNewCardPresent()) { return; } //Faça a leitura do ID do cartão if (mfrc522.PICC_ReadCardSerial()) { Serial.print("UID da tag :"); String rfid_data = ""; for (uint8_t i = 0; i < mfrc522.uid.size; i++) { Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "); Serial.print(mfrc522.uid.uidByte[i], HEX); rfid_data.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ")); rfid_data.concat(String(mfrc522.uid.uidByte[i], HEX)); } Serial.println(); rfid_data.toUpperCase(); rfid_card = rfid_data; //Carregue o arquivo de cadastro vector <String> users_data = readFile(FILENAME); //Faça uma busca pelo id int user_index = findUser(users_data, rfid_data, ""); if (user_index < 0) { Serial.printf("Nenhum usuário encontrado\n"); digitalWrite(LED_RED, HIGH); } else { Serial.printf("Usuário %d encontrado\n", user_index); digitalWrite(LED_GREEN, HIGH); } delay(1000); digitalWrite(LED_GREEN, LOW); digitalWrite(LED_RED, LOW); Serial.println(); } } |
Entendendo o código
A seguir uma breve explanação sobre as partes do código.
Inclusão das bibliotecas
Aqui fazemos a inclusão das bibliotecas que utilizaremos. Destaque para a bibliotecas FS.h que responsável pelo acesso ao SPIFFS, ESPAsyncWebServer.h para criar nosso webserver e a MFRC522.h que fica responsável pela comunicação com o leitor RFID MFRC522 Mifare.
1 2 3 4 5 6 7 | #include <ESP8266WiFi.h> #include <ESPAsyncTCP.h> #include <ESPAsyncWebServer.h> #include <FS.h> #include <SPI.h> #include <MFRC522.h> #include <vector> |
Definição de constantes, variáveis e credenciais de rede
Altere as constantes ssid e password para as credenciais da sua rede Wi-Fi.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | #define SS_PIN 4 //D2 #define RST_PIN 5 //D1 #define FILENAME "/Cadastro.txt" #define LED_RED 0 //D3 #define LED_GREEN 2 //D4 using namespace std; const char* ssid = "****"; const char* password = "****"; String info_data; //Informação sobre o usuario.Ex nome, cpf, etc. String id_data; //Id para o usuario. int index_user_for_removal = -1; String rfid_card = ""; //Codigo RFID obtido pelo Leitor String sucess_msg = ""; String failure_msg = ""; |
Uma ressalva para ao trecho using namespace std é que uma diretiva que declara que o código a seguir terá funções e/ou objetos que pertencem ao namespace std. Neste exemplo a classe vector pertence a esse namespace, sem essa diretiva a forma de acessar acessar essa classe seria std::vector.
Instanciar objetos
Aqui instanciamos objetos para o webserver e para o leitor MFRC522.
1 2 3 4 5 | // Cria um objeto MFRC522. MFRC522 mfrc522(SS_PIN, RST_PIN); // Cria um objeto AsyncWebServer que usará a porta 80 AsyncWebServer server(80); |
Funções de manipulação de arquivos, cadastro.
Aqui encontramos as funções que responsáveis por adicionar, remover e buscar por usuários cadastrados no nosso sistema. Todas essas funções utilizam o SPIFFS para manter o cadastro salvo de forma persistente na memoria flash.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | //Inicializa o sistema de arquivos. bool initFS(){...} //Lista todos os arquivos salvos na flash. void listAllFiles(){...} //Faça a leitura de um arquivo e retorne um vetor com todas as linhas. vector <String> readFile(String path){...} //Faça a busca de um usuario pelo ID e pela INFO. int findUser(vector <String> users_data, String id, String info); //Adiciona um novo usuario ao sistema bool addNewUser(String id, String data){...} //Remove um usuario do sistema bool removeUser(int user_index){...} //Esta função substitui trechos de paginas html marcadas entre % String processor(const String& var){...} |
Também temos a função processor() que será importante adicionar conteúdo extra as paginas html.
Função Setup
Inicializamos a serial e os pinos conectados aos leds, as funções listAllFiles() e readFile() aqui são puramente para efeito de debug, listando todos os arquivos que existem na flash e o exibindo o conteúdo do nosso arquivo registro de usuários. O nome do arquivo é definido pela constante FILENAME.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | Serial.begin(115200); pinMode(LED_GREEN, OUTPUT); pinMode(LED_RED, OUTPUT); digitalWrite(LED_GREEN, LOW); digitalWrite(LED_RED, LOW); SPI.begin(); mfrc522.PCD_Init(); // Inicia MFRC522 // Inicialize o SPIFFS if (!initFS()) return; listAllFiles(); readFile(FILENAME); // Conectando ao Wi-Fi WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(1000); Serial.println("Conectando WiFi.."); } Serial.println(WiFi.localIP()); |
Rotas
Logo após teremos uma sequencia de definições de rotas com as respectivas paginas html que serão servidas como resposta.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) { rfid_card = ""; request->send(SPIFFS, "/home.html", String(), false, processor); }); server.on("/home", HTTP_GET, [](AsyncWebServerRequest * request) { rfid_card = ""; request->send(SPIFFS, "/home.html", String(), false, processor); }); server.on("/sucess", HTTP_GET, [](AsyncWebServerRequest * request) { request->send(SPIFFS, "/sucess.html", String(), false, processor); }); server.on("/warning", HTTP_GET, [](AsyncWebServerRequest * request) { request->send(SPIFFS, "/warning.html"); }); server.on("/failure", HTTP_GET, [](AsyncWebServerRequest * request) { request->send(SPIFFS, "/failure.html"); }); //continua ... |
Definimos uma rota utilizando o método server.on(). Nos métodos acima por exemplo temos que para a rota “/” e “/home” serviremos a mesma página home.html e ela deve ser encontrada utilizando SPIFFS. Definimos qual arquivo será enviado utilizando o método request->send(). Além de simplesmente carregar paginas também podemos realizar outras tarefas como adicionar, excluir usuários dentro do método server.on().
Vale destacar que em algumas chamadas dessa função utilizei uma função callback. Essa função callback, neste caso a função é processor(). Ela fará uma substituição de parte do código html da página antes de servi-la para o usuário. Isso é útil pois precisamos manter uma tabela de usuários cadastrados sempre visível e como essa informação é variável não podemos salva-la previamente memória flash.
Não só paginas html mas também outros tipos de arquivos salvos na flash devem ter rotas configuradas.
1 2 3 4 5 6 | server.on("/stylesheet.css", HTTP_GET, [](AsyncWebServerRequest * request) { request->send(SPIFFS, "/stylesheet.css", "text/css"); }); server.on("/logo.jpg", HTTP_GET, [](AsyncWebServerRequest *request){ request->send(SPIFFS, "/logo.jpg", "image/jpg"); }); |
Utilizei um arquivo css para estilizar nossa pagina, alem disso, adicionei também uma imagem de logo. Depois de definirmos todas as rotas podemos iniciar o serviço.
1 2 | // Inicia o serviço server.begin(); |
Função Loop
Na função Loop() aguardamos a leitura de tags RFID. O funcionamento é bem simples, quando um cartão cadastrado é detectado o led verde é acionado por 1 segundo, quando um cartão desconhecido é detectado o led vermelho é acionado pelo mesmo período.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | void loop() { // Procure por novos cartões. if (!mfrc522.PICC_IsNewCardPresent()) { return; } //Faça a leitura do ID do cartão if (mfrc522.PICC_ReadCardSerial()) { Serial.print("UID da tag :"); String rfid_data = ""; for (uint8_t i = 0; i < mfrc522.uid.size; i++) { Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "); Serial.print(mfrc522.uid.uidByte[i], HEX); rfid_data.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ")); rfid_data.concat(String(mfrc522.uid.uidByte[i], HEX)); } Serial.println(); rfid_data.toUpperCase(); rfid_card = rfid_data; //Carregue o arquivo de cadastro vector <String> users_data = readFile(FILENAME); //Faça uma busca pelo id int user_index = findUser(users_data, rfid_data, ""); if (user_index < 0) { Serial.printf("Nenhum usuário encontrado\n"); digitalWrite(LED_RED, HIGH); } else { Serial.printf("Usuário %d encontrado\n", user_index); digitalWrite(LED_GREEN, HIGH); } delay(1000); digitalWrite(LED_GREEN, LOW); digitalWrite(LED_RED, LOW); Serial.println(); } } |
Colocando para Funcionar
Para verificar o funcionamento tenha em mão algumas tags RFID de 13,56MHz e um navegador. Acesse a pagina de cadastro através do ip informado pelo ESP8266 via MonitorSerial. Uma pagina semelhante a da imagem abaixo será exibida.
Figura 9 – Página principal do Sistema.
Para realizar um cadastro aproxime uma tag do leitor e observe que o primeiro campo será preenchido automaticamente. Em seguida adicione uma informação antes de prosseguir o cadastro. Agora clique em cadastrar. Em caso de sucesso uma pagina de confirmação será exibida.
Figura 10 – Página de cadastro bem sucedido.
Clique em voltar e observe a lista de usuários foi atualizada.
Figura 11 – Página principal com o acréscimo de um usuário.
Note que para cada usuário possui um UID RFID e uma informação relacionada. Também existe um botão “Excluir” para cada usuário. O processo de exclusão é muito simples, basta clicar no botão “Excluir” correspondente ao usuário, uma nova pagina será exibida perguntando se deseja prosseguir com a exclusão.
Figura 10 – Página de confirmação de exclusão.
Existem outras paginas pra eventuais falhas no cadastro, mas deixarei para vocês testarem e descobrirem.
Desafio
O sistema proposto é uma versão simples e possui varias limitações que vocês podem descobrir e melhorar. Por exemplo adicionar uma autenticação com usuário e senha antes do cadastro de novas tags para evitar que qualquer invasor apague seus cadastros. Também fica como lição de casa encontrar uma forma de manter o sistema ativo mesmo sem a presença de uma rede Wi-Fi.
Gostou? Deixe seu comentário logo abaixo, aguardo você no próximo post. Confira também a nossa loja virtual encontre todos os componentes utilizados no projeto no post.
Aparece no monitor que está conectando ao wi-fi, e aparece o IP, mas sempre dá erro. E depois começa a mostrar as Tags.
O que pode ser?
Bom dia Maria!
Que tipo de erro está ocorrendo? Travamento, paginas não carregam?
Boa noite. Instalei o sketch acima alterando ssid e senha logicamente. Alterei pinos PIN SS e PIN RST para D3 e D8, conforme minha montagem. Quando reinicio a tela monitor serial mostra a conexao feita na rede com sucesso e fas leitura das tags (RFID ok) nas a pagina de acesso na rede da erro 404 (não localizada) e nao abre. Alguma dica?
Bom dia Olgorofi!
Além de carregar o sketch você também precisa carregar as paginas html para a memoria flash do esp8266. Esse upload é feito pela ferramenta “ESP8266 Filesystem Uploader” como explanado no tópico “Programando”. Abraço.
amigo tem como fazer um similar pelo firebase ?
Olá Yure, fiz isto mas continua a dar erro 404.
ou então amigo teria como agregar unidades aos cartões rfid e por outro sistema retirar essa unidades com um controle de passe
necessito muito de uma ajuda por favor
Olá Yure, tudo bem!
Fiz tudo conforme sua explicação neste tópico, mas está dando erro 404 não carrega a página o que poderá ser, você pode me ajudar?
Olá Luciano!
Além de carregar o sketch você também precisa carregar as paginas html para a memoria flash do esp8266. Esse upload é feito pela ferramenta “ESP8266 Filesystem Uploader” como explanado no tópico “Programando”.
Abraço.
Bom dia Yure!
Verificando em outro tutorial vi que tem que criar uma pasta “data” e dentro dela colocar as páginas HTML, más a onde está os arquivos da página HTML?
Olá Luciano!
Este link do projeto
https://github.com/yurevsal/ESP8266-Sistema-de-cadastramento-RFID
Lá você encontrará todos os arquivos necessários.
Abraço
Olá amigo não tem um video passo apasso no youtube
mostrando como gravar os arquivos no meu da erro ESP8266 Filesystem Uploader
Boa tarde! Esse webService feito no projeto não utiliza uma conexão MQTT ?
Olá Caique, o serviço só funciona como interface(http) com o usuário via navegador, mas poderia ser feito com mqtt tambem.
Olá Yure, muito obrigado pelo tutorial. tentei recriar o código para o ESP 32, mas estou encontrando dificuldade, você conseguiria fazer o favor postar o código portado para o ESP 32? Desde já agradeço pela atenção.
Não estou conseguindo ver onde está o erro, no meu está aparecendo esse erro
exit status 1
reference to ‘byte’ is ambiguous
apareceu para mim também, troquei para de byte para int e funcionou, não sei se é o correto, mas até agora não percebi nenhum erro que poderia acontecer por causa dessa troca
Cara, muito bom… eu comecei a desenvolver alguns projetos com o node mcu, mas faz pouco tempo e ainda estou em um nível bem amador. Esse projeto abriu um pouco mais minha mente para uma forma de fazer projetos realmente profissionais. Parabéns, se você puder compartilhar seu linkedin, eu gostaria muito de acompanhar mais do seu trabalho.
Tive problemas com a variável tipo bit resolvi trocando por uint8_t na linha 238
Olá estou com problemas no cadastramento das tags em alguns momentos ao salvar ocorre um erro depois do html/string ele apresenta</td????, e quebra o carregamento da pagina, suspeito que seja algum problema de leitura enquanto grava.
Alguém ja teve este problema? tem limite de tamanho ou cadastro no arquivo?
tem o mesmo problema
muito bom o projeto, abre uma grande gama de possibilidades de projetos para utilizar estes recursos, e o fato de ter mostrado essa tool de upload de arquivos para o esp32 foi muito interessante, não conhecia, tive o mesmo problema mencionado por outros usuários com o byte sendo considerado ambíguo, mas trocar por int resolveu.
O sistema grava os cadastro em arquivo .txt? 4mb aguenta uns 300 registros?
Olá Luiz, Sim a memoria do ESP8266 é suficiente pra armazenar essa quantidade de registros. Recomendo editar a função readFile() retirando os prints da porta serial afim de reduzir o tempo de processamento.
Yure.
Valeu por esse exemplo.
Mas eu estou tentando colocar o WiFimanager e não consigo compilar com o esp8266 ou o esp32.
Tu sabe o que pode estar ocorrendo?
Boa tarde!
funcionou corretamente, estou com problemas quando cadastro mais de uma tag, ai a pagina de cadastro nao abre mais, pergunto , onde deveria estar este arquivos cadastro.txt citado no codigo? nao achei o mesmo em lugar algum.
Agradeço a ajuda!
Fala Yure,
é possivel implementar um relê de 1 canal , juntamente como led verde. toda vez que o LED verde ascendesse acionaria o relé?
Olá Yure.
Seria possível no ‘else’ de usuário encontrado, que faz acender o led verde, ele também dar um print na porta serial mostrando o nome que foi cadastrado para aquele id?
Sim é possivel.