Serial.print, HEX and indent

I had a need to work with 64-bit unsigned integers. However, printing on serial port is not available and printing 32-bit parts can not be indent.

I'm missing the point to print hex numbers without indent according it physical length. Simple printing this way require custom code and additional string buffer to override this.

Or simply I missing important notes from serial lib documentation.

void setup() {

  Serial.begin(115200);

  uint64_t m=0xAABBCCDD0000EEFF;

  //Serial.println(m,HEX); // Still not supported

  uint32_t m1 = m>>32;
  uint32_t m2 = m;

  Serial.print("0x");
  Serial.print(m1,HEX);
  Serial.print(" ");
  Serial.println(m2,HEX); 


  // Result: 0xAABBCCDD EEFF

  // Upper require additional code to print as 0xAABBCCDD 0000EEFF

}

void loop() {  

}

No, you are missing nothing, Serial.print prints up to 32bit without any formatting. If you need formatting then printf you should use (stdio.h) but 64bit is out (I think). Probably, you have to write your own code.

If you use printf/sprintf, you can probably do

 printf("%x%08x", m1, m2);

(You'll always get 9 digits, though, even in m1 is 0 and m2 is small.)

westfw: If you use printf/sprintf, you can probably do

 printf("%x%08x", m1, m2);

(You'll always get 9 digits, though, even in m1 is 0 and m2 is small.)

Thank you, but solving this is not the issue. I already have many low level functions wrote by myself especially for AVRs respecting speed and storage. Printf or sprint costs too much of both.

Unless I missing the title "Suggestions for the Arduino Project", this should be suggestion for Arduino team to make a progress.

Why this is moved to "Project Guidance"?

It is suggestion to Arduino team to make necessary modifications.

There was nothing in the initial post to suggest that.

Simple printing this way require custom code

Agree.

and additional string buffer to override this.

Disagree

Printf or sprintf costs too much of both.

Fair enough. Although I hear that 64bit math is pretty bloated as well :-)

Unless I missing the title "Suggestions for the Arduino Project", this should be suggestion for Arduino team to make a progress.

So the suggestions are: 1) print class should support 64bit integers 2) print class should support more extensive formatting. In particular, hex output should support leading zeros so that you can string together arbitrary length numbers.

I don't think that those are likely to happen in a way that you'd like. For 1, there is the rarity of 64bit integer use in the Arduino community, plus the previously-mentioned bloat and slowness of 64bit AVR math. (2) has been done by 3rd parties, usually by having the print class call sprintf() "I don't want all of printf, just this one feature" always tends to grow uncontrollably until you have code that is bigger than printf() :-(

How about Serial.hexprint(uint8_t *p, size_t *len) ? That at least has, um, bounded complexity, and perhaps general usefulness for debugging all sorts of dataBuffer-like structures... (and it's pretty trivial to implement.)

westfw: Although I hear that 64bit math is pretty bloated as well :-)

I have not tested it deeply, as I have needed only addition and shifting for uint64_t. Should be maximally fast coded, but only disassembling will show...

westfw: So the suggestions are: ...

Yes.

However, I have looked Arduino code and generic method printNumber and I have nothing else to say - I will stick with my own functions.

Printf or sprintf costs too much of both.

Fair enough.

I may have to retract that. sprintf() seems to add about 1.5k to the final elf file, comparing:

Serial.print(along, HEX);

to

sprintf(buf, "%08x", along); Serial.print(bug);

That's not bad (and it gets better, the more types you print. Because sprintf() is monolithic, while Serial.print() brings in functions as they are used...)

westfw: I may have to retract that. sprintf() seems to add about 1.5k to the final elf file, comparing:

...

That's not bad (and it gets better, the more types you print. Because sprintf() is monolithic, while Serial.print() brings in functions as they are used...)

:)

Dedicated custom made function in comparison with KBs costs nothing. Really, really, bad choice...

This is retro computers like range ROM and RAM world, where any byte and CPU clock counts. For me, it is an art rather than challenge to make all ideally respecting need, space and speed. That is actually primary reason why I started to play with micro-controllers.

As I said, I will not submit not comment anymore any Arduino coding.

Have a look at the PrintEx library. It is an amazing library. It can wrap existing classes to implement a printf() function. It actually calls the Print class so it it is better than a typical printf() implementation. Plus since it is a wrapper class it wraps the existing objects to to give you things like:

Serial.printf(....)

Unfortunately, the examples that come with the library are pretty lacking and the documentation is a bit behind.

Here is a bit of code I pulled from one of my example sketches that uses PrintEx that will do some magic to create a wrapper class but still allow you to use the "Serial" object name in all your existing code:

#include  // include for the PrintEx library
// This can also be used on any existing Print class object like Serial.
// However, to use it transparently, it requires doine some "magic" foo:
// - create a new object (in this called __Serial) that wraps the existing
//   Serial object 
// - use a cpp macro to map the name "Serial" to "__Serial" so that the 
//   sketch code can think it is using Serial object but is actually
//   using the wrapped object named __Serial
//
// This will add the printf() method to "Serial"

PrintExWrap &__Serial = PrintEx::wrap(Serial);
#define Serial __Serial

Then you can use Serial.printf() in your code and use most of the normal printf formatting types including floating point (which you don't get by default on AVR) see the PrintEx documentation for more.

--- bill