Sunday, June 28, 2015

RFID for Intel Edison

The following example shows how to connect an ID-20LA RFID reader (125 kHz) to an Intel Edison and read RFID tags. This example reads RFID cards using a relatively simple program written in C. To keep things simple, the program just reads the card and prints the number to the terminal window.  Using a Sparkfun RFID USB Reader board makes connecting the RFID reader very easy (using the serial hookup on the board instead of the USB connection).  On the Edison side, the connection is via the UART1 pins provided by the Sparkfun GPIO block for Edison (included in the starter pack for Edison).

Connections 


Note that the UART1 pins on the GPIO block connect to the Linux serial port device /dev/ttyMFD1. (See this post for information on the Edison's serial ports.)

RFID Reader Board Edison GPIO Block(UART1)
GND               GND
TXR               GP131/TX
TX                GP130/RX
VCC               3.3v

C Code


#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>

/* Edison's UART1 connects to /dev/ttyMFD1 */
#define SERIAL_DEV "/dev/ttyMFD1"

/* baudrasettings are defined in <asm/termbits.h>, which is
   included by <termios.h>. Change as needed, keep B 
*/
#define BAUDRATE B9600

/* POSIX compliant source */
#define _POSIX_SOURCE 1

// Function declarations
void configPins();
int openSerial(const char *);
void handleSIGINT(int);

/* Declare variable for original serial port settings here
   so it can be accessed from handleSIGINT function 
*/
struct termios savedTio;

/* Make descripter for serial connection global so
   handleSIGINT() can access it to restore original serial
   settings when program ends. 
*/ 
int serialHandle;

// Set loop that reads serial port to run indefinitely
int run = 1; 

int main() {
   int fd, c, res;
   char buf[255];

   printf("\nScan a tag to see its ID number. Press ctrl-c to quit.\n\n");

   // Program runs until user presses ctrl-c
   signal(SIGINT, handleSIGINT);
   
   serialHandle = openSerial(SERIAL_DEV);

   /* Loop continuously to handle serial input */
   while (run) {     
      /*  read blocks program execution until a line terminating character is
          input, even if more than 255 chars are input. If the number
          of characters read is smaller than the number of chars available,
          subsequent reads will return the remaining chars. res will be set
          to the actual number of characters actually read. 
      */
      res = read(serialHandle, buf, 255);
      /* set end of string, so we can printf */
      buf[res] = 0;
      printf("%s", buf, res);
   }
}

// Configure & open serial port.
int openSerial(const char *serial) {
   struct termios tio;
   /* Open device for reading and writing and not as controlling tty
      because we don't want to get killed if linenoise sends CTRL-C. */
   int fd = open(serial, O_RDWR | O_NOCTTY );
   if (fd < 0) { 
      printf("\nError opening %s.\n", serial); 
      exit(1); 
   }
   /* save current serial port settings to global var so they can be 
      restored when the program ends (see handleSIGINT). . 
   */
   tcgetattr(fd, &savedTio);
   /* clear struct for new port settings */
   memset(&tio, 0, sizeof(tio));

   /* CRTSCTS : output hardware flow control
      CS8     : 8n1 (8bit,no parity,1 stopbit)
      CLOCAL  : local connection, no modem contol
      CREAD   : enable receiving characters 
   */
   tio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD;

   /* IGNPAR  : ignore bytes with parity errors
      otherwise make device raw (no other input processing) 
   */
   tio.c_iflag = IGNPAR;

   /*  Raw output  */
   tio.c_oflag = 0;

   /* ICANON  : enable canonical input disable all echo functionality, and 
      don't send signals to calling program 
   */
   tio.c_lflag = ICANON;
   /* now clean serial line & activate settings for the port */
   tcflush(fd, TCIFLUSH);
   tcsetattr(fd,TCSANOW, &tio);
   return fd;
}

// Function to clean up & end program when user presses ctrl-C
void handleSIGINT(int signum) {
   char *gpio[] = {"4", "40", "41"};
   char path[30];
   tcsetattr(serialHandle, TCSANOW, &savedTio);
   printf("\nProgram ending...\n");
   // Export ports for sysfs access
   int fd = open("/sys/class/gpio/unexport", O_WRONLY);
   int c;
   for(c = 0; c < 3; c++) {
      write(fd, gpio[c], strlen(gpio[c]));
   }
   close(fd);
   exit(0);
}

No comments:

Post a Comment