Print commands are not consistent

I have used the Serial.print() command:

int aValue=32;
Serial.print(aValue); //give you "32"
Serial.print((uint8_t)aValue); //give you a space " "

Do this make a sense?

In my opinion each normal call should reply the bytes (byte by byte for long data types). Print with special bases should be switched on with second parameter in all cases.

It makes complete sense as it's currently implemented. Print of an 8 bit character prints the character. Print of a 16 or 32 bit value prints the value. It may seem odd to have the apparent behaviour change but it would be very strange to have print('a') print anything other than the character a.

Yes, it makes sense. the 32 is not a number anymore... it is ASCII character for "3" and then for "2". You think you sent the value of 32... but you sent ASCII code for "51" then "50" when using the PRINT statement.

SERIAL TRANSMISSION sends ASCII codes so that's what Serial.print does.


Nonsense; it sends binary. ASCII only defines 128 codes, but serial transmission allows you to transmit 256 different values.

The behaviour the OP has raised is not about ASCII, extended ASCII or binary. Its about the way Arduino print routines differentiate on the type of value passed to the print function.

When printing a char or byte, Arduino will send this as a single byte (it doesn't care if its ASCII or not). When printing a 16 or 32 bit integer or a float, it will send this as the string of characters that represent the value.

If the receiving side displays these as ASCII values (as does the Arduino Serial Monitor) you would see the (extended) ASCII value of a printed character (or byte), or the numerals representing the value of integers or floats.

Serial.print(aValue,BYTE); //is confusing because BYTE=0 and this base couldn't handled with mathematical correctness

Next Problem: In actual arduino this will print for types with n x byte (int, real, float, double etc.) only the first byte!

My suggestion: Serial.print(aValue); //should always and ever send bytes Serial.print(aValue,DEC); //should send a number as ASCII-Char Serial.print(aValue,HEX); //should send a number as ASCII-Char Serial.print(aValue,8); //should send a number as ASCII-Char

DEC=10, HEX=16

Following this logic you don't need anymore the base BYTE (=0)!

I think it works well just as it is. The parameter when non zero is treated as the base used to display value, and when zero the character rather then the value is displayed.

I think most Arduino users would be surprised if the following did something other than print the digits “1234” to the serial monitor. int value = 1234; Serial.print(1234);

If I understand your suggestion, your version would print whatever is the ascii value of 0xD2 – which is not what I think most Arduino users would want to see.

I would be surprised now that I know what is supposed to happen. I’m not that fluent in c/c++ so I don’t know if Arduino’s behavior is logical or not.

I’ll have to admit, I found it very counter-intuitive at first.

what would you have expected this code to do? int value = 1234; Serial.print(1234);

I think I would have either expected an error or have it truncated to 0xd2. To me, a serial device is byte oriented and I would expect to have to do something special to have it print a character string.

I'm not complaining, mind you. :)

That example was meant to be int value = 1234; Serial.print(value);

I guess your expectation would be the same.

But would you expect int value = 1234; lcd.print(value); to truncate to 0xd2 ?

would you want it to?

Only because I know that the LCD class derives from Print. Otherwise, I wouldn’t expect it to do anything until I wrote a driver.

?Otherwise, I wouldn't expect it to do anything until I wrote a driver.

I think many of the design decisions taken by the Arduino team were to ensure that users did not need to know what a driver was, let alone think about writing one ;)

Those of us that do understand the plumbing should accept that we are not the primary audience for Arduino


My background is in embedded controller/processor design and while I have written nE5 lines of assembly language having any kind of high level language support has always been a luxury. The c compilers available for 8/16 bit chips usually concentrate on port and bit manipulation and if they do arithmetic at all it's normally integer only.

Consequently, Arduino is a real M-series in my opinion and for the tasks it was designed to do, I wouldn't use anything else.

The fact that some things seem a little nonintuitive to me is of no consequence, as they are quickly learned. I discovered a long time ago that it's more productive to use the tools you have than to piss and moan about the ones you wish you had. Besides, tomorrow is another day. ;)

I think the OP is trying to illustrate the inconsistency of the "print" method overloading. Specifically, the difference between "print"ing an int versus a uint8_t.

I've already experienced this problem. Here is some more code to clarify the problem:

uint8_t mybyte;         // this is UNSIGNED
int myword;             // an int is 16bits - explicitly: int16_t (from stdint.h)

myword = 32;
mybyte = myword;

Serial.print(myword);   // prints "32" - as expected
Serial.print(mybyte);   // prints " " - not exactly intuitive

Herein lies the problem: What do you do with a byte? Since a byte === unsigned char, do you print it as a series of characters in a readable format representing the number (e.g. "32")? Do you send the direct value of the byte over the serial connection? It's unclear, because the data type is ambiguous.

A more clearly defined Print Base Class would solve this problem.

For example, for consistency, Print::print(uint8_t n) should be:

void Print::print(uint8_t n)
  print((long) n);

and for clarity, a new method should be added:

void Print::printchar(char c)

Unfortunately, this will break a LOT of current code, since people have already accepted that Serial.print((uint8_t)32) prints a space.

The OP is saying that instead of assuming that "print"ing a uint8_t means to send a direct value over the serial connection, it should be "print"ed in the same way as a long value. Furthermore, the OP is saying that to print a byte directly, it should be explicit, e.g. print(mybyte, BYTE). I'm not complacent with that format (if anything BYTE should be changed to DIRECT - semantically differentiating the methods). "print" should be consistent - i.e. always printing readable characters or such.

Again, this will break a lot of code.


I think the OP is confused as to the difference between "print"ing an int versus a uint8_t.

I don't think the OP was confused about the difference, he wanted a different behaviour – for similar reasons to the one you posted.

I would think that the current Arduino behaviour was borrowed from Processing. Those familiar with Java will be comfortable with the way it works now. There are a few things that Arduino borrowed from Processing that seem odd to C/C++ programmers but the underlying principle has been do make Arduino intuitive to non-technical people and I think the way print works now does that better then the more rigorous behaviour being proposed in this thread.

Anyway, changing the behaviour would break existing code so I think we need to get used to it.

FWIW, I don't think anything rigorous was proposed. It's purely semantical. It's about interface consistency - which is HIGHLY desirable for newcomers.

Try telling someone new to the Arduino community that this works as expected:

int myvar = 32;

Serial.print(myvar);  // prints out "32"

whereas this doesn't:

byte myvar = 32;

Serial.print(myvar);  // prints out a space

I don't want to dwell on this, because it would take enormous effort to have the current Print class changed (even though it's a tiny change). We have to live with the quirks in the system. It wouldn't be life if we didn't!


It's purely semantical. It's about interface consistency - which is HIGHLY desirable for newcomers.

Try telling someone new to the Arduino community that this works as expected: int myvar = 32; Serial.print(myvar); // prints out "32" whereas this doesn't: byte myvar = 32; Serial.print(myvar); // prints out a space

I am happier telling someone new to programming that Serial.print(' '); Prints a space (not the number 32)

Granted. PROVIDED they wanted to print a space.


In my experience people new to programming expect Serial.print('A'); to print the character A