Working with byte array I get an "invalid conversion from char* to byte"

Bare with me. I’m not very good at writing in Arduino/C.

I am reading and writing to an RFID tag using MFRC522.h
I can currently read the UID of a card and dump it to “UIDChar”
The UID of a card typically is 8 characters.

UID Example: 467EE9A9

I can use the mfrc522.MIFARE_SetUid function to write this UID to a new card. In order to do this I have to set the newUID to:

0x46,0x7E,0xE9,0xA9

I have written this into my code.
What I am wanting to do is convert the UID string into a byte array so that I can use that in place of my manually written 0x46,0x7E,0xE9,0xA9.

I use the convert function to convert the UID into that format.
It can that be displayed with “buf”.

Serial.println(buf);

Now my problem. If I replace the

byte newUid = {0x46,0x7E,0xE9,0xA9f};

with

byte newUid = {buf};

I get the error
invalid conversion from ‘char*’ to ‘byte {aka unsigned char}’

How can I set my “newUid” as “buf”?

// Creates a Wifi AP, Displays Website, and Reads RFID Tags
#define SS_PIN 0  //D2
#define RST_PIN 2 //D1

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


/* For RFID */
MFRC522 mfrc522(SS_PIN, RST_PIN);   // Create MFRC522 instance.
char buf[40]; // For string to byte array convertor

void convert(char *s)
{
 int i, j, k;
 buf[0] = 0x0;
 
 for (j = 0, i = 0, k = 0; j < strlen(s); j++)
 {
   
   if (i++ == 0) {
     buf[k++] = '0';
     buf[k++] = 'x';
   }
   
   buf[k++] = s[j];
   
   if (i == 2) {
     if(j != strlen(s) -1)  buf[k++] = ',';
     i = 0;
   }
 }

buf[k] = 0x0;

}

void clone() {
  
 /* RFID Read */
  // Look for new cards
  if ( ! mfrc522.PICC_IsNewCardPresent()) 
  {
    return;
  }
  // Select one of the cards
  if ( ! mfrc522.PICC_ReadCardSerial()) 
  {
    return;
  }
  //Show UID on serial monitor
  Serial.println();
  Serial.print(" UID tag :");

  //  Very basic UID dump
  unsigned int hex_num;
  hex_num =  mfrc522.uid.uidByte[0] << 24;
  hex_num += mfrc522.uid.uidByte[1] << 16;
  hex_num += mfrc522.uid.uidByte[2] <<  8;
  hex_num += mfrc522.uid.uidByte[3];

  // Get UID
  int  NFC_id = (int)hex_num;
  Serial.print(NFC_id, HEX);

  // Convert UID to string using an int and a base (hexadecimal)
  String stringUID =  String(NFC_id, HEX);
  char UIDChar[10];
  stringUID.toCharArray(UIDChar,10);

  delay(1000);
  Serial.println();


  // Convert to uppercase 
  for (int i = 0; i < strlen(UIDChar); i++ )
  {
    if ( UIDChar[i] == NULL ) break;
    UIDChar[i] = toupper(UIDChar[i]);
  }

  //Serial.print( &UIDChar[0] );
  Serial.println();
  convert(UIDChar);
  Serial.println(buf);
  
   /* RFID Write */

   // Set new UID
   //  Change your UID hex string to 4 byte array

   // I get error if I use byte newUid[] = {buf};
 /*  ERROR HERE */
  byte newUid[] = {0x46,0x7E,0xE9,0xA9};
  if ( mfrc522.MIFARE_SetUid(newUid, (byte)4, true) ) {
    Serial.println( "Wrote new UID to card." );
  }
  
  // Halt PICC and re-select it so DumpToSerial doesn't get confused
  mfrc522.PICC_HaltA();
  if ( ! mfrc522.PICC_IsNewCardPresent() || ! mfrc522.PICC_ReadCardSerial() ) {
    return;
  }
  
  // Dump the new memory contents
  Serial.println( "New UID and contents:" );
  mfrc522.PICC_DumpToSerial(&(mfrc522.uid));
  
}

void setup() {

  Serial.begin ( 115200 );

  /* RFID */
  SPI.begin();      // Initiate  SPI bus
  mfrc522.PCD_Init();   // Initiate MFRC522

  clone();

}

void loop() {

}

Replace:

  byte newUid[] = {buf};

with:

  byte newUid[40];
  strncpy(newUid, buf, 40);

That gives me

invalid conversion from 'byte* {aka unsigned char*}' to 'char*'

Try this:

  byte newUid[40];
  strncpy((char *) newUid, (char *) buf, 40);

I no longer get an error but it's not writing the correct UID.

Normally 0x46,0x7E,0xE9,0xA9 will write a UID of 46 7E E9 A9

But instead, a UID of 30 78 34 36 is being written.

byte newUid[40];
strncpy((char *) newUid, (char *) buf, 40);
Serial.println(newUid[40]);

Prints "52" instead of the 46 7E E9 A9

0x30 is ASCII '0'
0x78 is ASCII 'x'
0x34 is ASCII '4'
0x36 is ASCII '6'

That is what you put into buf and then copied to newUid. Subsequently you set the UID with the first 4 bytes of the newUid array using this line of code:

  if ( mfrc522.MIFARE_SetUid(newUid, (byte)4, true) ) {

The code did exactly what you asked it to do. I'm assuming, however, that the UID should be binary data not ASCII. Therefore I'm not sure why your convert function is converting to ASCII and not binary.

Also unsigned int is only 16 bits. Not sure how this is working:

  //  Very basic UID dump
  unsigned int hex_num;
  hex_num =  mfrc522.uid.uidByte[0] << 24;
  hex_num += mfrc522.uid.uidByte[1] << 16;
  hex_num += mfrc522.uid.uidByte[2] <<  8;
  hex_num += mfrc522.uid.uidByte[3];

Which leads me to the question…the mfrc522.uid.uidByte byte array is already a binary UID representation. You don’t need to convert anything.

The convert function just takes a number and puts it in that particular format. Sorry, I’m confused about the mfrc522.uid.uidByte. How can I use it properly? I’ve tried the following and it doesn’t write the UID I need.

  if ( mfrc522.MIFARE_SetUid(mfrc522.uid.uidByte, (byte)4, true) ) {
    Serial.println( "Wrote new UID to card." );
  }

I’ve also tried writing it out as mfrc522.uid.uidByte[4], etc.

 for (byte i = 0; i < mfrc522.uid.size; i++) {
    Serial.print(mfrc522.uid.uidByte[i]);
  }

prints 70126233169

I’m going to look up more info on binary and bytes. This is all new to me.

merdenoms:
The convert function just takes a number and puts it in that particular format.

Your convert function is creating a 20 character ASCII character string of "0x46,0x7E,0xE9,0xA9" which is nice if you want to print it. It does not create the array {0x46,0x7E,0xE9,0xA9} which is 4 bytes and which is why when you have the following line of code it works.

byte newUid[] = {0x46,0x7E,0xE9,0xA9};

I haven't studied your code closely but it looks as if you are trying to write the UID from one card to another, but the code looks like you are reading the UID from the same card you write it to. I may be wrong because I haven't worked with these cards but doesn't mfrc522 refer to the same card in all cases since it is the same instance?

Thank you for your help! You’ve actually explained some stuff to me that I needed to know.

The library I’m using is intended for the use with one card but I’ve been trying to use it to clone the UID to another card.

I finally got it working. I ditched the convert function.

  // Convert to array of bytes
  char *CardNumber = UIDChar;
  byte CardNumberByte[4];

  // Use 'nullptr' or 'NULL' for the second parameter.
  unsigned long number = strtoul( CardNumber, nullptr, 16);

  for(int i=3; i>=0; i--)    // start with lowest byte of number
  {
    CardNumberByte[i] = number & 0xFF;  // or: = byte( number);
    number >>= 8;            // get next byte into position
  }

  for(int i=0; i<4; i++)
  {
    Serial.print("0x");
    Serial.println(CardNumberByte[i], HEX);
  }

  // For manually writing UID:
  // byte CardNumberByte[] = {0x24, 0x25, 0x56, 0x77};
  // This equals UID: 24 25 56 77
  if ( mfrc522.MIFARE_SetUid(CardNumberByte, (byte)4, true) ) {
    Serial.println( "Wrote new UID to card." );
  }

Glad it worked out for you!