Pages: [1]   Go Down
Author Topic: 3-line printf-style hack  (Read 1380 times)
0 Members and 1 Guest are viewing this topic.
Bangalore, India
Offline Offline
Jr. Member
**
Karma: 0
Posts: 77
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

There are times (usually debugging) when I really hate having to type lines and lines of stuff like this:

Quote
Serial.print("a = ");
  Serial.print(a, DEC);
  Serial.print(", b = $");
  Serial.println(b, HEX);
...and I just wish I had a proper printf() type of function for writing to the serial port.

Well printf and friends are actually in the AVR libc library so here's a 3-line hack to give a printf-like function, which would ideally be incorporated into Serial already as Serial.printf().

Quote

 
#include <stdio.h>
char _str[32]; // 32 chars max!  increase if required to avoid overflow
#define writeln(...) sprintf(_str, __VA_ARGS__); Serial.println(_str)

int a = 2, b = 3;

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

  writeln("We're using writeln here\n");

  writeln("a = %d, b = %d, a+b = %d", a, b, a+b);
}

void loop() {
  for (int i = 0; i < 256; i++) {
    writeln("i = %3d ($%02x)", i, i);
    delay(200);
  }
}

I've found this useful so I'm presenting it here purely as a convenient hack...

Disadvantages are that it would be easy to overflow the _str[] buffer, but I've kept it small to save space (it's easy enough to make it bigger).  Also that the vfprintf() library uses quite a lot of memory, but for smaller sketches there may be times when it's worth the trade-off.

Flames to /dev/null, as we used to say.... ;-)

Docs for printf/sprintf/vfprintf are here: http://www.nongnu.org/avr-libc/user-manual/group__avr__stdio.html#ga3b98c0d17b35642c0f3e4649092b9f1
« Last Edit: April 24, 2008, 11:40:33 am by mungbean » Logged

London
Offline Offline
Tesla Member
***
Karma: 10
Posts: 6255
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Oh man, I am not sure that information will be a help or hindrance to those not already familiar with sprintf and the murky consequences of buffer overflow.

It's worth re-emphasizing that its really easy to overflow the buffer, the compiler gives absolutely no warning of this and the runtime consequences are difficult to predict. Its about the worst thing that can happen if you are trying to debug code that isn't working.

Unless one enjoys living dangeriously, or is in full command of how the sprintf arguments will be expanded,  my advice is to spend a few extra seconds typing those compound Serial.print statements  smiley-wink
« Last Edit: April 24, 2008, 11:14:14 am by mem » Logged

Bangalore, India
Offline Offline
Jr. Member
**
Karma: 0
Posts: 77
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Unless one enjoys living dangeriously,

I believe I used the work "hack" in bold. smiley-wink

So what's chances of a Serial.printf() then?  Is there any good reason not to have it, apart from the size of the library?
Logged

Forum Administrator
Cambridge, MA
Offline Offline
Faraday Member
*****
Karma: 12
Posts: 3538
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

The library is big, the syntax is obscure (especially compared to the core Arduino API), the syntax is different from the equivalent functionality in Processing, and it could be tough to implement properly in a memory-constrained environment (e.g. what do you we do if we don't have enough space for a buffer big enough to hold everything someone wants to print).  Plus, the existing Serial API can do pretty much anything printf() can, it just takes a bit more text.  I like the idea of making printf() easy for advanced users to hack into their code, but I'm wary of including it in the API.
Logged

Underhill Center, Vermont, USA
Offline Offline
Jr. Member
**
Karma: 0
Posts: 71
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Good show, just one small comment ....

You call it "writeln()" and use  "Serial.println()", wouldn't it be more appropriate to call "Serial.print()" and put in the '\n' yourself ... if, where, and when you want it????

Buffer overflow considerations aside, I want it for formating stuff to LCD displays, where a 20-40 byte buffer is all I need and if I ain't payin attenshun to my line size I deserve whatever I get!!!!!

Thanks for a good idea ...

cheers ... BBR

Logged

Bangalore, India
Offline Offline
Jr. Member
**
Karma: 0
Posts: 77
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
You call it "writeln()" and use  "Serial.println()", wouldn't it be more appropriate to call "Serial.print()" and put in the '\n' yourself ... if, where, and when you want it????

yeah good point.

I think with 'writeln' i was subliminally harking back to days of Pascal  smiley-wink

Logged

Underhill Center, Vermont, USA
Offline Offline
Jr. Member
**
Karma: 0
Posts: 71
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

There now seems to be a proble in Arduino 0011 invoking stdio.h ... see this  thread http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1213815025

cheers ... BBR

Logged

Bangalore, India
Offline Offline
Jr. Member
**
Karma: 0
Posts: 77
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

put this...

#undef int

before the #include <stdio.h>

it's a problem with v11, which redefines int for some reason which I forget.

Logged

Pages: [1]   Go Up
Jump to: