How to convert byte array to String?

Hi guys!

I am working on a little RFID project but I am having one tiny problem.

I have a RC522 RFID Module connected to an Arduino UNO and I want to be able to read TAGS and then compare the read ID to a string.

The ID will get stored into a byte array with the size of 4.

For instance...

byte readTAG[4];

will hold...

{ C3, 7D, DF, C7 }

I now want to take this array and convert it into a String such as...

"C37DDFC7"

This way...I could do operations such as

if(readTag == "12345678") {
// Do something...
}

How would I go about doing this?

Thanks in advance!

Here is my code:

#include <MFRC522.h>
#include <SPI.h>

int RST_PIN = 9;
int SDA_PIN = 10;

byte readCard[4];

MFRC522 mfrc522(SDA_PIN, RST_PIN);

void setup() {
  Serial.begin(9600);
  SPI.begin();
  mfrc522.PCD_Init();
}

void loop() {
  ReadTAG();  

}

// Lese TAG aus und gebe die ID im Serial Monitor aus.
void ReadTAG() {
  // Wenn ein neuer TAG vorhanden ist UND erfolgreich gelesen werden konnte, dann Lese TAG aus.
  if (mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial()) {     
    for (int i = 0; i < 4; i++) { 
     readCard[i] = mfrc522.uid.uidByte[i];
     Serial.print(readCard[i], HEX);       
    }       
    Serial.println();    

    // Wenn der TAG ausgelesen wurde dann stoppe das Lesen da er sonnst das gleiche TAG vielemale ausließt.
    mfrc522.PICC_HaltA();
  }
}

What on earth would possess you to convert into a String? Have you got something against using strcmp() ?

KenF:
What on earth would possess you to convert into a String? Have you got something against using strcmp() ?

I just can't figure out how to do it...

I changed the code to this.

if (mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial()) {
for (int i = 0; i < 4; i++) {
readCard[ i ] = mfrc522.uid.uidByte[ i ];
}
readCard[4] = '\0';

Serial.println(readCard);

readCard is also a 'char' now.

But when I print readCard to Serial I get...

Ã}ßÇ

and when trying to use strcmp like this...

if (strcmp(readCard, "Ã}ßÇ") == 0) {
Serial.println("Test");
}

It fails.

. . . or memcmp

Not to mention, its not null terminated as you think it is.

Unless you make readCard have 5 elements: char readCard[5];

readCard[4] = '\0';

This will not work.

HazardsMind:
Not to mention, its not null terminated as you think it is.

Unless you make readCard have 5 elements: char readCard[5];
This will not work.

Sorry i forgot to post the change. I did increase the array to 5 to account for the termination. But why am I getting weird output when I print readCard?

Serial.println(readCard);

This is only showing you what is in index 0, and not the full array (use a for loop), also the result you are seeing is the character based on value in index 0.

Add in HEX to see the hex value, DEC for the decimal value or BIN to see the binary value.
Serial.println(readCard, HEX);

Assuming readTAG is filled with data:

{ 0xC3, 0x7D, 0xDF, 0xC7 }

(as in your first post), you can simply compare it to a number, like this:

if ( *(uint32_t*)readTAG == 0xC7DF7DC3 )
byte readCard[4];
for (int i = 0; i < 4; i++) { 
     readCard[i] = mfrc522.uid.uidByte[i];
     Serial.print(readCard[i], HEX);       
    }

You have your values in byte arrays and AWOL has pointed you toward memcmp as the way perform conditional tests. Here is a small sketch which demonstrates memcmp.

void setup() {
  Serial.begin(9600);
  byte readCard[4];
  byte mfrc522_uid_uidByte[] = {0xC3,0x7D,0xDF,0xC7};
  byte checkArray[3][4]={
  {0xC3,0x7D,0xDF,0xC7},
  {0xC3,0x7D,0xDF,0xC6},
  {0xC4,0x7D,0xDF,0xC7},  
 };
 
  for (int i = 0; i < 4; i++) { 
    readCard[i] = mfrc522_uid_uidByte[i];
    Serial.println(readCard[i], HEX); 
  }
  
  Serial.println("Checking Match");
  
  for(int i=0; i<3; i++){
    Serial.print("Testing Match with checkArray ");
    Serial.println(i);
  if((memcmp(readCard,checkArray[i],4))==0)
    Serial.println("Arrays Match");
  else
    Serial.println("No Match");
}
}
void loop() {
}

guix:
Assuming readTAG is filled with data:

{ 0xC3, 0x7D, 0xDF, 0xC7 }

(as in your first post), you can simply compare it to a number, like this:

if ( *(uint32_t*)readTAG == 0xC7DF7DC3 )

This works! Thank you so much!

Though I noticed that you all flipped the bytes...why? C3, 7D, DF, C7 to C7, DF, 7D, C3

That's because arduinos are little endian systems ( see this ) :wink:

I now want to take this array and convert it into a String such as...

The below might be of use.

void setup(void)
{
}

void loop(void)
{
  byte byteArray[5];
  strcpy((char *)byteArray,"0123");
  String myString = String((char *)byteArray);
}

Hello, I have a problem with my rfid reader that is ID-20LA to convert this array type code.

I want to change into string form. So how?
Tq

Here is my code:

byte tagID[12];
boolean tagread=false;

//configure arduino
void setup()
{
Serial.begin(9600);
Serial.println("Staff Attendance Using RFID starting...");
}

void loop()
{
if(Serial.available()>=13) //Make sure all the frame is received
{
if(Serial.read()==0x02) //Check for the start byte = 0x02
{
tagread=true; //New tag is read
for(int index=0;index<sizeof(tagID);index++)
{
byte val=Serial.read();

//convert from ASCII value to value range from 0 to 9 and A to F
if( val >= '0' && val <= '9')
val = val - '0';
else if( val >= 'A' && val <= 'F')
val = 10 + val - 'A';

tagID[index]=val;
}
}
else
{
tagread=false; //Discard and skip
}
}

if(tagread==true) //New tag is read
{
ReadFromTag(); //Display the tag ID
clear_tag(); //Clear the tag ID and ready for next tag
tagread=false;
}
delay(10);
}

void ReadFromTag() //Subroutine to display the tagID content
{
Serial.print("Tag ID: ");
for(int index=0;index<10;index++)
{
Serial.print(tagID[index],DEC); //Display tagID
}
Serial.print("\r\nChecksum: ");
Serial.print(tagID[10],DEC); //Display checksum
Serial.println(tagID[11],DEC);
}

void clear_tag() //Subroutine to clear the tagID content
{
for(int index=0;index<sizeof(tagID);index++)
{
tagID[index]=0;
}
}

All you need to do to turn the tagID array of chars into a C style string (lowercase s) all you need to do is to put a zero in the last position in the array but you MUST increase the size of the array in the declaration to allow space for it.

byte tagID[13];
      for(int index=0;index<sizeof(tagID - 1);index++)
      {
        byte val=Serial.read();
        
        //convert from ASCII value to value range from 0 to 9 and A to F
        if( val >= '0' && val <= '9')
        val = val - '0';
        else if( val >= 'A' && val <= 'F')
        val = 10 + val - 'A';
        
        tagID[index]=val;
        tagID[index + 1]='\0';
      }

Of course, if you are going to use strings (lower case s, meaning null terminated array of chars), it's more usual to make the array type char.

And, since the device is sending chars, stop subtracting '0' from each one before you store it in the array.

HazardsMind:
This is only showing you what is in index 0, and not the full array (use a for loop), also the result you are seeing is the character based on value in index 0.

Add in HEX to see the hex value, DEC for the decimal value or BIN to see the binary value.
Serial.println(readCard, HEX);

Actually, Serial.println() is not overloaded to accept a pointer to a byte array.

Hi!

I would like to use this code:

#include <MFRC522.h>
#include <SPI.h>

int RST_PIN = 9;
int SDA_PIN = 10;

byte readCard[4];

MFRC522 mfrc522(SDA_PIN, RST_PIN);

void setup() {
 Serial.begin(9600);
 SPI.begin();
 mfrc522.PCD_Init();
}

void loop() {
 ReadTAG();  

}

// Lese TAG aus und gebe die ID im Serial Monitor aus.
void ReadTAG() {
 // Wenn ein neuer TAG vorhanden ist UND erfolgreich gelesen werden konnte, dann Lese TAG aus.
 if (mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial()) {     
   for (int i = 0; i < 4; i++) { 
    readCard[i] = mfrc522.uid.uidByte[i];
    Serial.print(readCard[i], HEX);       
   }       
   Serial.println();    

   // Wenn der TAG ausgelesen wurde dann stoppe das Lesen da er sonnst das gleiche TAG vielemale ausließt.
   mfrc522.PICC_HaltA();
 }
}

whit this section:

"Assuming readTAG is filled with data:
Code: [Select]

{ 0xC3, 0x7D, 0xDF, 0xC7 }

(as in your first post), you can simply compare it to a number, like this:
Code: [Select]

if ( *(uint32_t*)readTAG == 0xC7DF7DC3 )"

but I dont know, how I should use this.

how I should inserte it.

The first thing to do is to make it readable in the forum with no italic code caused by an array suffix of [­i]

Do this by selecting the code in the forum editor and clicking the code icon (</>) top left of the editor, to insert code tags, then saving the post.

I have corrected it.

You can NOT compare an array of values to anything using ==.

You CAN compare an array of values to another array of values using memcmp().

Stick with what you CAN do instead of trying to invent new syntax that hasn't a hope in hell of working.

1 Like