2

On my current project, I have RFID badges which sends a 10 chars ID to my Arduino UNO (ex: 2700BBA0E8). The doc says "Printable ASCII", but I don't know if it's always [0-9A-F].

On Arduino, the memory is limited:

  • char is 1 byte
  • int is 2 bytes
  • long is 4 bytes

an int or a long would be shorter than a char[10] and simpler to compare (strcmp() vs ==), so I wonder how I can transform the 10 chars received one by one (on serial) to an int or a long?

Thanks for your help

Max13
  • 919
  • 2
  • 9
  • 27
  • 2
    Even 10 hex digits [0-9A-F] would be 5 Bytes and therefore more than one `long`. – SpamBot Aug 01 '16 at 10:03
  • You could concievably put the 2 first values into an int, and the last 8 values into a long, and do a comparaison with a logical and on both variables, but I'm pretty sure that the extra code to do so would be more than just doing a `strcmp`, and more complicated. – AntonH Aug 01 '16 at 10:07
  • @AntonH Also if you put `int` and `long` into same struct, that could take whole 8 bytes because of memory alignment. (I don't know how exactly this works for Arduino). – Markus Laire Aug 01 '16 at 10:09
  • @MarkusLaire Potentially, yes. There are methods to get around memory alignment, such as using `pragma pack`, but I don't know how well they work with Arduino (though I don't see a reason why it shouldn't). – AntonH Aug 01 '16 at 10:11
  • compare one Long and one char – YOU Aug 01 '16 at 10:13
  • I thought about 2 `long`s from the 5 first chars, but I don't know how to transform them to numerical type – Max13 Aug 01 '16 at 10:13
  • If you're looking for code to convers hex to binary, 5-second Google search: https://stackoverflow.com/questions/8205298/convert-hex-to-binary-in-c But I would stick with the `strcmp`, personally, especially if you're unsure if only HEX values are accepted, or if it's all alphanumerical values. – AntonH Aug 01 '16 at 10:17
  • If the documentation says 'printable ASCII', characters outside the range 0-9A-F are allowed. So I'd be really rather dubious about doing this. – Tom Tanner Aug 01 '16 at 10:18
  • 1
    Speaking of "simpler to compare", AVR is a 8 bit processor, and it only has 8 bit registers. So you won't get the benefit of word comparisons like you would on 32 bit processors. – WGH Aug 01 '16 at 14:43

1 Answers1

1

As already mention, you want put 5 bytes inside a long which can store only 4 bytes. Also, you have to use structure:

struct RFIDTagId
{
    unsigned long low;
    unsigned long high; // can also be unsigned char
};

And use something like that:

unsigned int hex2int(char c)
{
    if (c >= 'A' && c <= 'F')
        return (c - 'A' + 0x0A);
    if (c >= '0' && c <= '9')
        return c - '0';
    return 0;
}

void char2Id(char *src, RFIDTagId *dest)
{
    int i = 0;

    dest->low = 0;
    for(i = 0; i < 8; ++i)
    {
        dest->low |= hex2int(src[i]) << (i*4);
    }

    dest->high = 0;
    for(i = 8; i < 10; ++i)
    {
        dest->high |= hex2int(src[i]) << ((i-8)*4);
    }
}

And to compare 2 ids:

int isRFIDTagIdIsEqual(RFIDTagId * lhs, RFIDTagId * rhs)
{
    return lhs->low == rhs->low && lhs->high == lhs->high;
}

or if you really have c++:

bool operator==(RFIDTagId const & lhs, RFIDTagId const & rhs)
{
    return lhs.low == rhs.low && lhs.high == lhs.high;
}
Garf365
  • 3,619
  • 5
  • 29
  • 41
  • Thanks for your answer, I was exactly looking for this "bitwise shift" method. But now, as a proof of concept, is there a way to make a unique "checksum" out of the 10 char ID ? – Max13 Aug 01 '16 at 21:47
  • Maybe take a look at CRC32, it calculates a hash on data. This hash is store on 4bytes, so you save a byte. It's a relatively simple algorithm, easy to implement in embedded device. IMHO, according specificity of RFID ID (according some RFID standard, one part of ID is for manufacturer and another one for serial number), probability you get a collision is really small, so you can use it to identify tags. But to have a totally perfect unique hash to your 5 bytes data, you have to take an at least 5 bytes hash. – Garf365 Aug 02 '16 at 07:26
  • Thx. Actually, I want to make an electronic version of the monopoly using RFID CC. The max is 4 players, so even if I take the last 4 chars to int or long, I think the collision risk is almost 0%. So, to make sure, a CRC32 would be perfect. – Max13 Aug 02 '16 at 08:10
  • It's the plan. The first element will be the bank, then I'm waiting for the board on which I will "dig" electrical tracks to glue an RGB stripe (to led the properties). And I will certainly post a video of the process. If you're interested, I can post here the github – Max13 Aug 02 '16 at 09:13
  • I'm interesting yes :). Everything will by on arduino ? or arduino is only for acquisition of tag id ? – Garf365 Aug 02 '16 at 09:20
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/118884/discussion-between-garf365-and-max13). – Garf365 Aug 02 '16 at 09:23