RFID - 기판 수령, 분석
내장형 하드웨어/RFID / 2011. 11. 1. 11:02
→ 5개의 선이 stream 안테나에서 본체(회로)에 연결
→ CPU내에 여러 회로가 내장되어있다. 여러 칩들이 큰 플라스틱에 쌓여있다.
→ 스피커는 PWM으로 연주 가능
→ 케페시터 - SMD(Surface Mount Device) type
※ SMD
→ 기본적으로 고주파에 강하며, 잡음을 적게 탄다.
→ 반대로 SMD type이 아닌 저항등은 잡음을 흡수한다.
→ 잡음을 타면 안되기 때문에 SMD type을 사용한다.(가격이 10배 높다.)
→ LED 두개, 스피커 한개의 제어가 가능하다.(시리얼 통신으로, 펌웨어가 제공하는 한도내에서)
→ 우리가 사용하는 카드를 확인하면 3A Logics(RFID 칩 만드는 회사)
※ 시리얼 통신 선에서 3개는 데이터 송수신(Tx, Rx, GND), 나머지는 전원 공급이 가능하도록 되어있다. 우리가 사용하는 RFID 회로에는 전원공급을 할 수 있는 장치가 없기 때문에 이를 이용해서 전원을 공급하여야 한다.
→ 위의 사진은 스트리밍 안테나이다. 간단하며 기능이 떨어지나 가격이 저렴하다.
→ 아래의 카드는 RFID가 정보를 읽을 카드이다.
→ 전체 사진
- 이제 이 기기를 linux의 시리얼 통신 소스를 수정하여 실행시켜 본다.
#include<stdio.h>
#include<fcntl.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<termios.h>
#include<sys/signal.h>
#include<unistd.h>
#define CRC_POLYNOM 0X8408
#define CRC_PRESET 0xFFFF
//#define SPEED B19200
#define SPEED B38400
#define COMPORT1 "/dev/ttyS0" //
void Input_Incomming(int);
void Output_Incomming(int);
void my_signal(int arg); // 시그널 처리 함수
char cBuff[255]; // 수신용 버퍼
volatile int iBreak = 0;
int iRet;
int iCom1 = 0;
struct termios stOldSt1; // 기존 Serial Port1 상태 정보
unsigned char cArr[13]={0x0d,0x00,0x71,0x00
,0x3f,0x00,0x00,0x00
,0xa0,0x00,0x00,};
unsigned int cnt = 11;
unsigned short CRC16(void * DATA, unsigned int cnt);
int main()
{
int iMaxFD = 0;
unsigned short crc;
unsigned int iCnt;
struct termios stNewSt1; // 새로운 Serial Port1 상태 정보
struct sigaction act; // sigaction 구조체 변수 선언
fd_set stRFd; // file descriptor set
crc = CRC16(cArr, sizeof(cArr)-2);
printf("%02X\n", crc);
*((unsigned short*)(cArr+11)) = crc;
// 읽기,쓰기 모드로 모뎀장치를 연다.(O_RDWR)
// 데이터 전송시에 CTRL+C 문자가 오면 프로그램이 종료되지 않도록
// 하기 위해 controlling tty가 안되도록 한다.(O_NOCTTY)
iCom1 = open(COMPORT1, O_RDWR|O_NOCTTY); // 시리얼 포트 오픈
if(0 > iCom1) // 시리얼 포트1 오픈 에러
{
perror(COMPORT1);
exit(-1);
}
bzero(&act, sizeof(act));
act.sa_handler = my_signal; // 시그널 처리 함수
act.sa_flags = 0;
sigaction(SIGINT, &act, 0); //
// save current serial port setting
tcgetattr(iCom1, &stOldSt1);
// clear struct for new port setting
bzero(&stNewSt1, sizeof(stNewSt1));
// CS8-8N1(8bit, no parity, 1 stop bit), CLOCAL-local connection,
// CREAD - 문자수신을 가능하게 한다.
// PARENB - 짝수 페리티
stNewSt1.c_cflag = SPEED|CS8|CLOCAL|CREAD|PARENB;
// IGㄲNL - Parity 에러가 있는 문자 바이트를 무시.
stNewSt1.c_iflag = IGNPAR;
stNewSt1.c_cc[VMIN] = 1; // read시 리턴되기 위한 최소 문자 개수 지정
// 시리얼 포트 라인을 초기화 하고 포트 세팅을 마친다.
tcflush(iCom1, TCIFLUSH); // 시리얼 포트 수신 큐 초기화
tcsetattr(iCom1, TCSANOW, &stNewSt1); // 시리얼 포트에 새 속성 적용
iMaxFD = iCom1 + 1;
while(1)
{
// Set Descriptor
FD_ZERO(&stRFd);
FD_SET(iCom1, &stRFd);
FD_SET(0, &stRFd);
// block until input
select(iMaxFD, &stRFd, NULL, NULL, NULL);
if(iBreak == 1)
{
break;
}
// 입력을 받는다.
if(FD_ISSET(iCom1, &stRFd))
{
Input_Incomming(iCom1);
}
// 키보드 입력을 보낸다.
if(FD_ISSET(0, &stRFd))
{
// memset(cBuff, 0, 255);
// iRet = read(0, cBuff, sizeof(cBuff));
// cBuff[iRet] = 0;
write(iCom1, cArr, *cArr);
}
}
tcsetattr(iCom1, TCSANOW, &stOldSt1); // 시리얼 포트의 원래 속성 복귀
close(iCom1); // 시리얼 포트 닫음
printf("End program\n"); // End main()
return 0;
}
void Input_Incomming(int iCom1)
{
int iCnt=0;
iRet = read(iCom1, cBuff, 255); // 시리얼 포트로 부터 데이터 수신
while(iRet>iCnt)
{
printf(" %02X ", *(cBuff+iCnt)); // hex 값을 표시하겠다.
++iCnt;
if(0 == (iCnt%16)) // 16개마다 개행하겠다.
{
putchar('\n');
}
}
putchar('\n');
putchar('\n');
return ;
}
void Output_Incomming(int iCom1)
{
return ;
}
void my_signal(int arg)
{
iBreak = 1;
printf("\nCtrl-C pressed\n");
tcsetattr(iCom1,TCSANOW,&stOldSt1);
close(iCom1);
return ;
}
unsigned short CRC16(void *P, unsigned int cnt)
{
unsigned char *DATA = P;
unsigned int i;
unsigned int j;
unsigned short crc = CRC_PRESET;
// cnt = number of protocol bytes withdout CRC
for(i=0;i<cnt;++i)
{
crc = crc^DATA[i];
for(j=0;j<8;++j)
{
if(crc&0x0001)
{
crc = (crc>>1)^CRC_POLYNOM;
}
else
{
crc = (crc>>1);
}
}
}
return crc;
}
#include<fcntl.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<termios.h>
#include<sys/signal.h>
#include<unistd.h>
#define CRC_POLYNOM 0X8408
#define CRC_PRESET 0xFFFF
//#define SPEED B19200
#define SPEED B38400
#define COMPORT1 "/dev/ttyS0" //
void Input_Incomming(int);
void Output_Incomming(int);
void my_signal(int arg); // 시그널 처리 함수
char cBuff[255]; // 수신용 버퍼
volatile int iBreak = 0;
int iRet;
int iCom1 = 0;
struct termios stOldSt1; // 기존 Serial Port1 상태 정보
unsigned char cArr[13]={0x0d,0x00,0x71,0x00
,0x3f,0x00,0x00,0x00
,0xa0,0x00,0x00,};
unsigned int cnt = 11;
unsigned short CRC16(void * DATA, unsigned int cnt);
int main()
{
int iMaxFD = 0;
unsigned short crc;
unsigned int iCnt;
struct termios stNewSt1; // 새로운 Serial Port1 상태 정보
struct sigaction act; // sigaction 구조체 변수 선언
fd_set stRFd; // file descriptor set
crc = CRC16(cArr, sizeof(cArr)-2);
printf("%02X\n", crc);
*((unsigned short*)(cArr+11)) = crc;
// 읽기,쓰기 모드로 모뎀장치를 연다.(O_RDWR)
// 데이터 전송시에 CTRL+C 문자가 오면 프로그램이 종료되지 않도록
// 하기 위해 controlling tty가 안되도록 한다.(O_NOCTTY)
iCom1 = open(COMPORT1, O_RDWR|O_NOCTTY); // 시리얼 포트 오픈
if(0 > iCom1) // 시리얼 포트1 오픈 에러
{
perror(COMPORT1);
exit(-1);
}
bzero(&act, sizeof(act));
act.sa_handler = my_signal; // 시그널 처리 함수
act.sa_flags = 0;
sigaction(SIGINT, &act, 0); //
// save current serial port setting
tcgetattr(iCom1, &stOldSt1);
// clear struct for new port setting
bzero(&stNewSt1, sizeof(stNewSt1));
// CS8-8N1(8bit, no parity, 1 stop bit), CLOCAL-local connection,
// CREAD - 문자수신을 가능하게 한다.
// PARENB - 짝수 페리티
stNewSt1.c_cflag = SPEED|CS8|CLOCAL|CREAD|PARENB;
// IGㄲNL - Parity 에러가 있는 문자 바이트를 무시.
stNewSt1.c_iflag = IGNPAR;
stNewSt1.c_cc[VMIN] = 1; // read시 리턴되기 위한 최소 문자 개수 지정
// 시리얼 포트 라인을 초기화 하고 포트 세팅을 마친다.
tcflush(iCom1, TCIFLUSH); // 시리얼 포트 수신 큐 초기화
tcsetattr(iCom1, TCSANOW, &stNewSt1); // 시리얼 포트에 새 속성 적용
iMaxFD = iCom1 + 1;
while(1)
{
// Set Descriptor
FD_ZERO(&stRFd);
FD_SET(iCom1, &stRFd);
FD_SET(0, &stRFd);
// block until input
select(iMaxFD, &stRFd, NULL, NULL, NULL);
if(iBreak == 1)
{
break;
}
// 입력을 받는다.
if(FD_ISSET(iCom1, &stRFd))
{
Input_Incomming(iCom1);
}
// 키보드 입력을 보낸다.
if(FD_ISSET(0, &stRFd))
{
// memset(cBuff, 0, 255);
// iRet = read(0, cBuff, sizeof(cBuff));
// cBuff[iRet] = 0;
write(iCom1, cArr, *cArr);
}
}
tcsetattr(iCom1, TCSANOW, &stOldSt1); // 시리얼 포트의 원래 속성 복귀
close(iCom1); // 시리얼 포트 닫음
printf("End program\n"); // End main()
return 0;
}
void Input_Incomming(int iCom1)
{
int iCnt=0;
iRet = read(iCom1, cBuff, 255); // 시리얼 포트로 부터 데이터 수신
while(iRet>iCnt)
{
printf(" %02X ", *(cBuff+iCnt)); // hex 값을 표시하겠다.
++iCnt;
if(0 == (iCnt%16)) // 16개마다 개행하겠다.
{
putchar('\n');
}
}
putchar('\n');
putchar('\n');
return ;
}
void Output_Incomming(int iCom1)
{
return ;
}
void my_signal(int arg)
{
iBreak = 1;
printf("\nCtrl-C pressed\n");
tcsetattr(iCom1,TCSANOW,&stOldSt1);
close(iCom1);
return ;
}
unsigned short CRC16(void *P, unsigned int cnt)
{
unsigned char *DATA = P;
unsigned int i;
unsigned int j;
unsigned short crc = CRC_PRESET;
// cnt = number of protocol bytes withdout CRC
for(i=0;i<cnt;++i)
{
crc = crc^DATA[i];
for(j=0;j<8;++j)
{
if(crc&0x0001)
{
crc = (crc>>1)^CRC_POLYNOM;
}
else
{
crc = (crc>>1);
}
}
}
return crc;
}
- 동작 동영상