ASCII? Decimal? Binary? what the heck is going on here?

Hey all,

I’ve read, am reading, and will continue to read, but this still eludes me. I’ve done plenty of programming before, but I’ve never had the need to convert between character representations before. And for some reason, I just can’t seem to grok this, so I’m reaching out for some help.

It’s probably best to start with my code:

bool isDone=false;

byte someData[] = {
    B01100110,
    01100110
};

void setup() {
  Serial.begin(9600);
}

void loop() {
  if(!isDone){
    Serial.println(someData[0]);        // Yields       102
    Serial.println(someData[0],DEC);    // Yields       102
    Serial.println(someData[0],HEX);    // Yields        66
    Serial.println(someData[0],OCT);    // Yields       146
    Serial.println(someData[0],BIN);    // Yields   1100110
    Serial.write(someData[0]);          // Yields         f
    
    Serial.println("\n===================");

    Serial.println(someData[1]);        // Yields        72 - wth? Where'd *this* come from?
    Serial.println(someData[1],DEC);    // Yields        72 - Ok, I get this one
    Serial.println(someData[1],HEX);    // Yields        48 - Yup, makes sense too
    Serial.println(someData[1],OCT);    // Yields       110 - Still with ya
    Serial.println(someData[1],BIN);    // Yields   1001000 - I even get this
    Serial.write(someData[1]);          // Yields         H - And yah, 72 is "H", but *where* did I ask for a "letter" to be printed??
    isDone=true;
  }
}

Now, I get that the first element (B01100110) is a binary number by virtue of the prefix “B”, and as expected, Serial.print() displays 102. But I’m just not understanding how the second element (01100110) is 72 (in decimal.) How’d that happen? Could anyone provide me an analogy, a mental model you use, or an explanation of why I’m seeing those results?

And on a related subject, I understand that Serial.print() is a sort of a convenience function for Serial.write(), but why am I seeing the ASCII representations instead of a “number”? I’m guessing that the serial console that I’m using received the “number” and decided to display a letter “f”, or “H”? I understand that 102=“f” and 72=“H”, but I don’t see where I instructed anything to display a letter!

As you can see, I’m very confused about this, so I’m hoping to maybe get some references to articles, or analogies, or anything that has helped you understand how these conversions work…something that I haven’t read yet (e.g. ALL of the articles that Google’s returned about this subject)…

I look forward to your replies.

The leading 0 in 01100110 tells the compiler to treat the number as octal which is 294964 decimal. This is too big to fit in a byte so only the 8 least significant bits are used. These are decimal 72!

stowite:
The leading 0 in 01100110 tells the compiler to treat the number as octal which is 294964 decimal. This is too big to fit in a byte so only the 8 least significant bits are used. These are decimal 72!

I imagine it would have to be a leading "O" for octal. I suspect that 01100110 is treated as the decimal number 1100110

...R

Leading zero for octal

Robin2:
I imagine it would have to be a leading “O” for octal. I suspect that 01100110 is treated as the decimal number 1100110

…R

No not “O” - One last time - the leading zero tells the compiler that it is an OCTAL number not a DECIMAL number. This is standard C/C++ syntax .

stowite:
No not "O" - One last time - the leading zero tells the compiler that it is an OCTAL number not a DECIMAL number. This is standard C/C++ syntax .

I bow to your superior knowledge.

But how stupid is that system.

...R

But how stupid is that system.

I'm sure that someone, somewhere, thought it was a good idea at the time.

Robin2:
But how stupid is that system.

...R

To my mind not as stupid as allowing b10101010 be a binary constant value since b10101010 could conceivably be a variable name ! I always use 0b10101010 which has no ambiguity.

B01100110
0146
0x66
102
and
CII

Are all different ways of writing the same number, although the C compiler doesn’t understand that last one.

although the C compiler doesn't understand that last one.

Nor did most Romans.

PaulMurrayCbr:
the C compiler doesn't understand that last one.

... or the first one without some assistance, like defining a macro.

B0000...
is not STD C or C++, is defined in Arduino framework.
And work only for 8bit.
forget it!

Ah, I see now why I was getting the results that I did. And this discussion sure brought to light the confusion of having a leading zero can cause. Well, I won't be making that same mistake again.

Still, my questions remain. Specifically, with regard to Serial.write(), and any articles that have helped you understand data representations.

I modified the program a bit to remove that leading zero, and I’m still not sure how I got the values in the second set:

bool isDone=false;

byte someData[] = {
    B11100110,
    11100110
};

void setup() {
  Serial.begin(9600);
}

void loop() {
  if(!isDone){
    Serial.println(someData[0]);        // Yields       230
    Serial.println(someData[0],DEC);    // Yields       230
    Serial.println(someData[0],HEX);    // Yields        E6
    Serial.println(someData[0],OCT);    // Yields       346
    Serial.println(someData[0],BIN);    // Yields  11100110
    Serial.write(someData[0]);          // Yields         � - Sure, this makes sense - sorta
    
    Serial.println("\n===================");

    Serial.println(someData[1]);        // Yields       206 - wth? Where'd *this* come from?
    Serial.println(someData[1],DEC);    // Yields       206 - Ok, I get this one
    Serial.println(someData[1],HEX);    // Yields        CE - Yup, makes sense too
    Serial.println(someData[1],OCT);    // Yields       316 - Still with ya
    Serial.println(someData[1],BIN);    // Yields  11001110 - I even get this
    Serial.write(someData[1]);          // Yields         � - And yah, 206 is "something", but *where* did I ask for a "letter" to be printed??
    isDone=true;
  }
}

andrius_d:
I modified the program a bit to remove that leading zero, and I'm still not sure how I got the values in the second set:

byte someData[] = {

B11100110,
    11100110
};

The number 11100110 (eleven million, one hundred thousand, one hundred and ten) will not fit in a byte. If you try to make it fit, you will get garbage.

OH! Ok, this is starting to sink in now. Thanks! I guess I had too many dumburgers for lunch yesterday . . .