There are other features that I want todiscuss (I've already implemented them; it's just a matter of whether or not to remove them):
Attached you'll find the Print.h file, which has macro definitions at the beginning that can be commented out to disable individual features; as well as the Print.cpp file (for AVR, not SAM). These macros and all the #ifdef would be removed on the final code I put on the PR.
What do you think? Any opinions on which features should or shouldn't go here, or any other comment? I think this could improve the user experience considerably.
For this reason, I always use printf if I can afford the memory.Is it possible to do number formatting such as zero or space padding ?Although the existing syntax is painful, its worst feature is the inability to print columns of aligned values.
--
You received this message because you are subscribed to the Google Groups "Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email todevelopers+unsubscribe@arduino.cc.
I use printf 99.9% of the time.
--
You received this message because you are subscribed to the Google Groups "Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email todevelopers+...@arduino.cc.
From a beginner’s point of view, I think the most valuable addition to print and println would be a Java/JavaScript-style ability to string multiple substrings and variables together with +. e.g.:int SensorOne = analogRead(A0);int sensorTwo = analogRead(A1);Serial.println(“sensor 1: “ + sensorOne + “\tsensor 2: “ + sensorTwo);orint red = analogRead(A0)/4;int green = analogRead(A1)/4;int blue = analogRead(A2)/4;Serial.println(“<body bgcolor=\”#” + hex(red) + hex(green) + hex(blue) + “\”>);I’ve taught beginners in different programming languages, and of all the ones I’ve dealt with, that style is the one that comes most naturally to novices. Adding that without adding significantly to the memory footprint of the functions would be the biggest improvement. It’s the one thing about print/println that I get asked for most often.
To unsubscribe from this group and stop receiving emails from it, send an email to developers+unsubscribe@arduino.cc.
--
You received this message because you are subscribed to the Google Groups "Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email todevelopers+unsubscribe@arduino.cc.
From a beginner’s point of view, I think the most valuable addition to print and println would be a Java/JavaScript-style ability to string multiple substrings and variables together with +. e.g.:
Serial.println("sensor 1: " + sensorOne + "\tsensor 2: " + sensorTwo);
I have to point out that, as can be seen inavr-gcc documentation for *printf, the implementation is rather weak: it doesn't handle %f specifiers the way Arduino uses it (displays ? instead) and it lacks other printf features such as *, plus some minor things (e.g. printf("%hhX", -1) prints FFFF; it should print FF). So it's not like printf will be a full replacement for print, and C users may find it's not what they're used to. But it still works for simple things such as integer formatting.
I think having hex(num, [width]) and base(num, radix, [width]) would be the way to go.
Then again, that doesn't give much freedom specifying arbitrary formatters; another option is stringing formatters like hex(num).width(8).digits(5).withSign() (sadly C++ doesn't allow the optional argument syntax other languages such as Python do), or pushing them as dummy arguments that modify how Serial behaves (kinda like std::cout) but that option feels weird.
A (probably inefficient) idea for a format function:
format(num, "width", 3, "base", 16)
(returns num formatted as a String in base 16 padded to 3 digits)
#define DIGITS <<8 // minimum width (chars; not necessarily digits)
#define ZEROS 0x00 // pad with zeros (default)
#define SPACES 0x80 // pad with spaces
#define SIGN 0x40 // always +/- sign
#define HEX 16 // base 16, etc
Serial.print(n, HEX | ZEROS | 6 DIGITS);
This allows combining base (6 bits), '0' flag (1 bit), '+' flag (1 bit), and width (8 bits) into a single 16-bit int field. For floats/doubles, base is replaced by decimals (up to 63, might be a bit short).
(This doesn't solve the problem of print(n, attributes) being a bit weird combined with other print(string1, string2) calls which just print 2 things, though.)
string foo;
Serial.print(foo=....);
Serial.print((string)....);
--
You received this message because you are subscribed to the Google Groups "Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to developers+unsubscribe@arduino.cc.
Some pros and cons of printf (functionality):
Pros:
- It's existed for decades, so it's well known and broadly documented.
- C programmers are used to it.
- It's already there; there's no need to reimplement it (unless there's a good reason for it such as efficiency).
- It provides plenty of formatting features in a compact manner.
- It teaches how to use printf (although Arduino is more about teaching programming than C specifically).
Cons:
- It doesn't allow printing non-POD objects such as Arduino Strings directly (a solution for this might be to add a variadic template wrapper that adds .c_str() before calling printf).
- Its syntax looks rather weird to new users.
- It requires a format string; you can't print a variable directly as Serial.print allows.
- It doesn't allow printing binary or arbitrary bases.
- avr-gcc's implementation of printf is limited (small too, nevertheless).
Conclusion: Serial.printf would be a good thing to have because of formatting, but Serial.print is more convenient from an ease of use point of view (specially if the variadic thing I proposed is implemented), therefore both methods should coexist.
I think the way to go is to implement Serial.printf (in an efficient way, if you want) AND improve Serial.print (I may be biased but I think my idea of including formatting flags into the `base` parameter may be good).
By the way, if creating custom file descriptors is as easy as you say, it may be a good idea to make a Print::operator FILE*() method so that you can just call fprintf(Serial, ...), fputs(str, Serial), etc.
What I think is that implementing it properly using callback functions and custom FILE objects would be important.
I think I'm going to drop that feature from this "project" and move it to a separate one; it deserves its own PR and is independent from the variadic template thing anyway (both can be implemented as separate PRs).
I'm also going to forget about adding formatting capabilities to the `base` parameter *for now* for a similar reason; it doesn't affect the rest of the idea and can be implemented separately. (Also it would require modifying WString.cpp as well.) But I still think it should be done, since there seems to be quite some interest in adding extra formatting capabilities to Serial.print.
Gabriel,
What you propose is very limited and requires modification for every individual usage case. IMO, it is not a good solution.
There are much better ways to get xxprintf() style formatted output within the C++ Arduino environment.
For example using the power of C++ and the Arduino Print class it is reallytrivial to make a function that works like fprintf() but uses Print class objects.
Here is the code for a simple function called Printf() that works just like fprintf() but uses a Print class object instead of a FILE pointer.
size_t Pprintf(Print &outdev, const char *format, ...)
{
char buf[128];
va_list ap;
va_start(ap, format);
vsnprintf(buf, sizeof(buf), format, ap);
va_end(ap);
return(outdev.write(buf));
}
This function would will work with any object that uses the Print class, which includes pretty much any Serial, LCD, GLCD, LED matrix libraries, etc..
Essentially, anything that currently supports print() will work with the Pprintf() function above.
and here is a working sketch that demonstrates how to use it with the Serial object.
void setup(void)
{
Serial.begin(115200);
Pprintf(Serial, "Pprintf...\n");
}
void loop(void)
{
Pprintf(Serial, "Seconds up: %04ld\n", millis()/1000);
delay(1000);
}
size_t Pprintf(Print &outdev, const char *format, ...)
{
char buf[128];
va_list ap;
va_start(ap, format);
vsnprintf(buf, sizeof(buf), format, ap);
va_end(ap);
return(outdev.write(buf));
}
And here is a bit of rant on the topic of the Arduino Print class.
From a larger perspective, IMO, the only reason not to have a printf() method built into the bundled Print class provided by the Arduino IDE is obstinance on the part of certain key Arduino developers. Yeah I know that is a pretty harsh assessment, but that is my opinion.
At this point in time, the xxprintf() formatting routines have existed for 50 years.
They are very well documented and understood and examples on how the formatting string works are literally everywhere.
Many people have been asking for it on Arduino for many years.
This playground page has existing for around 6 years:https://playground.arduino.cc/main/printf
Also, several 3rd party cores have already added a printf() method to their Print class. Cores like Teensy/Teensy3, Chipkit, and ESP.
Even if very green/newbie Arduino users find it complicated or too complex for them, they don't have to use it and it won't eat up any code space in their images.
But in reality with a small bit of coaching and a bit of googling, I believe that even a newbie should be able to easily figure out how to use it.
So at this point in time, I really don't understand why there is still so much resistance to adding a printf() method to the Print class.
--- bill
--
I seem to recall there was a language that had print formats in the form of an even more specific template than printf - something like nnnnn.nn. I forget what it was. A quick scan of Python, Pascal and several FORTRANS didn't find it but did confirm that there is nothing in common use that's better than printf. Just messier ones.
--
You received this message because you are subscribed to the Google Groups "Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email todevelopers+...@arduino.cc.
To view this discussion on the web visithttps://groups.google.com/a/arduino.cc/d/msgid/developers/CAH1-q0hNsssYOAM%3DZEej471hJOKtjAOL5DhTQdpSM7mHUkpCtA%40mail.gmail.com.
To view this discussion on the web visithttps://groups.google.com/a/arduino.cc/d/msgid/developers/067BEFA0688749578132D845346329E6%40JohnDoughPC.