Hardware
Como vimos anteriormente, o leitor requer somente três conexões, nos pinos +5, GND e D0. Estas conexões serão feitas na barra de pinos da placa JY-MEGA32. As duas primeiras são óbvias (Vcc e GND), a terceira requer uma olhada no datasheet do ATmega32, para descobrir que o sinal Rx da USART é compartilhado com PD0.
Um outro detalhe não óbvio é que o sinal PD0 está ligado na placa ao conector USB (isto pode ser verificado no esquema da placa, que está nos arquivos do blog). Se o leitor e o cabo USB estiverem conectados simultaneamente, a comunicação com o leitor não será confiável. Após a carga do firmware é recomendável alimentar a placa ligando a alimentação por um dos outros conectores. No meu caso, usei o conector de programação SPI.
Software
Para este teste vamos acender os LEDs com os tags. O objetivo é associar cada tag a um LED. Incialmente não temos nenhuma associação; quando um novo tag é detectado, o próximo LED é associado a ele (desde que ainda tenhamos LEDs não associados). Quando um tag conhecido é detectado, o LED correspondente é aceso.
Para facilitar as coisas, os ids dos tags são convertidos em valores binários de 32 bits. Uma tabela de 8 posições guarda os ids dos tags conhecidos, o valor zero indica que a posição da tabela esta livre. Cada posição da tabela corresponde a um LED.
O ponto principal neste teste é a comunicação entre o leitor e o ATmega. O ATmega32 possui uma USART, que é programada com os parâmetros adequados (comunicação assíncrona no formato 8N1, a 9600bps). É também habilitada a interrupção de recepção:
// Programa a USART para 9600 8N1 UCSRA = _BV(U2X); // para maior resolução do baud rate UCSRB = _BV(RXEN)|_BV(RXCIE); // liga recepção, com interrupção UCSRC = _BV(URSEL)|_BV(UCSZ1)|_BV(UCSZ0) ; // 8bit, 1 stop, sem paridade UBRRL = (CLK_CPU / (8 * 9600UL)) - 1; // 9600 bpsA rotina de interrupção utiliza uma pequena máquina de estados para conferir o formato da mensagem e armazenar o id do tag. Ao converter o id para binário eu considerei a possibilidade de vir um número hexadecimal (apesar dos meus testes terem sempre apresentado um número decimal). Recebida uma mensagem correta, o id do tag é colocado em uma variável global, desde que ela esteja livre (com zero).
// Último tag detectado volatile uint32_t tagLido; // Lista de tags conhecidos volatile uint32_t tags[8]; // Interrupção de recepção da USART ISR(USART_RXC_vect) { static uint8_t estado = 0; static uint32_t idTag; uint8_t c; c = UDR; if (bit_is_clear(UCSRA, FE)) { // recebeu caracter sem erro if (estado == 0) { // Aguardando o STX if (c == 0x02) { estado = 1; idTag = 0; } } else if (estado == 9) { // Aguardando o ETX if (c == 0x03) { // Recebeu ID com sucesso tagLido = idTag; } estado = 0; } else { // recebeu um dígito, vamos tratar como hexadecimal if ((c >= '0') && (c <= '9')) idTag = (idTag << 4) | (c & 0xF); else if ((c >= 'A') && (c <= 'F')) idTag = (idTag << 4) | (c - 'A' + 10); else if ((c >= 'a') && (c <= 'f')) idTag = (idTag << 4) | (c - 'a' + 10); else estado = 0xFF; estado++; } } else estado = 0; }O programa principal fica monitorando a variável global que indica a detecção de um tag. Quando esta variável deixa de ser zero, indica que um tag foi detectado. O tag é então procurado na tabela, se achado o LED correspondente é aceso. Se o tag não estiver na tabela, e ela não estiver cheia, ele é acrescentado ao final. Em seguida a variável é retornada a zero, para indicar que está pronto para tratar uma nova leitura.
for (;;) { if (tagLido != 0) { int i; // Procura nos conhecidos for (i = 0; (i < 8) && (tags[i] != 0); i++) { if (tags[i] == tagLido) { // achou, acende o LED correspondente LED_PORT = 1 << i; break; } } if ((i < 8) && (tags[i] == 0)) { // Não encontrou e tem espaço, coloca na lista tags[i] = tagLido; LED_PORT = 1 << i; } tagLido = 0; } //if (TIFR & _BV(OCF1A )) //{ // TIFR = _BV(OCF1A ); // Limpa indicação do timer // LED_PORT ^= 0x80; //} } }Teste
O vídeo abaixo mostra o sistema em funcionamento. Cinco tags (três cartões e dois chaveiros) são apresentados primeiro em ordem e depois aleatoriamente. Para facilitar, os tag estão identificados com o número do LED correspondente.
Nenhum comentário:
Postar um comentário