how do i convert 0x0f to 46 hex

hey guys, little problem.

i am working with rfid and i have two readers.

the old reader gives me this for example: 0x30, 0x31, 0x30, 0x39, 0x36, 0x38, 0x32, 0x44, 0x43, 0x36.
10 bytes and on my lcd-display it gives me: 0109682DC6.

the new reader gives me this instead: 0x01, 0x09, 0x68, 0x2D, 0xC6
which are only 5 bytes, but as you can see, it are the same numbers. again it is: 0109682DC6.

my problem is, i need the numbers to be as i got them from the first reader.
this is because i send them to an other device which expects them that way and i dont have the opportunity to change that.

now i started converting them by doing this:

char testspeicher3[5] = {0x01, 0x09, 0x68, 0x2D, 0xC6  };

  test_speicher2[0] = ((testspeicher3[0] & 0xf0 ) >> 4 ) + 0x30;
  test_speicher2[1] = (testspeicher3[0] & 0x0f) + 0x30;
  test_speicher2[2] = ((testspeicher3[1] & 0xf0 ) >> 4 ) + 0x30;
  test_speicher2[3] = (testspeicher3[1] & 0x0f) + 0x30;
  test_speicher2[4] = ((testspeicher3[2] & 0xf0 ) >> 4 ) + 0x30;
  test_speicher2[5] = (testspeicher3[2] & 0x0f) + 0x30;
  test_speicher2[6] = ((testspeicher3[3] & 0xf0 ) >> 4 ) + 0x30;
  test_speicher2[7] = (testspeicher3[3] & 0x0f) + 0x30;
  test_speicher2[8] = ((testspeicher3[4] & 0xf0 ) >> 4 ) + 0x30;
  test_speicher2[9] = (testspeicher3[4] & 0x0f) + 0x30;

but that only works for the numbers.
for the letters i had to add 40 but i have no idea how to detect when i need to add 30 and when i need to add 40.

0x0..0x9 add 0x30
0x0A...0x0f add 0x37

for the letters i had to add 40 but i have no idea how to detect when i need to add 30 and when i need to add 40.

(testspeicher3[4] & 0x0f) or ((testspeicher3[4] & 0xf0 ) >> 4 ) will be between 0 and 9 or between a and f. If the value is between 0 and 9, add 0x30. If it is between a and f, add 0x40.

If it is between a and f, add 0x40.

0x4A == 'J'

yeah, 0x0A had to become 0x41.
so i need to add 0x37.

so the best way is to look if i have 0 - 9 or A- F!?
how do i do that?

so the best way is to look if i have 0 - 9 or A- F!?

No, 0x0F! is 1 307 674 368 000.

how do i do that?

x += (x< 10) ? 0x30 : 0x37;

AWOL:
No, 0x0F! is 1 307 674 368 000.

what do u mean with this?

AWOL:

x += (x< 10) ? 0x30 : 0x37;

and this looks nice.
could you explain how this works?

edit: i tried it like this:

test_speicher2[9] += ((testspeicher3[4] & 0x0f)<10) ? 0x30 : 0x37;

and testspeicher3[4] is 0x8f.

but no every loop i get something else.

test_speicher2[9] += ((testspeicher3[4] & 0x0f)<10) ? 0x30 : 0x37;

is not a proper substitution for x in

x += (x < 10) ? 0x30 : 0x37;

Your best bet would be to store each nibble in a temporary variable, manipulate that temporary variable, and then store the modified temporary variable into the destination variable.

Quote from: AWOL on Today at 11:41:43

No, 0x0F! is 1 307 674 368 000.
what do u mean with this?

It was a geek-gag.
2! = 2
3! = 6
4! = 24 etc.

test_speicher2[9] += ((testspeicher3[4] & 0x0f)<10) ? 0x30 : 0x37;

The "+=" implies you're trying to squeeze two characters into one byte.
That won't work.

You're all missing the obvious...

the old reader gives me this for example: 0x30, 0x31, 0x30, 0x39, 0x36, 0x38, 0x32, 0x44, 0x43, 0x36.
10 bytes and on my lcd-display it gives me: 0109682DC6.

the new reader gives me this instead: 0x01, 0x09, 0x68, 0x2D, 0xC6

The first is giving a string of ASCII characters representing the code.
The second is giving the numeric value of the code in hexadecimal.

Just "print" the new value as hex and it will result in the old value:

char temp[11];
sprintf(temp, "%02X%02X%02X%02X%02X", val[0], val[1], val[2], val[3], val[4]);

That will result in a string containing "0109682DC6".

You're all missing the obvious...

No, we were trying to point out the obvious...subtly {sigh}

AWOL:

You're all missing the obvious...

No, we were trying to point out the obvious...subtly {sigh}

Too subtly... You have to be as subtle as a brick with these people.

first: okay, so you were talking about factorials. ^^

2nd: i already use this:

for( int b=0; b<5; b++ ){
    lcd.print( test_speicher[b],HEX);
  }

but for some reasons it gives me 19685524 instead of 0109685524.
but that isnt even the problem.

i have to send a data package which contains 10 bytes for the number over serial.
that is why i need the converting.

and i am doing it like this now:

if ((testspeicher3[4] & 0x0f)<0x0A){
    test_speicher2[9] = (testspeicher3[4] & 0x0f) + 0x30;
  } 
  else{
    test_speicher2[9] = (testspeicher3[4] & 0x0f) + 0x37;
  }

it works, but is there a nicer way?

do you maybe even know if i can do that in a "for-loop" for all this:

test_speicher2[0] = ((testspeicher3[0] & 0xf0 ) >> 4 ) + 0x30;
  test_speicher2[1] = (testspeicher3[0] & 0x0f) + 0x30;
  test_speicher2[2] = ((testspeicher3[1] & 0xf0 ) >> 4 ) + 0x30;
  test_speicher2[3] = (testspeicher3[1] & 0x0f) + 0x30;
  test_speicher2[4] = ((testspeicher3[2] & 0xf0 ) >> 4 ) + 0x30;
  test_speicher2[5] = (testspeicher3[2] & 0x0f) + 0x30;
  test_speicher2[6] = ((testspeicher3[3] & 0xf0 ) >> 4 ) + 0x30;
  test_speicher2[7] = (testspeicher3[3] & 0x0f) + 0x30;
  test_speicher2[8] = ((testspeicher3[4] & 0xf0 ) >> 4 ) + 0x30;
  test_speicher2[9] = (testspeicher3[4] & 0x0f) + 0x30;

but for some reasons it gives me 19685524 instead of 0109685524.

You're missing the leading zeroes.

AWOL:

but for some reasons it gives me 19685524 instead of 0109685524.

You're missing the leading zeroes.

how can i avoid that when using lcd.print?

By testing to see if the number you're about to print is less than 16.

all this obvious answers :sweat_smile:

thought there maybe some "cooler" ways to do it.

i am doingt it like this now:

for( int b=0; b<5; b++ ){
    if (test_speicher[b]<16){
      lcd.print("0");
      lcd.print( test_speicher[b],HEX);
    }
    else    lcd.print( test_speicher[b],HEX);
  }

but i found a new wiered problem.
the loop above works fine with tags that give me numbers like this: {01, 09, 68, 55, 34}.

but when i read this tag: {01, 09, 68, 46, 8f} it gives me this on my lcd-display: 010968460ffffff8f. :~

Sign extension - cast your numbers to "byte"

for( int b=0; b<5; b++ ){
    if (test_speicher[b]<16){
      lcd.print("0");
    }
    lcd.print( (byte)test_speicher[b],HEX);
 for( int b=0; b<5; b++ ){
    if (test_speicher[b]<16){
      lcd.print("0");
      lcd.print( (byte)test_speicher[b],HEX);
    }
    else  lcd.print( (byte)test_speicher[b],HEX);
  }

now i dont get 010968460ffffff8f, but i still get 0109684608f instead of 010968468f.

one zero to much.

Randam:

 for( int b=0; b<5; b++ ){

if (test_speicher[b]<16){
      lcd.print("0");
      lcd.print( (byte)test_speicher[b],HEX);
    }
    else  lcd.print( (byte)test_speicher[b],HEX);
  }




now i dont get 01096846**0ffffff**8f, but i still get 01096846**0**8f instead of 010968468f.

one zero to much.

Same problem, but further up. You're comparing a signed value with 16, and if it's lower then put a 0 - the same 7th bit of 0x8f that caused the fffff to appear is making it a negative number, so it will be less than 16.

It would be better to use a byte array not a char array right from the start.