What's the difference?

I've tried to figure out what the difference is between the following and why one works and the other doesn't. If I specify that SendByte[1] & [2] = 0x01, the bytes transmit correctly. But if I want to take an integer and sprintf() it to be 0x01, I don't get the action from the bytes transmitted.

What works:

byte SendByte[5];

SendByte[1] = 0x01;
SendByte[2] = 0x01;

What doesn't work:

byte SendByte[5];

int i = 1;
int j = 1;

sprintf(SendByte[1], "0x%02X", i);
sprintf(SendByte[2], "0x%02X", j);

I must be misunderstanding the documentation of sprintf(). I was expecting the desired result of 0x01.

I can't for the life of me figure out what you're trying to do. sprintf() populates a c-string. That's a null-terminated array of char. Each element (byte) of the array is an ASCII character (i.e. one character per byte). So, it's impossible to stuff 4 ASCII characters plus the null terminator into a single element of a byte array.

Not only that, but the first parameter of sprintf() needs to be a pointer to char (i.e. char *) or, equivalently, an array name. Turn up you compiler warnings in 'preferences'. You should see lots of complaints with that second code. I can't believe it will even compile and upload.

gfvalvo:
I can't for the life of me figure out what you're trying to do. sprintf() populates a c-string. That's a null-terminated array of char. Each element (byte) of the array is an ASCII character (i.e. one character per byte). So, it's impossible to stuff 4 ASCII characters plus the null terminator into a single element of a byte array.

Not only that, but the first parameter of sprintf() needs to be a pointer to char (i.e. char *) or, equivalently, an array name. Turn up you compiler warnings in 'preferences'. You should see lots of complaints with that second code. I can't believe it will even compile and upload.

That's probably what I've missed. Lemme go back to the drawing board with the pointer info. Just seen 'warnings' were set to 'none'. Oof.

Is there an actual value difference when I specify 0x01 to each byte? Or is it still seeing just a value of '1' and ignoring the rest (0x0 part)? If I ignore the sprintf(), does casting the value to a char (or unsigned) represent that same value when I have to 'construct' it with an int?

Thanks.

0x is the prefix for specifying a numeric literal in hex notation.

So, 0x01 is the same numerical value as 1 in decimal notation.

0xC7 is the same numerical value as 199 in decimal notation.

Your first example doesn't 'send' anything anywhere.

I would not expect your second attempt to even compile. It certainly gets a number of warnings!

Was this what you intended it to do?

char SendByte[5];


void setup()
{
  Serial.begin(115200);


  int i = 1;
  int j = 1;


  sprintf(SendByte, "0x%02X", i);
  Serial.println(SendByte);
  sprintf(SendByte, "0x%02X", j);
  Serial.println(SendByte);
}


void loop()
{
}

I'm trying to convert a decimal value to a hexadecimal value. (i.e. 131 = 0x83). I'm not understanding why I can't grasp this correctly. It seems like I'm reading and trying to understand to get the value I want, but I'm having a hard time grasping it. Maybe leftovers from my screwed up med change a few weeks ago??

John, I believe this is the same thing you tried to help me out with about a month ago and I couldn't get it then. Well, now I just recently learned the correct terminology and that I've needed to get the actual "value". All this after doing more research on what gfvalvo recommended and playing with an online decimal to hex convertor. So I've been barking up the wrong f'n tree and a little upset with myself.

As in the decimal 23, how does one convert it to the hex value of 17 or, 0x17? I've tried messing with a few of the examples and each one that involved some kind of "string" caused compile errors.

Yes, you are badly wrapped around the axle. There is no such thing as a "hex value" or a "decimal value". There is just value. Numeric values within the processor are all binary in the conceptual sense that an 8-bit register consists of 8 transistors. Each of those transistors can be on or off. That is the only "value" that the processor knows.

Hex and decimal only come into play when humans need to read the value. Humans read ASCII characters. So, the value 11001010 represented internally by 4 "on" transistors and 4 "off" transistors can be read by a human as CA (hex), 202 (decimal), 312 (octal), or 11001010 (binary). Note that each of the representations are groups of ASCII characters. To make it clear what the number base for the ASCII string is, there are standard prefixes (also nothing but ASCII characters):
hex - 0x
decimal - none
octal - 0
binary - 0b

Make sense?

gfvalvo:
Yes, you are badly wrapped around the axle.

To say it nicely. LOL

There is no such thing as a "hex value" or a "decimal value". There is just value. Numeric values within the processor are all binary in the conceptual sense that an 8-bit register consists of 8 transistors. Each of those transistors can be on or off. That is the only "value" that the processor knows.

I understand that part. I'm stuck at "converting" a Base 10 to Base 16. It's hard for me to say exactly what it is I need to do. I know what needs to be the end result, just getting to that point. (i.e. using the words to say, I need to make '23' look like '0x17'). You and I had what was probably a disagreement about a week ago, I knew what I needed, I just couldn't get the correct term out and I believe it frustrated the both of us. My apologies for that.

Hex and decimal only come into play when humans need to read the value. Humans read ASCII characters. So, the value 11001010 represented internally by 4 "on" transistors and 4 "off" transistors can be read by a human as CA (hex), 202 (decimal), 312 (octal), or 11001010 (binary). Note that each of the representations are groups of ASCII characters. To make it clear what the number base for the ASCII string is, there are standard prefixes (also nothing but ASCII characters):
hex - 0x
decimal - none
octal - 0
binary - 0b

Make sense?

Definitely makes sense and I understand it. I appreciate the explanation, seriously.

Kinda depends where the 23 is coming from.

Are you reading a 2 and a 3 from the Serial monitor?
Then multiplying the 2 x 10 and adding 3 to get 23?

If you want to send that back to the serial monitor, you could use
Serial.print (yourNumber, HEX);
to show it as '17'.

If you wanted to break 0x17 into its 2 digits, I think you could use this
highHex = highByte(yourNumber);
lowHex = lowByte (yourNumber);
to end up with
highHex = 0x01
and
lowHex = 0x07

See highByte() and lowByte() on the reference page.

CrossRoads:
Kinda depends where the 23 is coming from.

Are you reading a 2 and a 3 from the Serial monitor?
Then multiplying the 2 x 10 and adding 3 to get 23?

If you want to send that back to the serial monitor, you could use
Serial.print (yourNumber, HEX);
to show it as '17'.

If you wanted to break 0x17 into its 2 digits, I think you could use this
highHex = highByte(yourNumber);
lowHex = lowByte (yourNumber);
to end up with
highHex = 0x01
and
lowHex = 0x07

See highByte() and lowByte() on the reference page.

I actually just read info on the highByte() and lowByte(). BTW, the '23' is from a text input form on a webpage. I need that '17' or '0x17' value to go into either byte, SendByte[1] or [2]. It's just getting that value in there. '23' could be any two digit integer. I'll check here in the morning for any changes or updates.

peasoup:
I'm stuck at "converting" a Base 10 to Base 16.

A "Base 10" and "Base 16" what?
Are they strings of ASCII characters (one byte per character) held in a char, byte, or unit8_t array? If so, is the array null-terminated?

Again, if we're talking about null-terminated arrays of char (aka c-strings). Does this mysterious "Base 16" thing that you want to make have to include the standard Hex identification prefix (i.e. "0x")? If so then, obviously, those additional ASCII characters need to be tacked onto the beginning of the c-string.

What about leading zeros? Both 0x1 and 0x01 are ASCII c-string representations of the same value. But, since you want to make a human-readable ASCII c-string (again, this is the ONLY reason to be talking about "Hex" because the processor doesn't know or care about that), it may matter.

It's really hard to help if you don't provide clear, complete, and coherent requirements.

gfvalvo:
A “Base 10” and “Base 16” what?

I’m assuming it would be an integer. I say this because of this:

byte SendByte[1] = 0x83;

Serial.print(SendByte[1]);

// results in the number 131 on the Serial Monitor

And if I do this:

byte SendByte[1];
int SendInt[1];

SendInt[1] = 23;
SendByte[1] = SendInt[1]; <-- this is the conversion I need to equal 17 and don't know how to get there.

Serial.print(SendByte[1]);

// results in the number 23 on the Serial Monitor

The problem is that I need to find that resulting numeric representation of 0x83 (i.e. 131), just like 0x17=23. I don’t know the word I’m looking for here or the function that will produce the correct value (probably where I was attempting to use sprintf() with “0x%02X”, cuz I thought, hey, that’s what I need for a final result in SendByte[1]. I obviously screwed the pooch on that one. I want to say hex to dec, but that doesn’t seem to be it either. If I could just find the correct terminology for what I want(need) to do, I’ll Google it and learn. And if it is, hextodec, I’m screwed cuz I’ve read 20 pages of that and can’t apply it correctly and why I started this thread.

It’s really hard to help if you don’t provide clear, complete, and coherent requirements.

I honestly try to. What sounds clear and concise to me, is jibberish sometimes to others. (i.e. this topic). LOL

byte SendByte[1] = 0x83;

Serial.print(SendByte[1], HEX);

// results in the number 83 on the Serial Monitor

So

SendInt[1] = 23;
Serial.print(SendInt[1], HEX);

// results in the number 17 on the Serial Monitor
byte SendByte[1];
....
SendByte[1] = SendInt[1]; <-- this is the conversion I need to equal 17 and don't know how

A one element array doesn’t have an element with the index 1

peasoup:
I’m assuming it would be an integer.

Again, if it’s an integer, there is no concept of decimal or hex. It’s just a value. Values are just groups of electrical charges in the processor organized and interpreted as a binary number.

As soon as you start talking about decimal and hex, that’s a human-readable representation. That mean ASCII characters. Serial.print() sends ASCII characters to the serial monitor.

TheMemberFormerlyKnownAsAWOL:

byte SendByte[1];


SendByte[1] = SendInt[1]; ← this is the conversion I need to equal 17 and don’t know how



A one element array doesn't have an element with the index 1

I just figured that out with this:

int SendInt[0] = 123;

    Serial.println(SendInt[0]);
    SendInt[1] = SendInt[0] / 100;
    Serial.println(SendInt[1]);
    SendInt[2] = SendInt[0] % 100;
    Serial.println(SendInt[2]);

    SendByte[2] = (SendInt[1], HEX); <-- Just for giggles to see what results
    SendByte[3] = (SendInt[2], HEX); <-- Same here

    Serial.println(SendInt[1], HEX);
    Serial.println(SendInt[2], HEX);
    Serial.println(SendByte[2]); 
    Serial.println(SendByte[3]);

    }

  SendByte[1] = 0x83;
  Serial.println(SendByte[1]);

Results in this:

07:31:45.833 -> 123
07:31:45.833 -> 1
07:31:45.833 -> 23
07:31:45.833 -> 1
07:31:45.833 -> 17  <-- The desired result from Serial.println(SendInt[2], HEX)
07:31:45.833 -> 16  <-- When I try SendByte[2] = (SendInt[1], HEX) 
07:31:45.833 -> 16  <-- and SendByte[3] = (SendInt[2], HEX)
07:31:45.833 -> 131 <-- Serial.println(SendByte[1]) when SendByte[1] = 0x83

int SendInt[0] = 123;…and a zero element array has no elements at all.
Not even one with the index 0.

I just figured that out with this:

…means “all bets are off”

TheMemberFormerlyKnownAsAWOL:

int SendInt[0] = 123;

...and a zero element array has no elements at all.
Not even one with the index 0.
..means "all bets are off"

I included the SendInt[0] to show how I got to SendInt[2] of "23'. I don't understand why '16' is the result and not '17' especially when it puts '16' for both the values of '1' (SendInt[1]) and '23' (SendInt[2]). Since then, I've found that no matter the value I put for SendInt[1] or [2], it puts '16' in there. So what I thought was a 'discovery', is moot.

You can’t put values into memory you don’t own.

Maybe this will help:

void ShowValue(int value)
{
  Serial.print("In decimal: ");
  Serial.print(value, DEC);  // DEC is the default if not specified
  Serial.print("\tIn hexadecimal: 0x");
  Serial.println(value, HEX);
}


void setup()
{
  Serial.begin(115200);
  
  int intA = 123;
  int intB = 23;
  int intC = 0x83;
  ShowValue(intA);
  ShowValue(intB);
  ShowValue(intC);


  byte byteA = 123;
  byte byteB = 23;
  byte byteC = 0x83;
  ShowValue(byteA);
  ShowValue(byteB);
  ShowValue(byteC);
}


void loop() {}

Resulting output:

In decimal: 123	In hexadecimal: 0x7B
In decimal: 23	In hexadecimal: 0x17
In decimal: 131	In hexadecimal: 0x83
In decimal: 123	In hexadecimal: 0x7B
In decimal: 23	In hexadecimal: 0x17
In decimal: 131	In hexadecimal: 0x83