Sabemos em escritórios, shoppings e em muitos outros locais onde apenas a pessoa com cartão de autorização pode entrar na sala. Esses sistemas usam sistema de comunicação RFID. RFID é usado em shoppings para impedir roubos, pois os produtos são etiquetados com chip RFID e quando uma pessoa sai do prédio com o chip RFID um alarme é acionado automaticamente. A etiqueta RFID é projetada tão pequena quanto parte da areia. Os sistemas de autenticação RFID são fáceis de projetar e baratos. Algumas escolas e faculdades hoje em dia usam sistemas de atendimento baseados em RFID.
Neste projeto vamos desenhar uma máquina de votação que só conta os votos autenticados. Isso é feito usando etiquetas RFID (Radio Frequency Identification). Aqui, vamos escrever um programa para ATMEGA para permitir que apenas os titulares de etiquetas RFID autorizados votem. (Verifique também este projeto simples de máquina de votação)
Componentes necessários
Hardware: ATMEGA32, fonte de alimentação (5v), AVR-ISP PROGRAMMER, JHD_162ALCD (16x2LCD), capacitor 100uF (conectado através da fonte de alimentação), botão (cinco peças), resistor 10KΩ (cinco peças), capacitor 100nF (cinco peças), LED (duas peças), EM-18 (módulo leitor RFID).
Software: Atmel studio 6.1, progisp ou flash magic.
Diagrama de Circuito e Explicação
No circuito, PORTA de ATMEGA32 está conectado à porta de dados do LCD. Aqui, deve-se lembrar de desabilitar a comunicação JTAG de PORTC para ATMEGA, alterando os bytes do fusível, caso se queira usar o PORTC como porta de comunicação normal. No LCD 16x2, existem 16 pinos no total, se houver uma luz negra, se não houver luz de fundo, haverá 14 pinos. Pode-se ligar ou deixar os pinos da luz de fundo. Agora, nos 14 pinos, há 8 pinos de dados (7-14 ou D0-D7), 2 pinos de fonte de alimentação (1 e 2 ou VSS e VDD ou gnd e + 5v), 3º pino para controle de contraste (VEE-controla a espessura dos caracteres mostrado), 3 pinos de controle (RS & RW & E)
No circuito, você pode observar que eu peguei apenas dois pinos de controle, isso dá a flexibilidade de um melhor entendimento, o bit de contraste e READ / WRITE não são usados com frequência, então eles podem estar em curto com o terra. Isso coloca o LCD em maior contraste e modo de leitura. Precisamos apenas controlar os pinos ENABLE e RS para enviar caracteres e dados de acordo.
As conexões que são feitas para LCD são fornecidas abaixo:
PIN1 ou VSS para aterrar
PIN2 ou VDD ou VCC para alimentação de + 5v
PIN3 ou VEE para aterrar (oferece contraste máximo, melhor para um iniciante)
PIN4 ou RS (seleção de registro) para PD6 de uC
PIN5 ou RW (leitura / gravação) para aterrar (coloca o LCD no modo de leitura facilita a comunicação para o usuário)
PIN6 ou E (habilitar) para PD5 de uC
PIN7 ou D0 a PA0 de uC
PIN8 ou D1 a PA1 de uC
PIN9 ou D2 a PA2 de uC
PIN10 ou D3 a PA3 de uC
PIN11 ou D4 a PA4 de uC
PIN12 ou D5 a PA5 de uC
PIN13 ou D6 a PA6 de uC
PIN14 ou D7 a PA7 de uC
No circuito, você pode ver que usamos comunicação de 8 bits (D0-D7). No entanto, isto não é obrigatório e podemos usar comunicação de 4 bits (D4-D7) mas com o programa de comunicação de 4 bits torna-se um pouco complexo, por isso preferi comunicação de 8 bits.
Portanto, pela mera observação da tabela acima, estamos conectando 10 pinos do LCD ao controlador, em que 8 pinos são pinos de dados e 2 pinos para controle.
Antes de prosseguir, precisamos entender sobre a comunicação serial. O módulo RFID aqui envia dados para o controlador em série. Possui outro modo de comunicação, mas para facilitar a comunicação, optamos pelo RS232. O pino RS232 do módulo é conectado ao pino RXD do ATMEGA.
Os dados enviados pelo módulo RFID vão como:
Agora, para a interface do módulo RFID, os seguintes recursos são necessários:
1. O pino RXD (recurso de recebimento de dados) do controlador deve ser habilitado.
2. Como a comunicação é serial, precisamos saber quando o bye de dados é recebido, para que possamos interromper o programa até que o byte completo seja recebido. Isso é feito ativando uma interrupção completa de recebimento de dados.
3. RFID envia dados para o controlador no modo de 8 bits. Portanto, dois personagens serão enviados ao controlador por vez. Isso é mostrado no bloco da figura 3
4. Na figura 3, não há bits de paridade, um bit de parada nos dados enviados pelo módulo.
Os recursos acima são configurados nos registros do controlador; vamos discuti-los brevemente,
VERMELHO (RXEN): Este bit representa o recurso de recebimento de dados, este bit deve ser definido para que os dados do módulo sejam recebidos pelo controlador, ele também habilita o pino RXD do controlador.
BROWN (RXCIE): Este bit deve ser definido para obter uma interrupção após a recepção de dados com sucesso. Ao habilitar este bit, ficamos sabendo, logo após o recebimento dos dados de 8 bits.
PINK (URSEL): Este bit deve ser definido antes de habilitar outros bits no UCSRC, depois de definir outros bits necessários no UCSRC; URSEL deve ser desativado ou zerado.
AMARELO (UCSZ0, UCSZ1, UCSZ2): Esses três bits são usados para selecionar o número de bits de dados que estamos recebendo ou enviando de uma só vez.
Como os dados enviados pelo módulo RFID são do tipo 8 bits (FIGURA 3), temos que definir UCSZ0, UCSZ1 para um e UCSZ2 para zero.
LARANJA (UMSEL): Este bit é definido com base em se o sistema está se comunicando de forma assíncrona (ambos usam relógio diferente) ou de forma síncrona (ambos usam o mesmo relógio),
Como o módulo e o controlador usam relógios diferentes, esse bit deve ser definido como zero ou deixado sozinho, pois todos eles são definidos como zero por padrão.
VERDE (UPM1, UPM0): Esses dois bits são ajustados com base na paridade de bit que estamos usando na comunicação.
Como o módulo RFID envia dados sem paridade (FIGURA 3), definimos UPM1 e UPM0 como zero ou eles podem ser deixados sozinhos, pois todos os bits em qualquer registrador são definidos como zero por padrão.
AZUL (USBS): Este bit é usado para escolher o número de bits de parada que estamos usando durante a comunicação.
Como o módulo RFID envia dados com um bit de parada (figura 3), só temos que deixar o bit USBS sozinho.
Agora, finalmente, precisamos definir a taxa de bauds, da figura 3 fica claro que o módulo RFID envia dados para o controlador com uma taxa de bauds de 9600bps (bits por segundo).
A taxa de transmissão é definida no controlador, escolhendo o UBRRH apropriado,
O valor UBRRH é escolhido por referência cruzada de taxa de transmissão e frequência de cristal da CPU,
Portanto, por referência cruzada o valor UBRR é visto como '6' e, portanto, a taxa de transmissão é definida.
Existem cinco botões aqui, quatro para incrementar os votos dos candidatos e o quinto para zerar os votos dos candidatos. Os capacitores presentes aqui são para anular o efeito de salto dos botões. Se forem removidos, o controlador poderá contar mais de um cada vez que o botão for pressionado.
Os resistores conectados por pinos são para limitar a corrente, quando o botão é pressionado para puxar o pino para o solo. Sempre que um botão é pressionado, o pino correspondente do controlador é puxado para baixo e, assim, o controlador reconhece que determinado botão foi pressionado e a ação correspondente a ser executada, pode ser incrementar os votos dos candidatos ou redefinir os votos dependendo do botão pressionado.
Quando o botão que representa uma pessoa correspondente é pressionado, o controlador o seleciona e incrementa o número da pessoa correspondente dentro de sua memória após o incremento, ele mostra a pontuação da pessoa correspondente no visor LCD 16x2.
O funcionamento da máquina de votação é melhor explicado passo a passo do código C abaixo:
Explicação do código
#include // cabeçalho para habilitar o controle do fluxo de dados sobre os pinos
#define F_CPU 1000000 // dizendo a frequência de cristal do controlador conectado
#incluir
#define E 5 // dando o nome “habilitar” ao 5º pino do PORTD, já que está conectado ao pino de habilitação do LCD
# define RS 6 // dando o nome de “ seleção de registros” ao 6º pino do PORTD, já que está conectado ao pino RS do LCD
void send_a_command (comando unsigned char);
void send_a_character (caractere sem sinal);
void send_a_string (char * string_of_characters);
int main (vazio)
{
DDRA = 0xFF; // colocando porta como pinos de saída
DDRD = 0b11111110;
_delay_ms (50); // dando atraso de 50ms
DDRB = 0b11110000; // Tomando alguns pinos da porta B como entrada.
UCSRB - = (1 <
// habilitando a interrupção completa do recebimento de dados, habilitando o pino de recepção de dados
UCSRC - = (1 <
// alterando outros bits definindo primeiro URSEL, configuração para comunicação de 8 bits
UCSRC & = ~ (1 <
UBRRH & = ~ (1 <
UBRRL = 6; // definir a taxa de transmissão
int16_t VOTEA = 0; // pessoa1 votos armazenando memória
char A; // pessoa1 vota exibindo caractere no LCD
int16_t VOTEB = 0;; // pessoa2 votos armazenando memória
char B; // pessoa2 votos exibindo caractere no LCD
int16_t VOTEC = 0;; // pessoa3 votos armazenando memória
char C; // person3 votos exibindo caractere no LCD
int16_t VOTADO = 0;; // pessoa4 votos armazenando memória
char D; / / person4 votos exibindo caractere no LCD
// O seguinte contém IDs de tags, eles devem ser alterados para tags diferentes, devem ser atualizados para que o projeto funcione
// Após descarregar o programa no controlador deve-se pegar os cartões que devem ser autorizados e obter o ID das tags, estas são obtidas colocando-se a tag perto do módulo RFID e a ID será mostrada na tela. Depois de obter os IDs, o programa deve ser atualizado substituindo os números de ID abaixo por novos números de ID.
char ADMIT = {{(0x97), (0xa1), (0x90), (0x92)}, {(0x97), (0xa1), (0x90), (0x93)}, {(0x97), (0xa1), (0x90), (0x94)}, {(0x97), (0xa1), (0x90), (0x95)}, {(0x97), (0xa1), (0x90), (0x96)}}; |
Agora, acima, estamos autorizando apenas cinco cartões, eles podem ser alterados para qualquer número, Por exemplo, considere que o programa padrão é descarregado no controlador, pegue os cartões que devem ser autorizados colocados um após o outro próximo ao módulo, você obterá o ID de cada um como xxxxxxxx (907a4F87), Se tivermos 7 tags, teremos 7 ID de oito bits.
// agora para sete cartas vai como // char ADMIT = {{(0x90), (0x7a), (0x4F), (0x87)}, // alocação de memória para mostrar o ID enviado por módulo int i = 0; voto interno = 0; int k = 0; send_a_command (0x01); // Limpar tela 0x01 = 00000001 _delay_ms (50); send_a_command (0x38); // informando ao lcd que estamos usando o modo de comando / dados de 8 bits _delay_ms (50); send_a_command (0b00001111); // TELA LCD LIGADA e cursor piscando char MEM; // alocando memória para armazenar a ID completa da tag send_a_string ("RFID NUMBER"); // envio de string send_a_command (0x80 + 0x40 + 0); // movendo o cursor para a segunda linha enquanto (1) { enquanto (! (UCSRA & (1 <
{ } COUNTA = UDR; // UDR armazena os dados de oito bits recebidos e é considerado um inteiro. MEM = COUNTA; // os primeiros dois caracteres são atualizados para a memória itoa (COUNTA, SHOWA, 16); // comando para colocar o número da variável no LCD (número da variável, em qual caractere substituir, qual base é variável (dez aqui, pois estamos contando o número na base 10)) send_a_string (SHOWA); // dizendo ao display para mostrar o caractere (substituído pelo número variável) da segunda pessoa após posicionar o cursor no LCD enquanto (! (UCSRA & (1 <
{ } COUNTA = UDR; itoa (COUNTA, SHOWA, 16); send_a_string (SHOWA); MEM = CONT.valores; // terceiro e quarto caracteres são atualizados para a memória enquanto (! (UCSRA & (1 <
{ } COUNTA = UDR; itoa (COUNTA, SHOWA, 16); send_a_string (SHOWA); MEM = COUNTA; // quinto e sexto caracteres são atualizados para a memória enquanto (! (UCSRA & (1 <
{ } COUNTA = UDR; itoa (COUNTA, SHOWA, 16); send_a_string (SHOWA); MEM = COUNTA; // sétimo e oito caracteres são atualizados para a memória send_a_string (""); send_a_command (0x80 + 0x40 + 0); UCSRB & = ~ (1 <
para (i = 0; i <5; i ++) { if ((MEM == ADMIT) & (MEM == ADMIT) & (MEM == ADMIT) & (MEM == ADMIT)) {// verificação de compra de autorização comparando dois personagens por vez com os personagens na memória PORTB - = (1 <
vote = 1; // se autorizado definir VOTE } } if (vote == 0) // autorização falhou se o voto não foi definido { UCSRB - = (1 <
} while (vote == 1) // faz este loop até votar, se autorizado { send_a_command (0x80 + 0); // ir para a posição zero na linha 1 send_a_string ("VOTE AGORA"); // exibindo string if (bit_is_clear (PINB, 0)) // quando o botão um é pressionado { VOTEA ++; // incrementa a memória do voto da primeira pessoa em um vote = 0; // deixando o loop while após a votação } if (bit_is_clear (PINB, 1)) // quando o botão 2 é pressionado { VOTEB ++; // incrementa a memória de voto da 2ª pessoa em um vote = 0; } if (bit_is_clear (PINB, 2)) // quando o botão 3 é pressionado { VOTEC ++; // incrementa a memória de voto da 3ª pessoa em um vote = 0; } if (bit_is_clear (PINB, 3)) // quando o botão 4 é pressionado { VOTED ++; // incrementa a memória de votos da 4ª pessoa em um vote = 0; } if (vote == 0) // limpo após o voto recebido { send_a_command (0x80 + 0); // mover para a posição zero da linha1 send_a_string ("THANK U FOR VOTE"); // exibir string para (k = 0; k <10; k ++) { _delay_ms (220); } PORTB & = ~ (1 <
send_a_command (0x01); send_a_command (0x80 + 0); // exibindo votos de todas as quatro pessoas send_a_string ("A ="); send_a_command (0x80 + 2); itoa (VOTEA, A, 10); send_a_string (A); send_a_command (0x80 + 8); send_a_string ("B ="); send_a_command (0x80 + 10); itoa (VOTEB, B, 10); send_a_string (B); send_a_command (0x80 + 0x40 + 0); send_a_string ("C ="); send_a_command (0x80 + 0x40 + 2); itoa (VOTEC, C, 10); send_a_string (C); send_a_command (0x80 + 0x40 + 8); send_a_string ("D ="); send_a_command (0x80 + 0x40 + 10); itoa (VOTADO, D, 10); send_a_string (D); send_a_command (0x80 + 0x40 + 16); para (k = 0; k <25; k ++) { _delay_ms (220); } UCSRB - = (1 <
send_a_command (0x01); send_a_command (0x80 + 0); // movendo para a posição zero send_a_string ("RFID NUMBER"); // enviar uma string send_a_command (0x80 + 0x40 + 0); } } void send_a_command (comando unsigned char) { PORTA = comando; PORTD & = ~ (1 <
PORTD - = 1 <
_delay_ms (50); PORTD & = ~ 1 <
PORTA = 0; } void send_a_character (caractere sem sinal) { PORTA = personagem; PORTD - = 1 <
PORTD - = 1 <
_delay_ms (50); PORTD & = ~ 1 <
PORTA = 0; } void send_a_string (char * string_of_characters) { enquanto (* string_de_caracteres> 0) { send_a_character (* string_of_characters ++); } } |