Já imaginou ter o controle total do acesso a qualquer ambiente na palma da sua mão? Neste post, você vai descobrir como transformar esse cenário em realidade, usando a combinação do Arduino e tecnologia RFID, além de conhecer uma plataforma que possibilita desenvolver um aplicativo de forma simples e rápida, o MIT App Inventor.
Este projeto consiste em uma integração entre tecnologia RFID e aplicativos móveis, para criar um sistema de controle de acesso inovador e com diversas aplicações. Entre as funções do projeto:
De modo geral, este projeto combina a sofisticação da tecnologia RFID com a conveniência da conectividade Bluetooth por meio de um aplicativo móvel. E como resultado, um sistema de controle de acesso personalizável e seguro, que pode ser inserido em várias aplicações, desde o controle de acesso residencial até o gerenciamento de segurança em escritórios e empresas.
O MIT App Inventor é uma plataforma de desenvolvimento de aplicativos móveis que torna a criação de aplicativos para dispositivos Android acessível a pessoas de todas as idades e níveis de habilidade. Desenvolvido pelo Instituto de Tecnologia de Massachusetts (MIT), o App Inventor foi lançado com o objetivo de democratizar o desenvolvimento de aplicativos e permitir que qualquer pessoa transforme suas ideias em aplicativos funcionais.
Uma das principais vantagens notáveis dessa plataforma é a sua capacidade de simplificar consideravelmente a criação de aplicativos. Todo o processo é eficiente e a interface é altamente intuitiva, facilitando a criação.
Primeiramente acesse a plataforma MIT App inventor e crie uma conta de acesso para a plataforma. Em seguida importe o projeto (APP simplificado) que serve como uma base para você adicionar demais funções.
Importando o projeto:
Ao selecionar o arquivo o projeto será aberto automaticamente:
Explicando a lógica do programa:
Existem duas formas para realizar a conexão do projeto:
Alimentação da Arduino nano via cabo mini USB:
Alimentação do Arduino via Fonte externa:
Pode ser necessário substituir o resistor de 1000 ohms para obter uma imagem mais clara do Display LCD.
O código a seguir é utilizado junto com o aplicativo disponibilizado acima, em conjunto eles realizam as seguintes funções:
Baixe a pasta “RFID_ELETROGATE_porRafaelFaleiros” neste link: https://github.com/eletrogate/rfid_celular/tree/main
Vamos analisar o código em partes:
#include <SPI.h> #include <MFRC522.h> #include <EEPROM.h> #include <SoftwareSerial.h> #include <LiquidCrystal.h> #define EEPROM_SIZE 1000 // Escolha o tamanho da EEPROM que deseja usar #define trava 8 // define pino para trava solenoide da porta #define ledVerde A5 // define o pino em que está conectado o terminal referente a cor verde do LED RGB #define ledVermelho A1 // define o pino em que está conectado o terminal referente a cor vermelha do LED RGB #define ledAzul A2 // define o pino em que está conectado o terminal referente a cor verde do LED RGB // Define os pinos para a conexão ao display LCD LiquidCrystal lcd(2,3,4,5,6,7); // Define os pinos RX e TX para o módulo HC-05 const int bluetoothRxPin = 9; // Conecte o TX do HC-05 ao pino 9 do Arduino const int bluetoothTxPin = 10; // Conecte o RX do HC-05 ao pino 10 do Arduino SoftwareSerial bluetoothSerial(bluetoothRxPin, bluetoothTxPin); char receivedText[9]; // Cria um array para armazenar os 8 caracteres mais o caractere nulo #define SDA_PIN A4 // Pino SS do MFRC522 #define RST_PIN A3 // Pino RST do MFRC522 #define RFID_TAG_LENGTH 8 // Tamanho da tag RFID (ajuste conforme necessário) MFRC522 mfrc522(SDA_PIN, RST_PIN); // Criação de uma instância do MFRC522 int incomingByte; void setup() { //Define os pinos do LED RGB e do módulo relé como saida. pinMode(ledAzul,OUTPUT); pinMode(ledVerde,OUTPUT); pinMode(ledVermelho,OUTPUT); pinMode(trava, OUTPUT); // Inicialização do LCD lcd.begin(16, 2); // Inicialização das comunicações Serial.begin(9600); bluetoothSerial.begin(9600); SPI.begin(); mfrc522.PCD_Init(); // Verifica se a EEPROM está limpa ou contém dados if (isEEPROMCleared()) { // Se limpa, exibe mensagem e imprime no monitor serial escreve("EEPROM LIMPA", 0, 0, 1); Serial.println("A EEPROM está limpa."); } else { // Se contém dados, exibe mensagem e imprime no monitor serial escreve("EEPROM ESCRITA", 0, 0, 1); Serial.println("A EEPROM não está limpa."); } delay(1000); } void loop() { digitalWrite(trava,HIGH); digitalWrite(ledAzul,HIGH); leituraTAG(); // Função para ler as tags RFID bluetooth(); // Função para lidar com a comunicação Bluetooth }
Este trecho de código se concentra na configuração inicial do projeto. Vamos descrevê-lo brevemente:
SPI
, MFRC522
, EEPROM
, SoftwareSerial
e LiquidCrystal
, são incluídas no início do código para habilitar funcionalidades específicas.EEPROM_SIZE
. Isso permite ajustar o tamanho da memória EEPROM para armazenar dados, como IDs de RFID, conforme necessário.LiquidCrystal
.SoftwareSerial
chamada bluetoothSerial
é criada para lidar com a comunicação Bluetooth.receivedText
é definido para armazenar dados recebidos via Bluetooth.setup()
, são realizadas as seguintes ações:
OUTPUT).
loop()
, as seguintes funções são chamadas repetidamente:
leituraTAG()
: Esta função lida com a leitura de tags RFID.bluetooth()
: Esta função lida com a comunicação Bluetooth.Este trecho de código estabelece a base para o funcionamento do seu projeto, configurando as conexões de hardware e verificando o estado da EEPROM antes de iniciar as operações principais, como leitura de tags RFID e comunicação Bluetooth.
// Função para encontrar o próximo endereço disponível na EEPROM int findNextAvailableAddress() { for (int addr = 0; addr < EEPROM_SIZE; addr += RFID_TAG_LENGTH) { bool isEmpty = true; // Verifica cada byte na EEPROM no espaço reservado para a tag RFID for (int i = 0; i < RFID_TAG_LENGTH; i++) { if (EEPROM.read(addr + i) != 0) { isEmpty = false; break; // Se encontrar um byte não vazio, a tag não está presente } } // Se não foi encontrado nenhum byte não vazio (tag presente), retorna o endereço if (isEmpty) { return addr; } } return -1; // Retorna -1 se não houver espaço disponível na EEPROM } // Função para verificar se a EEPROM está limpa (todos os bytes são 0) bool isEEPROMCleared() { for (int i = 0; i < EEPROM_SIZE; i++) { // Verifica cada byte na EEPROM if (EEPROM.read(i) != 0) { return false; // Se encontrar um byte diferente de zero, a EEPROM não está limpa } } return true; // Se não encontrou nenhum byte diferente de zero, a EEPROM está limpa }
Função findNextAvailableAddress()
:
Esta função tem a finalidade de encontrar o próximo endereço disponível na memória EEPROM para armazenar uma nova tag RFID. A memória EEPROM é dividida em blocos, cada um com um tamanho igual ao da tag RFID. Aqui está como a função opera:
EEPROM_SIZE
).RFID_TAG_LENGTH
) está vazio. Isso é feito comparando cada byte no bloco com zero.Função isEEPROMCleared()
:
Esta função tem como objetivo verificar se a memória EEPROM está limpa, o que significa que todos os seus bytes são iguais a zero. A memória EEPROM é considerada “limpa” quando não contém dados previamente armazenados. Aqui está como a função opera:
EEPROM_SIZE
).false
para indicar que a EEPROM não está limpa. Caso contrário, se não for encontrado nenhum byte diferente de zero em toda a EEPROM, a função retorna true
, indicando que a EEPROM está limpa.Essas funções desempenham um papel importante no gerenciamento da memória EEPROM, permitindo que o programa saiba onde armazenar novas tags RFID e se a EEPROM já contém dados anteriormente gravados.
// Função para limpar (apagar) todos os dados na memória EEPROM void clearEEPROM() { for (int i = 0; i < EEPROM_SIZE; i++) { EEPROM.write(i, 0); // Escreve o valor zero em cada endereço da EEPROM } Serial.println("EEPROM limpa."); // Imprime uma mensagem indicando que a EEPROM foi apagada }
Descrição da Função clearEEPROM()
:
A função clearEEPROM()
é responsável por apagar (ou limpar) todos os dados armazenados na memória EEPROM do Arduino. Aqui está como a função opera:
EEPROM_SIZE
).EEPROM.write(i, 0)
para escrever o valor zero (0) no endereço de memória correspondente. Isso efetivamente apaga ou substitui qualquer dado que estava previamente armazenado naquele endereço da EEPROM.Ao chamar esta função no seu código, todos os dados previamente armazenados na EEPROM serão permanentemente apagados, deixando-a vazia e pronta para ser utilizada para armazenar novas informações. Certifique-se de usar esta função com cuidado, pois a limpeza da EEPROM é irreversível, e os dados antigos serão perdidos. É útil quando você deseja redefinir a memória EEPROM para um estado inicial limpo antes de armazenar novos dados.
// Função para lidar com a comunicação Bluetooth void bluetooth() { if (bluetoothSerial.available() >= 8) { // Verifica se há pelo menos 8 caracteres disponíveis para leitura no buffer Bluetooth bluetoothSerial.readBytes(receivedText, 8); // Lê os 8 caracteres receivedText[8] = '\0'; // Adiciona um caractere nulo para formar uma string válida // Exibe o texto recebido no monitor serial Serial.println("Texto recebido: " + String(receivedText)); escreve("Tag adicionada:", 0, 0, 1); // Exibe a mensagem "Tag adicionada" no LCD escreve(receivedText, 0, 1, 0); // Exibe o conteúdo da tag RFID no LCD writeRFIDTagToEEPROM(receivedText); // Chama uma função para escrever a tag RFID na EEPROM } if (bluetoothSerial.available() > 0) { // Lê o byte mais antigo no buffer serial Bluetooth incomingByte = bluetoothSerial.read(); // Se o byte recebido for 'R', realiza uma ação específica (no caso, limpa a EEPROM) if (incomingByte == 'R') { clearEEPROM(); // Chama uma função para limpar a EEPROM escreve("EEPROM limpa.", 0, 0, 1); // Exibe uma mensagem no LCD indicando que a EEPROM foi limpa } } }
Descrição da Função bluetooth()
:
A função bluetooth()
é responsável por lidar com a comunicação Bluetooth e executar ações com base nos dados recebidos via Bluetooth. Aqui está como a função opera:
if (bluetoothSerial.available() >= 8)
.bluetoothSerial.readBytes()
e os armazena na variável receivedText
como uma string válida.writeRFIDTagToEEPROM()
para escrever a tag RFID na EEPROM.clearEEPROM()
para limpar todos os dados na EEPROM e exibe “EEPROM limpa” no LCD.Essa função permite que o Arduino interaja com um dispositivo Bluetooth externo, processando os comandos recebidos e realizando ações específicas, como adicionar tags RFID à EEPROM ou limpar a EEPROM quando necessário.
// Função para verificar se uma tag RFID está cadastrada na memória EEPROM bool isTagRegistered(const String &tag) { for (int addr = 0; addr < EEPROM_SIZE; addr += RFID_TAG_LENGTH) { bool match = true; // Verifica se cada byte da EEPROM corresponde ao conteúdo da tag fornecida for (int i = 0; i < RFID_TAG_LENGTH; i++) { if (EEPROM.read(addr + i) != tag[i]) { match = false; break; } } // Se todas as posições da tag coincidirem, a tag está cadastrada if (match) { return true; // A tag está cadastrada na EEPROM } } // Se a função chegou até aqui, a tag não foi encontrada na EEPROM return false; // A tag não está cadastrada na EEPROM }
Descrição da Função isTagRegistered(const String &tag)
:
A função isTagRegistered()
tem como objetivo verificar se uma tag RFID específica está cadastrada na memória EEPROM. Ela opera da seguinte maneira:
EEPROM_SIZE
). Isso é feito avançando de acordo com o tamanho da tag RFID (RFID_TAG_LENGTH
), garantindo que cada bloco de memória correspondente ao tamanho de uma tag seja verificado.match
é definida como verdadeira, indicando que a tag está cadastrada naquele endereço da EEPROM.match
permanecer verdadeira após a verificação de todos os bytes da tag, a função retorna true
, indicando que a tag está cadastrada na EEPROM.false
, indicando que a tag não está cadastrada na EEPROM.Essa função é útil para verificar se uma tag específica já foi registrada anteriormente na EEPROM, permitindo assim o controle de acesso com base nas tags cadastradas.
// Função para escrever uma tag RFID na memória EEPROM, se ainda não estiver cadastrada void writeRFIDTagToEEPROM(const String &tag) { if (isTagRegistered(receivedText)) { // Se a tag já estiver cadastrada, exibe uma mensagem e informa que a tag já existe escreve("TAG cadastrada", 0, 0, 1); // Exibe "TAG cadastrada" no LCD escreve(receivedText, 0, 1, 0); // Exibe o conteúdo da tag RFID no LCD Serial.println("Tag RFID já cadastrada."); } else { // Se a tag não estiver cadastrada, exibe uma mensagem e adiciona a tag à EEPROM escreve("TAG adicionada", 1, 0, 1); // Exibe "TAG adicionada" no LCD escreve(receivedText, 0, 1, 0); // Exibe o conteúdo da tag RFID no LCD Serial.println("Tag RFID adicionada"); // Encontra o próximo endereço disponível na EEPROM int addr = findNextAvailableAddress(); // Escreve a tag RFID na EEPROM for (int i = 0; i < RFID_TAG_LENGTH; i++) { EEPROM.write(addr + i, tag[i]); } } }
Descrição da Função writeRFIDTagToEEPROM(const String &tag)
:
A função writeRFIDTagToEEPROM()
é responsável por escrever uma tag RFID na memória EEPROM, mas somente se ela ainda não estiver cadastrada. Aqui está como a função opera:
isTagRegistered(receivedText)
. Se a tag já estiver cadastrada, a função exibe uma mensagem no LCD indicando que a tag já existe e também imprime “Tag RFID já cadastrada” no monitor serial.findNextAvailableAddress()
para encontrar o próximo endereço disponível na EEPROM onde a nova tag RFID será escrita.Essa função é crucial para o processo de adicionar novas tags RFID ao sistema de controle de acesso. Ela evita a duplicação de tags cadastradas, garantindo que apenas tags não registradas sejam adicionadas à EEPROM.
// Função para escrever texto no display LCD void escreve(String palavra, int linha, int coluna, int apagar) { if (apagar == 1) { lcd.clear(); // Limpa o conteúdo do LCD se o parâmetro "apagar" for igual a 1 } lcd.setCursor(linha, coluna); // Define a posição de escrita no LCD lcd.print(palavra); // Exibe a palavra no LCD na posição definida }
Descrição da Função escreve(String palavra, int linha, int coluna, int apagar)
:
A função escreve()
é responsável por exibir texto no display LCD, permitindo que você defina a posição exata (linha e coluna) onde o texto será exibido. Aqui está como a função opera:
apagar
. Se apagar
for igual a 1, a função chama lcd.clear()
para limpar o conteúdo atual do LCD antes de escrever o novo texto. Isso permite substituir o conteúdo anterior por um novo.lcd.setCursor(linha, coluna)
para definir a posição de escrita no LCD, onde linha
e coluna
são os parâmetros que determinam a posição.lcd.print(palavra)
para exibir a palavra
especificada no LCD na posição definida.Essa função é útil para atualizar e exibir informações no display LCD, como mensagens de status, dados de RFID lidos ou qualquer outra informação que você deseja apresentar visualmente no projeto. O parâmetro apagar
permite que você escolha se deseja limpar o conteúdo anterior antes de exibir o novo texto.
// Função para ler e processar uma tag RFID void leituraTAG() { escreve("Aproxime a TAG", 0, 0, 1); // Exibe "TAG cadastrada" no LCD escreve("do leitor", 0, 1, 0); // Exibe "TAG cadastrada" no LCD digitalWrite(ledAzul,HIGH); // Verifica se uma tag RFID está presente no leitor if (mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial()) { // Lê a tag RFID e a armazena em uma string String rfidTag = ""; for (byte i = 0; i < mfrc522.uid.size; i++) { rfidTag += String(mfrc522.uid.uidByte[i], HEX); } // Verifica se a tag lida está cadastrada na EEPROM if (isTagRegistered(rfidTag)) { escreve("TAG cadastrada", 0, 0, 1); // Exibe "TAG cadastrada" no LCD escreve(rfidTag, 0, 1, 0); // Exibe o conteúdo da tag RFID no LCD Serial.println("Tag RFID cadastrada."); Serial.println("Tag RFID lida: " + rfidTag); // Imprime a tag RFID no monitor serial // aciona a trava por 3seg digitalWrite(ledAzul,LOW); digitalWrite(trava,LOW); digitalWrite(ledVerde,HIGH); delay(3000); digitalWrite(trava,HIGH); digitalWrite(ledVerde,LOW); } else { escreve("TAG incorreta", 0, 0, 1); // Exibe "TAG incorreta" no LCD escreve(rfidTag, 0, 1, 0); // Exibe o conteúdo da tag RFID no LCD Serial.println("Tag RFID não cadastrada."); Serial.println("Tag RFID lida: " + rfidTag); // Imprime a tag RFID no monitor serial digitalWrite(ledAzul,LOW); digitalWrite(ledVermelho, HIGH); delay(3000); digitalWrite(ledVermelho, LOW); } // Aguarda um momento para evitar leituras múltiplas da mesma tag delay(1000); } }
Descrição da Função leituraTAG()
:
A função leituraTAG()
é responsável por ler e processar uma tag RFID quando ela está presente no leitor MFRC522. Aqui está como a função opera:
mfrc522.PICC_IsNewCardPresent()
. Se uma tag estiver presente, a função continua a execução.mfrc522.PICC_ReadCardSerial()
para efetivamente ler a tag RFID e armazenar seu conteúdo em uma string chamada rfidTag
. A tag é representada como uma sequência hexadecimal na string.isTagRegistered(rfidTag)
para verificar se a tag lida está cadastrada na EEPROM. Se a tag estiver cadastrada, a função exibe “TAG cadastrada” no LCD, exibe o conteúdo da tag RFID no LCD e imprime “Tag RFID cadastrada” no monitor serial. Caso contrário, exibe “TAG incorreta” no LCD, exibe o conteúdo da tag RFID no LCD e imprime “Tag RFID não cadastrada” no monitor serial.delay(1000)
antes de continuar a executar o loop.Essa função é essencial para o processo de leitura e validação de tags RFID no sistema de controle de acesso. Ela exibe informações relevantes no LCD e no monitor serial, permitindo que você saiba se a tag é válida ou não. Além disso, o atraso de 1 segundo ajuda a evitar leituras consecutivas da mesma tag.
Baixe todos os arquivos disponibilizados no link https://github.com/eletrogate/rfid_celular/tree/main
Baixe o aplicativo disponibilizado neste link com o nome “Eletrogate_RFID2_basic3.apk”
Baixe a pasta com os códigos nomeada como “RFID_ELETROGATE_porRafaelFaleiros”
Como acessar o código:
Como acessar o aplicativo:
Observação: Você pode precisar emparelhar inicialmente a placa com seu celular. Para fazer isso, vá para as configurações do seu smartphone, acesse ‘Dispositivos Bluetooth’ e selecione a placa. Se for solicitada uma senha, insira ‘0000’ (que é o padrão de fábrica).
Em seguida, você pode adicionar as tags desejadas e, se desejar, solicitar nomes a elas para facilitar a identificação das TAGs cadastradas para acessar seu ambiente. Depois de adicionar todas as TAGs desejadas, clique na opção ‘Atualizar Dados’. Isso salvará todas as novas TAGs no dispositivo.
IMPORTANTE:
No encerramento deste post, mergulhamos em um projeto prático de controle de acesso RFID, explorando a integração do Arduino, módulos RFID e o MIT App Inventor. Através deste tutorial, você teve a oportunidade de aprender como ler tags RFID, armazenar dados na memória EEPROM, estabelecer comunicação via Bluetooth e até mesmo reiniciar a memória quando necessário. Este projeto oferece uma visão prática da integração de tecnologias diversas para criar soluções de controle de acesso personalizadas.
Como pode ser observado a TAG do cartão não é reconhecida até que a mesma seja adicionada pelo aplicativo.
|
A Eletrogate é uma loja virtual de componentes eletrônicos do Brasil e possui diversos produtos relacionados à Arduino, Automação, Robótica e Eletrônica em geral.
Tenha a Metodologia Eletrogate dentro da sua Escola! Conheça nosso Programa de Robótica nas Escolas!