8 years, 6 months ago.

Writing and reading from card

How would I use your code to read and write to a MIFARE 1k card? I would assume id use

uint8_t MIFARE_Read	(	uint8_t 	blockAddr,uint8_t * 	buffer,uint8_t * 	bufferSize )	

to read it but I cant seem to get this working, it returns 0 every time, the code below shows my attempt, I am trying to read block 0 (believe theres a total of 64 blocks), I know only some of them contain data but im trying to read all from the card.

uint8_t* buffer;
    uint8_t* buffersize;
    RfChip.MIFARE_Read(0-0xff, buffer, buffersize);
    pc.printf("Block0: %x \r\n",buffer);

How could i do something like the picture below and read all the blocks? /media/uploads/NoLiver92/score_2.jpg

Question relating to:

RFID Chip MFRC522 driver

1 Answer

8 years, 6 months ago.

Your code has some fundamental problems, you are passing a very messed up block number (0-0xff = -255 which I think comes out as +1 when treated as a uint8) and you are using an undefined pointers as the data buffer and buffer size. Your printf is then printing the address of the data buffer rather than the data in it.

Going by the documentation in the header file I think you need something along the lines of this:

    uint8_t buffersize; 
    uint8_t buffer[256];

    for(unsigned int block = 0; block <64; block++) {
      buffersize = 256; // set max size to read
      if (RfChip.MIFARE_Read(block , &buffer, &buffersize) == STATUS_OK) { // read OK
         pc.printf("Block %u : %u bytes\r\n",block,buffersize);
         for(int i = 0; i<buffersize ; i++) // buffersize will have been modified to match the amount of data actually read
            pc.printf(" %02X", buffer[i]));
         pc.puts("\r\n");
      } else {
         pc.printf("Block %u : READ FAILURE\r\n",block);
      }
   }

Thanks for your reply Andy, I am new at this so please bare with me. what exactly is this asterix mean? (uint8_t *buffer). I think I understand the uint8_t, I believe its the same as an 8 bit char, am i right? Im trying your code but i get an error in the if statement: Error: Argument of type "std::uint8_t (*)[256]" is incompatible with parameter of type "std::uint8_t *" in "main.cpp". I am not quite sure what this means.

If I remove the & from buffer in the if statement, it returns STATUS_NO_ROOM

posted by Nick Oliver 30 Sep 2015

uint8_t is an unsigned 8 bit integer. A char is also an 8 bit integer but some compilers will consider it signed and some unsigned unless it's explicitly stated.

A * after a type means a pointer to that type so a uint8_t * is a pointer to a uint8_t. A pointer is just a variable that holds a memory address. To make things more confusing a star in front of a variable name means the thing pointed to by that variable. And an & in front of a variable name means the address of that variable.

Try casting the buffer pointer to the required type by using (uint8_t *)&buffer Casting (putting a type in brackets in front of a variable name) tells the compiler to ignore the type of the variable and treat it as the one you state. It's very powerful but you have to be sure you get it right.

The whole pointers thing takes some getting used to when you first come across them but once you do you'll wonder how any language could manage without them.

posted by Andy A 30 Sep 2015

Thanks, I will read up on pointers. The code has worked of sorts, I shortened it to only read the first block and output the result as it wasnt working,

<<code>> uint8_t buffersize; uint8_t buffer[200]; buffersize = 200; pc.printf("Message: %u \r\n", RfChip.MIFARE_Read(0, (uint8_t *)&buffer, &buffersize)); <</code>

This worked but returned STATUS_NO_ROOM, ive been trying to follow the method through and reproduce the steps in the main program to see which line is giving me a problem but everything ive tried seems to have worked so im not sure where this is arising from. STATUS_NO_ROOM seems like a default message from looking at the code so it could come from multiple places. Would you have any idea on why it returns with that, should return STATUS_OK

posted by Nick Oliver 01 Oct 2015

OK, sorry, I was being stupid. Your initial change, just buffer not &buffer, was correct.

A buffer is a pointer to start with (that's the way c handles arrays, the array name on it's own is a pointers to the block of memory that holds the array).

Sorry about sending you on the wrong path there, I'm not sure what I was thinking last night.

But you tried that and still got the same error, I have no idea why. Without the appropriate hardware I'm not sure how much more help I can be at this point.

posted by Andy A 01 Oct 2015

Thats ok, I appreciate you've taken time to try and help me. I think ive narrowed it down to this line in the MRFC522.cpp file: if ((buffer == NULL) || (*bufferSize < 18)).

One of these is causing it to return with the error code but im not sure how this links in with the pointers in the main code (im pretty sure they do somehow). I think its the NULL statement which might do it. Any ideas?

Ive proven its this line as I changed the error message in the library inside the if statement and when I scanned the card the outputted error was the new one I enetred, leading me to this line.

posted by Nick Oliver 01 Oct 2015

Odd, that doesn't make much sense. It's checking that buffer is pointing to something and that buffersize is 18 or more both of which should be true.

NULL is just another way of saying 0, setting a pointer to null is the normal way to indicate that it is invalid and shouldn't be used. *bufferSize is the value pointed to by bufferSize

By using &buffersize in your code you are passing a pointer to that variable and so it should work.

OK. I've just noticed another stupid error in my code. I set buffersize to 256, it's a 8 bit number so 256 will end up wrapping around and being 0. It should be set to 255 not 256. I really wasn't having a good day when I wrote that.

But then your code above you've used a size of 200 so that should be fine.

All I can think of is to try playing safe in case there is some signed/unsigned mess going on and use a buffer size of 127 instead.

uint8_t buffersize; 
uint8_t buffer[127];
 
buffersize = 127; // set max size to read
if (RfChip.MIFARE_Read(0 , buffer, &buffersize) == STATUS_OK)
...
posted by Andy A 01 Oct 2015