Home - Search - Members
Full Version: EM4001 RF Card Reader based on Access Control System
Morris
Sep 19 2009, 11:08 AM
Hi,
I was making a project of RF Card Reader with PIC12F629.
The microcontroller's tasks are as following:
1) IO simulate RS232 communication only for sending a package with 15 bytes
2) Receiving data from U2270B which is a RFID read/write base station
3) Sending the real card no. as a RS232 package form
The rom & ram size have been occupied 90% approximately.
When the device was running, reading card no. is right,
but the head 2 bytes of package were always 0, and the other bytes were right.
Why? the head 2 bytes i only defined at the first, and never changed them.
i defined : unsigned char RS232_buffer[15]={0x3C,0x0f,0,0,0,0x02,0,0,0,0,0,0,0,0,0x82};
Who can help me?

Finally i apologized that i have left for a long time,
because the world financial crisis affected me in this second quarter
But i will always support RICKEY'S WORLD.



Ajay Bhargav
Sep 22 2009, 4:17 PM
Hi morris welcome back..
are you talkin about a finished project or a project to be done yet?
coz 90% space for that much project seems too high to me.

Morris
Sep 22 2009, 9:18 PM
Hi,Ajay
Not finished project.i have planned and the systme included as below:
1). RF CardReader
2). Main Controller between CardReader & PC
3). PC Software for recorder
The first step i had to make the CardReader.but it was running wrongly.
Later on i'll attach its code and circuit diagram after i arrange and clean up them.

Ajay Bhargav
Sep 23 2009, 7:03 AM
you are using EM4001 RFID card reader so it wont be a problem to make it work. connect reader to PC serial port, see how response comes in what format etc. or simply check datasheet if you have.

which controller are you plannin to use?
Morris
Sep 23 2009, 9:22 AM
Although the card reader can work,the first 2 bytes of a package(15bytes)
are always wrong.:(
i attached the schematics & code as below.
i think the code is very very pell-mell due to i was in a hurry.
If you have any question or problem, i will check&make it up again.


//------------------------------------------------------------------------------------------
#include "pic12f6x.h"
#include "pic.h"
#include "math.h"
#include "string.h"
#include "BusProtocol.h"

#ifndef uchar
#define uchar unsigned char
#endif
#ifndef uint
#define uint unsigned int
#endif

#ifndef ERROR
#define ERROR 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif

#define PRELOAD_RS232 0x3D //2400baud
#define RFID_PERIOD 0x37 //200us

#define TXD GPIO2
#define RFID_DATA GPIO4

#define Enable_RFID_EX() IOCB4=1;GPIF=0;GPIE=1
#define Disable_RFID_EX() IOCB4=0;GPIF=0;GPIE=0
#define OnRFID() GPIO5=1
#define OffRFID() GPIO5=0

static volatile uchar ucTick0=0;
static volatile uchar count=0,t_count=0;
static volatile uchar RFCount=0;

static volatile bit RFBit=0; //Port Voltage Level Changed Interrupt Flag
static volatile bit StartRec=0; //1: Start Receive
static volatile bit RFID_IN=0; //RFID Data Input
static volatile bit Send_FLAG=0; //Send package Flag
//static volatile bit bSent=FALSE; //1: already sent a package
static volatile bit TM0_FLAG=0; //Timer 0 Overflow Interrupt

//16 bytes to receive 128 bits RFID data
uchar RFID_Buffer[16]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};

//15 bytes for Rs232 package
uchar RS232_Buffer[15]={0x3C,0x0F,0x00,0x00,0x00,0x02,0xBB,0x00,0x00,0,0,0,0,0,0x82};;

bit SendTo(volatile uchar *str);
void RS232SendEnd(void);
void Lmove_bite(void);
bit find_head(void);
void get_data(void);
bit Data_L_check(void);
bit Data_R_check(void);
void Get_EffectData(uchar edata);
bit Data_Sever(void);
void Data_receive(void);
bit ReadRFID(void);
void WaitTF0(void);

void DelayUs(uint i)
{
while(i--);
}
void DelayMs(uint j)
{
while(j--)
{
DelayUs(200);
}
}
//-----------------------------------------------------
void interrupt
ISR(void) //@ 0x10
{
if(GPIE==1 && GPIF==1)
{
RFBit = 1;
if(!StartRec)
{
if(RFCount == 2)
{
StartRec = 1;
}
TMR0 = RFID_PERIOD;
RFCount = 0;
}
GPIO = GPIO;
GPIF = 0;
}

if(T0IE==1 && T0IF==1)
{
T0IF=0;
if(!Send_FLAG)
{
TMR0 = RFID_PERIOD;
RFCount++;
if(RFCount > 9)RFCount = 0;
}
else TMR0 = PRELOAD_RS232;
ucTick0++;
if(ucTick0==2)
{
ucTick0=0;
TM0_FLAG = 1;
}
}
}
/*********************************************
Function Name:Lmove_bite
Description: Rotate 1 bit left for 128 bits
*********************************************/
void Lmove_bite(void)
{
uchar temp;
uchar tempData0=0 ;
for(temp=0 ; temp<0x10 ; temp++ )
{
if( temp == 0 ){ tempData0 = ( (RFID_Buffer[0]&0x01) <<7 ) ;}
if( temp == 0x0f ){ RFID_Buffer[temp] =( (RFID_Buffer[temp]>>1) | tempData0 ) ; }
else {RFID_Buffer[temp] = ( (RFID_Buffer[temp]>>1) | ( (RFID_Buffer[temp+1]&0x01) <<7 ) ) ;}
}
}
/*******************************************
Function Name:find_head
Description: find 9 bits of '1' of head
1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0
********************************************/
bit find_head(void)
{
uchar *pRFID = &RFID_Buffer;
for(count=0;count<128;count++)
{
if( (pRFID[0]==0x55) && (pRFID[1]==0x55) && ((pRFID[2]&0x03)==0x01)\
&&((pRFID[15]&0xC0)==0x80)){return 1;}
else {Lmove_bite();}
}
return 0 ;
}
/*******************************************
Function Name: get_data
Description: Sort effective 55 bits out except for the head of 128bits
********************************************/
void get_data(void)
{
uchar *Read_Buffer = &RFID_Buffer;
uchar c1,c2,c3,t1;
for( count=0 ,t_count=0 ; count <= 126 ; )
{
c1 = count+18;
c2 = c1/8;
c3 = c1+1;
t1 = t_count/8;
if(( Read_Buffer[c2]&(0x01<<(c1%8)))>(Read_Buffer[(c3/8)]&(0x01<<(c3%8)))) //1
{ Read_Buffer[t1] = ( Read_Buffer[t1] | ( 0x01 << (t_count%8) ) ) ; }
else//if(( Read_Buffer[c2]&(0x01<<(c1%8)))<( Read_Buffer[(c3/8)]&(0x01<<(c3%8)))) //0
{ Read_Buffer[t1] = ( Read_Buffer[t1] & ( ~ ( 0x01 << (t_count%8) ) ) ) ; }
t_count++;
count=count+2;
}
}
/*********************************************
Function Name:Data_L_check
Description: Column Data Check
********************************************/
bit Data_L_check(void)
{
uchar temp;
uchar *Read_Buffer = &RFID_Buffer;
for(count=0 ; count < 0x04 ; count++)
{
temp = 0 ;
t_count = count ;
for( ; t_count <= 53 ; )//0x37 ; )
{
if( ( Read_Buffer[(t_count/8)] & (0x01<<(t_count%8)) ) )//>> (t_count%8) )
{
temp ++ ;
}
t_count += 5 ;
}
if((temp%2)!= 0)
{
return 0 ; //Column Check Error
}
}
return 1 ;
}
/*********************************************
Function Name:Data_R_check
Description: Row Check
********************************************/
bit Data_R_check(void)
{
uchar temp,sum=0;
uchar *Read_Buffer = &RFID_Buffer;
uchar t_buf[5];
uchar m;
count=39;
for(t_count=0 ; t_count<= 45 ; )//0x32 ; )
{
for(temp=0;temp<5;temp++)
{
m = t_count + temp;
t_buf[temp] = (( Read_Buffer[m/8] & (0x01<<(m%8))) >> (m%8)) ;
sum += t_buf[temp];
}
if((sum%2) == 0)
{t_count += 5 ;sum = 0;}
else
{return 0 ;} //Row Check Error
for(temp=0 ; temp<0x04 ; temp++ )
{
Get_EffectData( t_buf[temp] ) ;
count--;
}
}
return 1 ;
}
/*********************************************
Function Name:Get_EffectData
Description: Get real data of RFID card
*********************************************/
void Get_EffectData(uchar edata)
{
uchar *pRS232=&RS232_Buffer;
uchar m=9+(count/8);
uchar n=(1<<(count%8));
switch(edata)
{
case 1:
pRS232[m]|=n;
return ;
case 0:
pRS232[m] &= (~n);
return ;
}
}
/*********************************************
Function Name:ChangeToCardNo
Description: Change to recognizable card num for customer
*********************************************/
void ChangeToCardNo(void)
{
uchar *pRS232=&RS232_Buffer;
uchar temp1,temp2;
for(temp2=0;temp2<2;temp2++)
{
temp1 = pRS232[13-temp2];
pRS232[13-temp2] = pRS232[9+temp2];
pRS232[9+temp2] = temp1;
}
for(temp1=0;temp1<3;temp1++)
{
pRS232[10+temp1] = pRS232[11+temp1];
}
temp1 = 0;
for(temp2=2;temp2<13;temp2++)
{
temp1 ^= pRS232[temp2];
}
pRS232[13]=temp1;
}

/*********************************************
Function Name:Data_Sever
Description: RFID data service
0 : error 1 : right
*********************************************/
bit Data_Sever(void)
{
if(find_head() == 0 ) //find a right head of 128bits Manchester Code
{ return 0 ; }
get_data() ;
if(Data_L_check() == 0 )
{ return 0 ; }
if(Data_R_check() == 0 )
{ return 0 ; }
return 1 ;
}
/*********************************************
Function Name:WaitRFBit
Description: RFID data input port level changed
*********************************************/
//---------------------------------------------------
void WaitRFBit(void)
{
while(!RFBit);
RFBit = 0;
}
/*********************************************
Function Name:Data_Receive
Description: Receive RFID data
*********************************************/
void Data_Receive(void)
{
uchar temp=0;
uchar BitCount=0,Bptr=0;
uchar *pRFID = &RFID_Buffer;
for(BitCount=0;BitCount<128;)
{
if(RFCount<=1)//200us<time<400us (time=1 * 1/2T)
temp=1;
else if(RFCount==2||RFCount==3)temp=2; //400us<time<600us (time=2 * 1/2T)
TMR0=RFID_PERIOD;
RFCount=0;
RFID_IN = RFID_DATA;
for(count=0;count<temp;count++)
{
GIE = 0;
Bptr = BitCount/8;
t_count = pRFID[Bptr];
t_count >>= 1;
if(!RFID_IN)t_count |= 0x80;
else t_count &= 0x7F;
pRFID[Bptr] = t_count;
BitCount++;
GIE = 1;
}
WaitRFBit();
}
}
/*******************************************
Function Name: ReadRFID
Description: Wait to read RFID Card
********************************************/
bit ReadRFID(void)
{
while(!StartRec);
Data_Receive();
GIE = 0;
if( Data_Sever() )
{
ChangeToCardNo();
return TRUE;
}
else //Check Error
{
GIE = 1;
StartRec = 0; //restart to receive
return FALSE;
}
}
//--------------------------------------------------
//*********Internal RC oscillator Calibration*********/
void IntRC_Calibration(void)
{
#asm
bsf _STATUS,5
call 3FFH
movwf _OSCCAL
bcf _STATUS,5
#endasm
}
//----------------------------------------------------
void TMR0_Init(void)
{
ucTick0 = 0;
TM0_FLAG = 0;
TMR0 = RFID_PERIOD;
OPTION |= 0x08; //Prescale is assigned to WDT
T0IF = 0;
T0IE = 1;
}
//---------------------------------------------
void Port_Init(void)
{
TRISIO = 0x18;
OPTION = 0x80; //disable GPIO pull-up
GPIO = 0x3F;
CMCON = 0x07; //Digital IO , Compator Off
}
//-----------------------------------------------
void Devices_Init(void)
{
PIE1 = 0x00;
PIR1 = 0x00;
INTCON = 0x00;
GPIO = 0x00;
IOCB = 0x00;
GPIF = 0;
GPIO = GPIO;
Port_Init();
TMR0_Init();
DelayMs(10);
}
//-------------------------------
void main(void)
{
DelayMs(50);
IntRC_Calibration();
Devices_Init();

Send_FLAG = FALSE;
OnRFID();
Enable_RFID_EX();
while(1)
{
if(ReadRFID())
{
if(SendTo(RS232_Buffer));
else RS232SendEnd();
DelayMs(600);
}
}
}

//---------------------------------------------------------------------------------------------
/***********************IO simulate UART***********************/
void RS232SendInit(void)
{
GIE = 0;
Send_FLAG = TRUE;
Disable_RFID_EX();
T0IE = 0;
TMR0 = PRELOAD_RS232;
ucTick0 = 0;
TM0_FLAG = 0;
T0IF = 0;
GIE = 1;
}
void RS232SendEnd(void)
{
Send_FLAG = FALSE;
TMR0 = RFID_PERIOD;
T0IF = 0;
StartRec = 0;
RFCount = 0;
T0IE = 1;
Enable_RFID_EX();
}

void WaitTF0( void )
{
while(!TM0_FLAG);
TM0_FLAG=0;
}

bit WByte(uchar input)
{
uchar i=8;
T0IE = 1;
TXD = 0;
WaitTF0();
while(i--)
{
TXD = (bit)(input&0x01);
NOP();NOP();NOP();NOP();NOP();NOP();
if(TXD != (input&0x01))return ERROR;
WaitTF0();
input >>= 1;
}
TXD = 1;
WaitTF0();
T0IE = 0;
return TRUE;
}

//Send RS232 Package
bit SendTo(volatile uchar *str)
{
uchar i=15;
uchar temp;
RS232SendInit();
while(i--)
{
temp = str[16-i];
if(WByte(temp))DelayUs(500);
else return ERROR;
}
RS232SendEnd();
return TRUE;
}

ExperimenterUK
Sep 23 2009, 4:40 PM
What do you get if you just store the 15 bytes from the reader,
and what do you expect ?.
Morris
Sep 23 2009, 8:17 PM
I want to get a right&proper package,but the first 2 bytes always are '0'.Why?I never changed them.
Ajay Bhargav
Sep 24 2009, 2:57 AM
post link to datasheet of this reader module. coz i am not able to understand what you're doin there in code.
Morris
Sep 24 2009, 7:19 AM
Thank you , Ajay
The card reader is made by myself in a hurry so no datasheet.
If you still cann't understand it, Pls wait me to tidy up the code and make some relevant instruction.
ExperimenterUK
Sep 24 2009, 11:58 AM


I want to get a right&proper package,but the first 2 bytes always are '0'.Why?I never changed them.


Morris


I meant what stream of bits do you actually get, and what stream of bits would you expect to see
before doing any bit shifting etc.
Do you know what the data on the card is ?.
Morris
Sep 25 2009, 4:19 AM
1) the card reader get a RFID Card data (Function"Data_Receive" run right)
2) change RFID data to real Card Numbers (Function "Data_sever" run right)
at the same time ,the real Card Numbers saved in an array--- RS232_Buffer[15] (RS232_Buffer[15] run right or error?)
3) Send data of RS232_Buffer[15] to BUS (2 first bytes of RS232_Buffer[15] error!!!)

Manchester data in the card, and i have already gotten it rightly .

i don't know whether you understand my explanation as above or not?
Thanks, ExperimenterUK
ExperimenterUK
Sep 25 2009, 1:38 PM


i don't know whether you understand my explanation as above or not?

Morris



Actually i don't
The trouble is I'm not really sure what you mean by EM4001.
Is it the way the data is stored on the card, or way the data is sent,
or even the device you are using.
Can you supply a definition ?.

As far as I can tell EM4001 defines the way the data is stored as a block of data
bits on the card.

The U2270B seems to output this block as a stream of bits not bytes.
As I see it there are no stop/starts bits so it is not an RS232 type serial link.
Can you tell us exactly what your hardware is and how it works ?.
Morris
Sep 26 2009, 12:33 AM
Oh, My poor English! :blush
EM4001 data format as below to link
http://www.rfidtalk.com/showthread.php?t=832

The processing of reading & sending is as follwing
By the way,now i used pic12f629 instead of pic12c508
1) The GP5 port of MCU(PIC12F629) is for enabling U2270B
2) U2270B send a stream of bits to the GP4 port of MCU
3) MCU save the stream of bits to array(RFID_Buffer[16])
4) MCU process the data of RFID_Buffer[16] and get real card number
5) MCU save the card number to the appointed location of RS232_Buffer[15]
6) MCU send the data of RS232_Buffer[15] by the GP1 port TO a bus of RS232
Now the step 5 & 6 are error!!!
------------------------------------------------------------------
//sending a byte of RS232 is as following
bit WByte(uchar input)
{
uchar i=8;
T0IE = 1;
TXD = 0 ; //send the start bit of RS232 .the GP1 port defined at the first
WaitTF0(); //wait to finish the start bit
while(i--)
{
...
}
TXD = 1; //send the stop bit of RS232
WaitTF0(); //wait to finish the stop bit
T0IE = 0;
return TRUE;
}
------------------------------------------------------------------
Ajay Bhargav
Sep 26 2009, 8:45 AM
are you trying to do software uart??
is it of correct baud as your RFID reader?
Ajay Bhargav
Sep 26 2009, 8:45 AM
Morris
Sep 26 2009, 3:00 PM
Software uart. and it is correct baud.
i wonder if you think it has some problem?
ExperimenterUK
Sep 26 2009, 3:57 PM


Oh, My poor English! :blush

5) MCU save the card number to the appointed location of RS232_Buffer[15]
6) MCU send the data of RS232_Buffer[15] by the GP1 port TO a bus of RS232
Now the step 5 & 6 are error!!!

Morris


Your English is fine, it's just that you know your project in great detail,
and the rest of us know nothing about it.
Now I understand a lot better

Have you tried putting test bytes into the into RS232_Buffer and seeing if they are sent
correctly.
Have you tried putting test data into the into RFID_Buffer and seeing if it is sent
correctly.
Morris
Sep 27 2009, 2:09 AM
Thanks,ExpeimenterUK
I have already put the test data into RS232_Buffer but...
for example.Firstly, i defined RS232_Buffer[]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}
than putting 4 bytes into the 10th~13th location into RS232_Buffer.
Secondly, i send the RS232_Buffer to bus of RS232, but receive that the 2 first bytes of RS232_Buffer are always logic 0 number
I think that about 90% code maybe too large like what Ajab ever said.
How can i find out the error detail?
i don't know
ExperimenterUK
Sep 27 2009, 11:23 AM
Am I right in thinking you problem is in sending the data out over a serial link ?
If so remove all the other code and just concentrate on getting your software
uart working.

Fill a buffer with text "ABCDEFGH" etc and send it to a PC running
Hyperterminal or similar.

Morris
Sep 27 2009, 12:30 PM
1)---- i skipped or removed all other code besides softwar uart.
-------i filled the buffer with text "ABCDEFGHIJKLMNO" .
-------i received the right text data "ABCDEFGHIJKLMNO".
-------i am sure i used hyperterminal!
2)---- i didn't skip or remove any code. than the first 2 bytes all became digital 0.
-------i am sure i used hyperterminal as well!
ExperimenterUK
Sep 27 2009, 6:05 PM



2)---- i didn't skip or remove any code. than the first 2 bytes all became digital 0.
-------i am sure i used hyperterminal as well!

Morris


This may be a language thing, but you must know if you used Hyperterminal or not.

In case 2 did you send "ABCDEFGHIJKLMNO" .
Don't forget Hyperterminal can't display hex values such as 0x00, 0x01,0x02,0x03
Morris
Sep 27 2009, 9:51 PM
Oh,Sorry. i didn't remove all code. i didn't tell a lie that i may be too dizzy
I put the card number into the buffer.Only in this way can I receive the error information.
wait please... i will attach screenshots...and will tell you the error detail...
Morris
Sep 28 2009, 4:52 PM
Sorry,ExperimenterUK. I have already corrected my mistakes.
I have almost taken a whole night to do the testing work, due to i have never recorded the relevant information before.
It is no way to get a previous error status.
But the testing result can explain the error.
Please find the screenshots as below.
Ajay Bhargav
Oct 3 2009, 4:29 AM
Morris you have to upload the screenshots to put them in IMG tag.

you can use tinypic.com to upload your ../images.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Rickey's World © 2003 - 2007