Reversing and Converting hex to decimal

Hi,

I'm working on an RFID system using a MFRC522 with this Library : GitHub - miguelbalboa/rfid: Arduino RFID Library for MFRC522
Here's the code I have right now:

int A=(mfrc522.uid.uidByte[0]);
int B=(mfrc522.uid.uidByte[1]);
int C=(mfrc522.uid.uidByte[2]);
int D=(mfrc522.uid.uidByte[3]);

Serial.println("UID is %x %x %x %x", A, B, C, D);

This results in the following output:

UID is 35 C5 5A 59

My issue is - how do I first reverse that UID : from 35 C5 5A 59 to 59 5A C5 35

  • and second convert and print the corresponding decimal value of that reversed UID. In this case, it would be 1499120949.

EDIT: I should mention that I need it as a string at the end to add it to the end of a POST command.

Thanks

Serial.println("UID is %x %x %x %x", D, C, B, A); Or is that too obvious?

AWOL:
Serial.println("UID is %x %x %x %x", D, C, B, A); Or is that too obvious?

I need it in decimal format. I'm just really confused - there seems to be so many conversions to do and so many functions itoa atoi.

1. Reversing is relatively easy; you save your data in an array in the reverse order.

2. If you want to show the corresponding decimal value on the Serial Monitor/LCD Monitor, you can do it easily using print() method.

3. If you want to save the decimal digits of the corresponding decimal value, you need to do some math using %(modulus) and /(division) operators. Before doing that you have to bind the array elements into a single integer using a suitable data structure.

GolamMostafa:
1. Reversing is relatively easy; you save your data in an array in the reverse order.

2. If you want to show the corresponding decimal value on the Serial Monitor/LCD Monitor, you can do it easily using print() method.

3. If you want to save the decimal digits of the corresponding decimal value, you need to do some math using %(modulus) and /(division) operators. Before doing that you have to bind the array elements into a single integer using a suitable data structure.

What suitable data structure can I use?

Delta_G:
Or use itoa. That would be a lot simpler don't you think?

Print the data in reverse order like @AWOL said. Then when you get the data just use itoa.

Forget thinking that it is HEX or Decimal, it's always binary to the computer. Hex, dec, oct, it's all stored as the same binary. When you use itoa you get to specify what base you want the ascii to represent. The default will be decimal.

How can I go for from printing the data to having the data in a data structure that itoa will accept? I mean if I use the solution AWOL had - I would have just printed out the individual reversed hex's.

In order to use itoa I need to have those individual reversed hex's combined together and then put into itoa as an integer and it will spit out a decimal string.

Like this? I'm getting some errors with this.

  int A=(mfrc522.uid.uidByte[0]);
  int B=(mfrc522.uid.uidByte[1]);
  int C=(mfrc522.uid.uidByte[2]);
  int D=(mfrc522.uid.uidByte[3]);

  char* final;
  sprintf(final, "%x%x%x%x", D, C, B, A);

What does final point to?

//  int A=(mfrc522.uid.uidByte[0]);
//  int B=(mfrc522.uid.uidByte[1]);
//  int C=(mfrc522.uid.uidByte[2]);
//  int D=(mfrc522.uid.uidByte[3]);

  byte A = '0x35';
  byte B = '0xC5';
  byte C = 'Ox5A';
  byte D = '0x59';

  char final[sizeof(byte)*4];
  sprintf(final, "%x%x%x%x", D, C, B, A);
  Serial.print("%s\n", final);

Okay, I replaced the mfrc522 library with fixed hex codes. When I try and do the Serial.print - I'm getting errors

no known conversion for argument 2 from 'char [4]' to 'int'
exit status 1
call of overloaded 'print(const char [4], char [4])' is ambiguous

Delta_G:

byte A = '0x35';

Single quotes are for single characters. Numbers, like 0x35, don't go in quotes.

The bytes are coming from the GitHub library file. Also if I don't use quotes - I get this error

'Ox5A' was not declared in this scope

Ooops. Sorry

//
  byte A = 0x35;
  byte B = 0xC5;
  byte C = 0x5A;
  byte D = 0x59;

  long revAndComb = ((unsigned long) D << 24) | ((unsigned long) C << 16) | ((unsigned long) B << 8) | A;

  Serial.print("%ld\n", revAndComb);

Does that MATH line convert to decimal too? Also I'm getting an error on print line

no known conversion for argument 1 from 'const char [5]' to 'long unsigned int'
exit status 1
call of overloaded 'print(const char [5], long int&)' is ambiguous

You're using Serial.print, not printf

Fantastic! It worked. Last thing - do I just use itoa now to make this a string so that I can use the + operator in my URL construct line.

Ah.
Okay I got it to work for those bytes

  byte A = 0x35;
  byte B = 0xC5;
  byte C = 0x5A;
  byte D = 0x59;

  long dec_value = ((unsigned long) D << 24) | ((unsigned long) C << 16) | ((unsigned long) B << 8) | A;

  char buf[50];
  ltoa(dec_value, buf, 10);
  String my_UID = String(dec_value);

  Serial.println(my_UID);

Outputs 1499120949 which is correct but if I try these bytes

  byte A = 0x40;
  byte B = 0xC3;
  byte C = 0x16;
  byte D = 0xA4;

  long dec_value = ((unsigned long) D << 24) | ((unsigned long) C << 16) | ((unsigned long) B << 8) | A;

  char buf[50];
  ltoa(dec_value, buf, 10);
  String my_UID = String(dec_value);

  Serial.println(my_UID);

I get 1542012096 which isn't correct according to Decimal to Hexadecimal Converter

Delta_G:
What would be correct? Does it fit in a long? Or do you need unsigned long?

595AC535 = 1499120949

For this one, it should be A416C340 = 2752955200, but the code is outputting 1542012096

EDIT: Oh wow. I changed dec_value to unsigned long and it fixed it. I'm guessing it was showing the overflowing values.

Works perfectly now. I cannot thank you enough for being able to bear with me. Thanks!!!!!!!!!!!!!

a6024132:
What suitable data structure can I use?

union
{
  unsigned long x;
  byte myArray[4] = {0x40, 0xC3, 0x16, 0xA4}; //LSByte, ..., MSByte (0xA416C340 = 2752955200)
} myData;

byte index[10];

void setup()
{
  Serial.begin(9600);
  
  for (int i = 9; i >= 0; i--)
  {
    index[i] = myData.x % 10;
    myData.x = myData.x / 10;
  }
}

void loop()
{

}

Delta_G:
Forget thinking that it is HEX or Decimal, it's always binary to the computer. Hex, dec, oct, it's all stored as the same binary.

With due respect to your opinion, I have a little bit different version of saying --

  1. A memory/register location contains data in bit form. For example: location-m0 contains: 10010101.

  2. If I tell the Computer to view it as BCD formatted data, it is : 95 (to human eyes).

  3. If I tell the Computer to view it as natural BINary formatted data, it is: 149 (to human eyes).

  4. If I tell the Computer to view it as 2's complement formatted data, it is: -107 (to human eyes).

  5. If I tell the Computer to view it as SM formatted data, it is: -21 (to human eyes).

My understanding is this: all data are in bit forms, the sign and magnitude depend on the rules supplied by the owner of the data.

  1. If I tell the Computer to view it as natural BINary formatted data, it is: 149 (to human eyes).

I think you mean "unsigned".
Binary would have only 1s and 0s.

Delta_G:
Or use itoa. That would be a lot simpler don't you think?

Given :

unsigned int x = 0x1A35;   //equivalent decimal = 6709
char myBuffer[50] = "";

itoa(x, muBuffer, 10); //myBuffer[0:3] contains ASCII formatted codes for 6, 7, 0, and 9 respectively.
Serial.print(myBuffer); //shows: 6709

No doubt simple!