Open top menu
quinta-feira, abril 25, 2013

Hoje vou apresentar o hardware de um projeto de controle de acesso de colaboradores baseado em Arduino, RFID e Ethernet, futuramente vou postar uma versão da WEBAPI e site de gerenciamento dos acessos.

Para liberação de acesso o usuário aproxima o cartão RFID, o hardware realiza a leitura do número do cartão e acessa a WEBAPI de validação, se o cartão for válido, retorna o status de liberação com o nome do usuário cadastrado no sistema.

Vamos ver um video e fotos do projeto:


Protótipo do equipamento


Detalhe das conexões


Cada local de acesso é cadastrado com um código e as coordenadas de localização, possibilitando em tempo real acompanhar em um mapa todas as entradas e saídas dos colaboradores nos locais cadastrados.


API de acesso 
Request:

http://SERVIDOR/api/acesso/CODIGOCLIENTE/CODIGOEQUIPAMENTO/NUMEROCARTAORFID


SERVIDOR: IP ou DNS do servidor com WEBAPI publicada.
CODIGOCLIENTE: Codigo fixo do cliente, serve para agrupar os locais e usuários.
CODIGOEQUIPAMENTO: Código de identificação único do hardware, atráves dele é cadastrada as coordenadas para identificação do local do acesso.
NUMEROCARTAORFID: Número do cartão RFID.


Response:
<XML>|STATUS NOMEUSUARIO|</XML>
|: Caracter que identifica o início do retorno de validação do acesso
STATUS: Status da validação do acesso
NOMEUSUARIO: Nome do Usuário
|:Caracter que identifica o término do retorno de validação do acesso


Exemplo do acesso
O que é RFID?
Identificação por radiofrequência ou RFID (do inglês "Radio-Frequency IDentification" ) é um método de identificação automática através de sinais de rádio, recuperando e armazenando dados remotamente através de dispositivos denominados etiquetas RFID.

Uma etiqueta ou tag RFID é um transpondedor, pequeno objeto que pode ser colocado em uma pessoa, animal, equipamento, embalagem ou produto, dentre outros. Contém chips de silício e antenas que lhe permite responder aos sinais de rádio enviados por uma base transmissora. Além das etiquetas passivas, que respondem ao sinal enviado pela base transmissora, existem ainda as etiquetas semi-passivas e as ativas, dotadas de bateria, que lhes permite enviar o próprio sinal. São bem mais caras que do que as etiquetas passivas.
RFID: utiliza transponders ( os quais podem ser apenas lidos ou lidos e escritos) nos produtos, como uma alternativa aos códigos de barras, de modo a permitir a identificação do produto de alguma distância do scanner ou independente, fora de posicionamento. Tecnologia que viabiliza a comunicação de dados através de etiquetas com chips ou transponders que transmitem a informação a partir da passagem por um campo de indução. (ex: muito usado em pedágio "sem parar").

by Wikipedia


Conexões do projeto:

Lista de Componentes:
  • Arduino Mega 2560
  • Arduino Ethernet Shield
  • Arduino Rele Shield *
  • Regulador de tensão LM7805.
  • Leitor RFID ID-12 Innovations
  • Cartões RFid
  • Fonte chaveada 12V x 3A
  • LCD 40 Colunas x 4 Linhas (pode ser usado LCD com 2 linhas)
  • Buzzer
  • Rabicho de alimentação para fonte
  • Fios, barras de terminais e termoretráteis para conexão
* A montagem do rele shield foi apresentada no post Construindo um Relé Shield






Pode ser substuido por Arduino 5V Relay module





Código fonte do Arduino:
/*

Sergio de Miranda e Castro Mokshin
26/04/2013

Todos os direitos reservados

*/

#include
#include
#include

#define PIN_SAIDA_BUZZ 49

byte mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
// assign an IP address for the controller:
byte ip[] = {
192,169,1,20 };
byte gateway[] = {
192,168,1,1};
byte subnet[] = {
255, 255, 255, 0 };

byte server[] = { 74, 86, 188 ,173 };

char serverName[] = "dns.servidor.api"; //trocar pelo DNS API Web
EthernetClient client;

char tagRFID[10];
boolean lastConnected = false;

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
int rele1 = 22;
char validacaoTag;
char nomeTag[20];
int indexretornoServer;
boolean inicioretornoServer;

int KEY1 = 26;
int KEY2 = 28;
int KEY3 = 30;
int KEY4 = 32;
int localKEY1 = 0;
int localKEY2 = 0;
int localKEY3 = 0;
int localKEY4 = 0;


void setup() {

pinMode(rele1, OUTPUT);
digitalWrite(rele1, HIGH);

indexretornoServer = 0;
inicioretornoServer = false;

lcd.begin(20, 4);
lcd.print("Me Encontre ");
lcd.setCursor(0, 1);
lcd.print(" ");
lcd.setCursor(0, 2);
lcd.print("Iniciando Sistema ");

Serial.begin(9600);
delay(1000);
Serial.println("connecting...");

if (Ethernet.begin(mac) == 0) {
Serial.println("Failed to configure Ethernet using DHCP");
while(true);
}

aguardandocomandos();

}


void loop()
{
verificacartao();
lastConnected = client.connected();
}

void verificacartao(){

byte i = 0;
byte val = 0;
byte code[6];
byte checksum = 0;
byte bytesread = 0;
byte tempbyte = 0;

if(Serial.available() > 0) {
if((val = Serial.read()) == 2) {
bytesread = 0;
while (bytesread < 12) {
if( Serial.available() > 0) {

lcd.setCursor(0, 1);
lcd.print(" ");
lcd.setCursor(0, 2);
lcd.print("Buscando Dados ");
lcd.setCursor(0, 3);
lcd.print(" ");

val = Serial.read();
if (bytesread < 10)
{
tagRFID[bytesread] = val;
}

if((val == 0x0D)||(val == 0x0A)||(val == 0x03)||(val == 0x02)) {
break;
}

if ((val >= '0') && (val <= '9')) {
val = val - '0';
} else if ((val >= 'A') && (val <= 'F')) {
val = 10 + val - 'A';
}

if (bytesread & 1 == 1) {
code[bytesread >> 1] = (val | (tempbyte << 4));
if (bytesread >> 1 != 5) {
checksum ^= code[bytesread >> 1];
};
} else {
tempbyte = val;
};

bytesread++;
}
}

if (bytesread == 12) {
tagRFID[10] = '\0';
validaAcesso();
}
bytesread = 0;
}
}


}

void validaAcesso()
{
Serial.println(tagRFID);
if (client.connect(serverName, 80)) {
Serial.println("connected");
client.print("GET /api/acesso/INNER/0001/"); //INNER é o codigo do cliente e 0001 o código do Equipamento
client.print(tagRFID);
client.println(" HTTP/1.0");
client.println("Host: dns.servidor.api"); //trocar pelo DNS API Web
client.println();
}
else {
Serial.println("connection failed");
Serial.println();
lcd.setCursor(0, 1);

lcd.print("Erro durante acesso ");
lcd.setCursor(0, 2);
lcd.print("Tente novamente ");

}

inicioretornoServer = false;
indexretornoServer = 0;

while(client.connected() && !client.available()) delay(1); //waits for data
while (client.connected() || client.available()) { //connected or data available
char c = client.read(); //gets byte from ethernet buffer
Serial.print(c);
if (c == '|')
{
inicioretornoServer = !inicioretornoServer;
indexretornoServer = 0;
}

if (inicioretornoServer)
{
//Serial.println(indexretornoServer);
//Serial.println(c);
if(indexretornoServer == 1)
{
validacaoTag = c;
}
else if(indexretornoServer >= 2 && indexretornoServer <= 22)
{
nomeTag[indexretornoServer-2] = c;
}
indexretornoServer++;
//Serial.println(indexretornoServer);
}
}

Serial.println(" ");
Serial.print("Validacao: ");
Serial.print(validacaoTag);
Serial.println(" ");
Serial.print("Nome: ");
Serial.print(nomeTag);

lcd.setCursor(0, 1);
lcd.print(" ");
lcd.setCursor(0, 2);
lcd.print(nomeTag);
lcd.setCursor(0, 3);

if(validacaoTag == 'E'){
digitalWrite(rele1, LOW);
lcd.print("Entrada Registrada ");}

if(validacaoTag == 'S'){
digitalWrite(rele1, LOW);
lcd.print("Saida Registrada ");}

if(validacaoTag == 'X'){
lcd.print("Cartao sem Acesso ");}

Serial.println();
Serial.println("disconnecting.");
Serial.println("==================");
Serial.println();


delay(1000);
digitalWrite(rele1, HIGH);
delay(500);
client.stop(); //stop client
aguardandocomandos();
}


void consultacartaoserver(){

lcd.setCursor(0, 1);
lcd.print("Consultando dados ");
lcd.setCursor(0, 2);
lcd.print(" Aguarde ");

Serial.print("Cartao: ");
Serial.println(tagRFID);


int thisData;
thisData = 12234;



}

void aguardandocomandos(){
lcd.setCursor(0, 1);
lcd.print(" ");
lcd.setCursor(0, 2);
lcd.print("Passe o Cartao ");
lcd.setCursor(0, 3);
lcd.print(" ");


}


Fluxo de Operação

Código Fonte
O código fonte da API  e site de administração e localização está disponível no github.


Tagged
Different Themes
Written by Lovely

Aenean quis feugiat elit. Quisque ultricies sollicitudin ante ut venenatis. Nulla dapibus placerat faucibus. Aenean quis leo non neque ultrices scelerisque. Nullam nec vulputate velit. Etiam fermentum turpis at magna tristique interdum.

7 comentários:

  1. Boa noite Sergio, gostei muito do seu projeto e meu TCC eh muito parecido.
    A diferença eh que tenho que abrir um portão automatico e verificar no site o fluxo dos tags rfid.
    terias como me ajudar?

    ResponderExcluir
  2. Olá Sergio acho muito legal seu projeto assim como sua iniciativa e tudo mais.

    Comecei com Arduino a pouco tempo entretanto já programo a mais. Em um dos projetos que tive realizando com Arduino me deparei com a dificuldade em estar enviando varias variáveis ao Arduino ao mesmo tempo e o mesmo identificar o que é cada variável, seja via PHP ou C#.

    Pesquisei bastante na internet e esse projeto foi o que achei de mais próximo pois pelo que imagino na validação de acesso você precisa em algum momento retornar para o Arduino os dados e informações.

    Um exemplo que posso lhe dar é o controle de um LED RGB via PHP, aonde eu envio o código das cores obtidos para Arduino, no caso cada cor possui um código diferente, mas o Arduino não sabe diferenciar qual código é de cada cor. Outro exemplo é o de enviar dados de 3 sensores simultaneamente e saber de qual sensor no Arduino e cada dado enviado.

    Não sei se ficou claro mas ficarei grato se puder ajudar.

    Obrigado.

    ResponderExcluir
    Respostas
    1. Hércules, não ficou muito claro.
      Mas pelo que entendi, sua dificuldade é receber variaveis no arduino?
      Voce pode configurar como WebClient ou WebServer, precisa identificar qual implementação atende seu projeto.
      No meu caso, está implmentando como WebClient. Consumo uma WEBAPI Rest escrita em .NET (poderia sem em PHP, Java, etc) e essa API recebe o numero do cartao, valida e devolve um status.
      A partir da linha while(client.connected() && !client.available()) delay(1); //waits for data
      eu faço o tratamento e atualizo a variavel validacaoTag com o retorno.

      Excluir
  3. Boa noite Sérgio,

    Consegui fazer um sistema parecido, porém fiz com apenas duas tags.
    Queria colocar mais 4 tags, mas da seguinte forma:
    3 tags para identificar carros e as outras 3 tags identifica pessoas.
    O sistema só aceita a liberação do acesso, após 2 tags (distintas: carro e pessoa) forem válidos.
    o trecho do código segue abaixo, mas esse código não está dando certo. Tem como vc dar uma olhada e ver no que pode ajudar?
    ///////////////////////////////////
    //Verifica todos os tags
    ///////////////////////////////////

    if(strlen(tag) == 0) return; //se vazio, não verifica

    if(compareTag(tag, tag_carro))
    { // se é carro
    Serial.println("TAG 1");
    LCD.setCursor(0,1);
    LCD.print(" OCS 4616 ");
    carro_ok = 1;

    }else if(compareTag(tag, tag_pessoa))
    //se é pessoa
    Serial.println("TAG 2");
    LCD.setCursor(0,1);
    LCD.print(" Igor ");
    pessoa_ok = 1;

    if(compareTag(tag, tag_carro1))
    { // se é carro
    Serial.println("TAG 3");
    LCD.setCursor(0,1);
    LCD.print(" OSP 5408 ");
    carro_ok = 1;

    }else if(compareTag(tag, tag_pessoa1))
    { //se é pessoa
    Serial.println("TAG 4");
    LCD.setCursor(0,1);
    LCD.print(" Marcio ");
    pessoa_ok = 1;
    }
    else
    {// senão é nenhum dos dois escreve na serial
    Serial.println("Tag Inválido!");
    LCD.setCursor(0,1);
    LCD.print(" Tag Inválido ");
    carro_ok = 2;
    pessoa_ok = 2;
    }
    }

    ResponderExcluir
  4. Bom dia Sergio. Estou desenvolvendo um sistema de controle para alunos e professores de uma escola municipal de música de minha cidade. Gostaria, se possível, da sua indicação do material para estudo. Se puder indicar eu agradeço.

    ResponderExcluir
  5. Fala Wilton, Boa Noite!
    No projeto eu precisava armazenar o histórico de acessos, a API apenas inseria um registro de localização e data do usuário no banco de dados e a página mostrava a última localização.

    ResponderExcluir
  6. Boa tarde! A API e gerenciador foram desenvolvidos em .NET. Liberei o código fonte no github, o link foi disponibilizado no fim do artigo.

    ResponderExcluir