RFID modules

Required knowledge: [HW] Kontrollermoodul, [HW] Kombomoodul, [AVR] USART, [LIB] Jadaliides

Theory

RFID is a technology for data exchange via radio waves between a reader and an electronic identity attached to an object for identification and tracking. RFID allows each object to be associated with a unique ID number. Passive tags without a battery can be read when passing close to the reader.

Mifare SL031 RFID module

The Mifare RFID module is a high-frequency RFID reader operating at 13.56 MHz. At the same frequency, many ID cards and RFID tokens used in Estonian schools and companies also work. The SL031 module connects to the controller board as follows:

  • VCC - supply + 3.3 V (from the Xbee interface of the communication board or the controller board header). Be sure not to use higher supply voltage. The module data pins tolerate + 5 V.
  • IN - to save power, the RFID module can be put to sleep by sending command 0x50. The module wakes up on a falling edge on IN.
  • TXD - connect to controller RXD (e.g., PE0 for USART0)
  • RXD - connect to controller TXD (e.g., PE1)
  • OUT - indicates whether an ID is detectable (card near the module, output low) or not (no card, output high)
  • GND - ground

When using USART0 to communicate with the RFID module, the RFID TXD/RXD pins must not be connected to the communication board during ISP programming, otherwise a conflict occurs and programming fails.

Default USART settings for SL031 are 115200-8-N-1-N. When connecting to a computer, if USART0 is used to communicate with the RFID module, the jumpers on the right header pair must be moved from Xbee to RS232_2 and the computer COM port connected to the RS232_2 connector on the communication board.

The data exchange format between the controller and the RFID module consists of several bytes in a fixed order. The first byte is always the same (0xBA when sent by the controller). The second byte indicates how many bytes follow and can be used to track when all data has been sent. The last byte is a checksum that allows verifying correct reception. Different commands are available to write/read memory, put the module to sleep, etc.

The example program sends a command to the RFID module every second to check for a nearby ID card. If found, it displays the unique card ID on the display. Each byte in the exchange is in hex and must be converted to ASCII characters for display.

Mifare SL031 example code

#include <homelab/usart.h>
#include <homelab/delay.h>
#include <homelab/pin.h>
#include <homelab/module/lcd_gfx.h>
 
usart port = USART(1);	//Mifare RFID connection
 
// Command to module - select card
// preamble, len, command, data, checksum
char SL031CMD_SelectCard[] = {0xBA,0x02,0x01,0xB9};
 
void hex_to_ascii(char *mass, char byte);
 
int main (void)
{
    char resp[14];
    char str[4];
    int a = 0;
    int bnr = 4;
 
    // USART1 setup
    usart_init_async(port,
	             USART_DATABITS_8,
                     USART_STOPBITS_ONE,
                     USART_PARITY_NONE,
                     USART_BAUDRATE_ASYNC(115200));
 
    // LCD initialization
    lcd_gfx_init();
 
    // Turn on backlight
    lcd_gfx_backlight(true);
 
    // Write text to screen
    lcd_gfx_goto_char_xy(3, 0);
    lcd_gfx_write_string("RFID Demo");
    lcd_gfx_goto_char_xy(0, 2);
    lcd_gfx_write_string("ID: ");
 
    while (1)	//infinite loop
    {
        // Send command to RFID module
        usart_send_string(port, SL031CMD_SelectCard);
 
        // Wait until response bytes arrive
        while (a < bnr)
	{
		// read from USART and store
		if (usart_try_read_char(port, &resp[a]))
		{
		     // next byte
                     a++;
                     // second byte shows how many bytes follow
                     if (a == 2) bnr = resp[1] + 2;
		}
	}
 
	// if no ID - "no tag" response
	if (resp[3] == 0x01)
	{
		// write it
		lcd_gfx_goto_char_xy(4, 2);
	    	lcd_gfx_write_string("missing   ");
	}
	// ID exists and is readable
	else
	{
		// view only ID bytes
		for (a=4; a<(bnr-2); a++)
		{
			// convert read data to string
			hex_to_ascii(str, resp[a]);
			// write to display
			lcd_gfx_goto_char_xy((a-2)*2, 2);
		    	lcd_gfx_write_string(str);
		}
	}
	// reset counters
	a = 0;
	bnr = 4;
	// refresh delay
	hw_delay_ms(1000);
    }
}
 
// Convert a hex byte to ASCII and store in string
void hex_to_ascii(char *mass, char byte)
{
	unsigned int high = 0;
 
	// find first hex digit
	while (byte > 0x0F)
	{
		high++;
		byte -= 0x10;
	}
	// first digit, hex to ASCII
	mass[0] = high + 0x30;
	// if letter
	if (mass[0] >= 0x3A) mass[0] += 0x07;
	// second digit, hex to ASCII
	mass[1] = byte + 0x30;
	if (mass[1] >= 0x3A) mass[1] += 0x07;
	// string terminator
	mass[2] = 0x00;
}

Parallax RFID module

The Parallax RFID module is a low-frequency RFID reader that operates at ~170 kHz.

Parallax RFID example code

The following code uses an RFID reader and LCD display.

// RFID reader with Interstudy ATmegal28 board
// Reader pins : Enable - PD3, Serout - PD2 (RXD1)
// Reads and displays ID
 
// Includes 
#include <avr/io.h> 
#include <util\delay.h> 
#include "lcd.h"
#include "pin.h"
 
// Configuration
#define RFID_BAUDRATE     2400
#define RFID_BAUD_VALUE   (((F_CPU / (RFID_BAUDRATE * 16UL))) - 1)
#define RFID_ENABLE       PORTPIN(D, 3)
#define RFID_RX           PORTPIN(D, 2)
#define LED_GREEN         PORTPIN(C, 3)
#define LED_DEBUG         PORTPIN(B, 7)
 
//
// Display initialization
//
void display_init(void)
{
	lcd_init(LCD_DISP_ON);
	lcd_clrscr();
	lcd_puts("  RFID reader\n waiting for ID");
}
 
//
// Write ID on display
//
void display_write_id(char *id)
{
	lcd_gotoxy(0, 0);
	lcd_puts("ID: "); 
	lcd_puts(id);
}
 
//
// UART configuring
//
void uart_setup()
{
	// Setup serial interface
	SET_BIT(UCSR1B, RXEN);   // Activate RX only
	SET_BIT(UCSR1C, UCSZ0);  // 8 data bits, 1 stop bit, no parity
	SET_BIT(UCSR1C, UCSZ1);
 
	// Set baud rate
	UBRR1L = (RFID_BAUD_VALUE & 0xFF);
	UBRR1H = (RFID_BAUD_VALUE >> 8);
}
 
//
// Wait for UART incoming data
//
void uart_wait_rx()
{
	while (!IS_BIT_SET(UCSR1A, RXC)) { }
}
 
//
// Read UART data
//
inline unsigned char uart_read()
{
	return UDR1;
}
 
//
// RFID interface initialization
//
void rfid_init(void)
{
	// Setup UART
	uart_setup();
 
	// Setup enable and RX pin
	pin_setup_output(RFID_ENABLE); 		
	pin_setup_input(RFID_RX);
}
 
//
// RFID ID reading
//
void rfid_read_id(char *id)
{
	enum States { BEGIN, DATA, END } state = BEGIN;
	unsigned char data;
	unsigned char digits = 0;
 
	// Enable RFID with low signal
	pin_clear(RFID_ENABLE);
 
	// Cycle until tag ID received
	while (1)
	{	 
 		// Wait for data
		uart_wait_rx();		
		data = uart_read();		
 
		// Toggle debug indicator
		pin_toggle(LED_DEBUG);
 
		// What's present state and what's next ? 
		switch (state)
		{
			// Begin state - we expect start byte (0x0A)
			case BEGIN:
				// Got the start ?
				if (data == 0x0A)
				{
					state = DATA;
 
					// Disable RFID
					pin_set(RFID_ENABLE);
				}
				break;
 
			// Data state - we expect 10 bytes of ID
			case DATA:
				// Fill ID string
				id[digits++] = data;				
 
				// All digits arrived ?
				if (digits == 10) state = END;
				break; 
 
			// End state - we expect end byte (0x0D)
			case END:
				// Got the end ?
				if (data == 0x0D)
				{
					// Terminate the string
					id[digits] = '\0'; 
 
					// All done - return
					return;					
				}
				// Any other case - restart
				else
				{
					state = BEGIN;
 
					// Enable RFID with low signal
					pin_clear(RFID_ENABLE);
				}
				break; 			
		}
	}
}
 
//
// Main function  
//
int main(void)
{
	char id[11];
 
	// Initialization
	display_init();
	rfid_init();
 
	// Setup indicator pins
	pin_setup_output(LED_GREEN); 
	pin_setup_output(LED_DEBUG);
 
 	// Endless loop
	while (1)
	{		
		// Turn off green LED
		pin_set(LED_GREEN);
 
		// Read RFID tag ID
		rfid_read_id(id);
 
		// Light green LED
		pin_clear(LED_GREEN);
 
		// Display ID	
		display_write_id(id);		
	}
} 
en/examples/communication/rfid.txt · Last modified: by 127.0.0.1
CC Attribution-Share Alike 4.0 International
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0