• Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

How to read RFID tag by ATmega32 using Codevision ?

Thread starter #1
Hey there, I wanna know how to write a code by Codevision for reading RF01D data...
I know I should use USART...that's all I know...
It's an ATmega 32 and RF01D
in first step what changes should I apply on Codewizard?
thanks
 

wkrug

Active Member
#3
I would make the buffer bigger.
I think 40Bytes are OK.

Cause:
You have to readout the buffer before it will be overwritten.
When the buffersize is to small You'll loose data.
It depends how many other tasks your controller has to compute.
delay commands should be avoided.
 
Thread starter #4
I would make the buffer bigger.
I think 40Bytes are OK.

Cause:
You have to readout the buffer before it will be overwritten.
When the buffersize is to small You'll loose data.
It depends how many other tasks your controller has to compute.
delay commands should be avoided.
thanks for your answer, but I really need more help ...I even don't know how to receive the data from it...
could you please tell me how I can write a code for it?
 

wkrug

Active Member
#5
I'm not really shure what a RF01D is.
A 433MHz Receiver or an RFID Card reader.
Do You have any link to a Datasheet?

The automatic programm generator will do this for you.
Start this tool.
Go to section USART and click on RX and TX field.
Additional click on RX Interrupt field and increase the Buffer Size to 40.
Then choose the comunication parameters.

You can also configure the other Periphals when You want to do this.

Now click on "Programm" -> Generate, Save and Exit.
Choose a Folder and a project name, an additional name was asked and save the Project.

4 importent Parts will be built automatic:
// USART0 Receiver buffer
#define RX_BUFFER_SIZE0 80
char rx_buffer0[RX_BUFFER_SIZE0];

#if RX_BUFFER_SIZE0<256
unsigned char rx_wr_index0,rx_rd_index0,rx_counter0;
#else
unsigned int rx_wr_index0,rx_rd_index0,rx_counter0;
#endif

// This flag is set on USART0 Receiver buffer overflow
bit rx_buffer_overflow0;
// USART0 Receiver interrupt service routine
interrupt [USART0_RXC] void usart0_rx_isr(void)
{
char status,data;
status=UCSR0A;
data=UDR0;
if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
{
rx_buffer0[rx_wr_index0]=data;
if (++rx_wr_index0 == RX_BUFFER_SIZE0) rx_wr_index0=0;
if (++rx_counter0 == RX_BUFFER_SIZE0)
{
rx_counter0=0;
rx_buffer_overflow0=1;
};
};
}
// Get a character from the USART0 Receiver buffer
#define _ALTERNATE_GETCHAR_
#pragma used+
char getchar(void)
{
char data;
while (rx_counter0==0);
data=rx_buffer0[rx_rd_index0];
if (++rx_rd_index0 == RX_BUFFER_SIZE0) rx_rd_index0=0;
#asm("cli")
--rx_counter0;
#asm("sei")
return data;
}
// USART0 initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART0 Receiver: On
// USART0 Transmitter: On
// USART0 Mode: Asynchronous
// USART0 Baud rate: 38400
UCSR0A=0x00;
UCSR0B=0xD8;
UCSR0C=0x06;
UBRR0H=0x00;
UBRR0L=0x19;
//Receive one Byte - This has to be in the Main Loop
while(rx_counter0>0)
{
getchar();
//Receive Sensor Data
}
To read out more than one Byte You have to define a Buffer and search for an End Term.
When the End Term is reached you can process the result.

This Example is for an ATMEGA 1280 witch has 4 USART's so there is a 0 at the end.

When I'm right the chip has an 9600 bit/s USART Speed.
The rest You'll find in the Datasheet.
I'm not shure but I guess your RF01D had to be configured via the serial Port.
How to do this You should find in the Data sheet, or look for a library where the configuration will be done.
The important strings You can copy into Your file and send it via USART TX to the Chip.
 
Last edited:
Thread starter #8
How does this command work?
while(rx_counter0>0)
it means it starts to receive??
___________
and yes I want to receive the all data it sends ... so I need to define final condition for it
 

wkrug

Active Member
#10
Then choose the comunication parameters.
The Example works with 38400 Bit/s 8,N,1
Your Tag will work with 9600 Bit/s 8,N,1
Choose this Parameters in the APG and all will be fine.
SW 2 + 3 of the RF01D had to be set to o by switch.

while(rx_counter0>0)
The receive Routine works interupt driven.
Every Byte that was received in the interupt routine increases this counter.
Every Byte You read out with: bytex=getchar();
decrease this Counter.
When all received Bytes was processed the routine was not called again, until a new byte was received.

I saw an error by me:
False: getchar();
Right: bytex=getchar();

That was an very simple example.
For Your solution I would take the received bytes into a string that is pointed by a variable.
When a new byte was received, You had to check it for 0x10 ( = ENTER ).
When the last Byte is 0x10, I would check the byte before it had to be 0x13.
When both Conditions are OK You have received a complete Tag and it could be printed out.
Some print options in "C" must have a 0x00 at the End of the string.
Possibly You have to insert that.

After printout You can set the pointer variable to 0.
So the String is ready for the next card.

my tags contains 10 digits on their serial numbers
So I would prepare the datax variable for 15Bytes ( = 1 complete String + CR/LF + 0 +2 spacer )
unsigned char datax[15];
unsigned char datapoint=0;

The spacer is not a must, but Codevision overwrite the next variable without warning if the pointer address it.
That could be a problem if 0x10 or 0x13 wasn't received correctly.
You see some traps You can get in.

The interrupt receive buffer can be lower. I think 25Bytes are enough ( 2 complete Strings ).

Additional I would take a clock into the "string" Routine.
When ( e.g. longer than 1s ) no additional Bytes in the string -> Reset the pointer variable.
That could be done by a timer that increases a variable.
When a value was exeeded the Pointer had to be set to 0.
This avoid trouble, when a string wasn't received complete and the next string is coming in.

Additional Explaination:
The bytes 0x30,0x31,0x38 and so on are the ASCII Code of the Number Characters.
So You can print them out directly.
 
Last edited:

wkrug

Active Member
#11
Instantly I have only the trial version of CodeVision 3 on my Computer.
So there are not all functions included You need.

I've changed to AVR Studio 7 that's free for evaluation, but rather more complex.
 
Thread starter #16
can it be the main loop?

unsigned char datax[15];

gets(datax,15);
unsigned char datapoint=0;
_______
I am still not sure about "datapoint" application
 
Last edited:

wkrug

Active Member
#18
Where did they come from?
In Your last Post in the field OUTPUT DATA the two last bytes are 0x13 and 0x10.
The RF01D generate this Bytes.
one string equals to 12.5 bytes?
You get 10Bytes by the ID and 2Bytes Enter ( =0x13 + 0x10 ).
To use the string functions of "C" you had to insert a 0 as last Byte.
So You get 13Bytes. The additional 2Bytes are only for safety.
"C" put one variable after the other.
When the Pointer exeed 13 the following variable will be overwritten.
you mean this one?
Yes Sir.

can it be the main loop?
unsigned char datax[15];
This would be in the Initialisation at top of main.c

unsigned char datax[15]; //Prepare a variable with 15 possible values you use as string
unsigned char datapoint=0; //Prepare a variable that used as pointer and set it to 0

To define a variable in an loop doesn't work.

gets(datax,15);
In CodeVision i can't find anything about gets.

//This is the complete String readout for the reader
void makestring(void)
{
datax[datapoint]=getchar(); //Get the next character
datapoint++;
if ((datax[datapoint-2] == 0x13) && (datax[datapoint-1] == 0x10)) //End of string is reached?
{
datax[datapoint] = 0x00; //Insert the "C" String end
lcd_puts(*datax); //Any output routine could be insert here LCD, USART or something else.
datapoint = 0; //Set Pointer to 0 for next card
}

//In main loop in the section while(1) You have to insert
while(rx_counter>0)
{
makestring();
//Receive Data and generate a string
}

Function:
When a Byte was received with the USART, the rx_counter will be incremented.
The while(rx_counter>0) test this.
The makestring routine will be called and get the new Byte, test it if the end is reached, make it "C" compatible and print it out.
That's it.

What missing now is the trouble shooting.
I think the best way is, to make this by a time driven reset of the datapoint variable.
When the pointer >0 and some time no further Bytes comming in, the pointer will be set to 0.

A complete reset of the controller by watchdog is an additional way to do this - But that's not a proper way - The complete controller will be reseted.
 
Last edited:
Thread starter #19
In Your last Post in the field OUTPUT DATA the two last bytes are 0x13 and 0x10.
so this is how the RFID realizes when to finish reading, is there similar method for when to start reading?
You get 10Bytes by the ID and 2Bytes Enter ( =0x13 + 0x10 ).
To use the string functions of "C" you had to insert a 0 as last Byte.
So You get 13Bytes. The additional 2Bytes are only for safety.
you fantastically explained it , I really can't thank you for it.
unsigned char datax[15]; //Prepare a variable with 15 possible values you use as string
I guess I understand this variable , it saves the 15 bytes RFID sends (correct me if i'm wrong please)
unsigned char datapoint=0; //Prepare a variable that used as pointer and set it to 0
But I don't know what this variable works.

What missing now is the trouble shooting.
what do you mean? what's wrong with that code?
void makestring(void)
{
datax[datapoint]=getchar(); //Get the next character
datapoint++;
if ((datax[datapoint-2] == 0x13) && (datax[datapoint-1] == 0x10)) //End of string is reached?
{
datax[datapoint] = 0x00; //Insert the "C" String end
lcd_puts(*datax); //Any output routine could be insert here LCD, USART or something else.
datapoint = 0; //Set Pointer to 0 for next card
}

//In main loop in the section while(1) You have to insert
while(rx_counter>0)
{
makestring();
//Receive Data and generate a string
}
I really appreciate and never forget your favor!
_____________________________
I'll give it a practical try next week(and ask my unforeseen questions most probably;) ,again I'm really grateful .
 

wkrug

Active Member
#20
But I don't know what this variable works.
It adresses the place where the next character placed in the datax string.

datapoint=9;
datax[datapoint]='A'; //Places the character A at Place 10 of the datax string - The first place in datax begins with 0

what do you mean? what's wrong with that code?
When an uncomplete string from the RF01D was received the datapoint pointer has the last value.
When a new string from RF01D was received it will be placed after the uncomplete string.
So the max string len of datax will be exceeded an the following variable will be overwritten.
You have to avoid this.

so this is how the RFID realizes when to finish reading, is there similar method for when to start reading?
I guess the RF01D generate a string at it's TX pin, when a ID Card is reachable.

The jumper setting of the RF01D has to fit with the readout routine in the AVR.
 

Latest threads

EE World Online Articles

Loading

 
Top