No cost streams

So I found myself wanting to have line feeds after printing my variables for easier use over the serial monitor. I added one more piece (show here in bold) to Mikal’s code as to make it a bit more like the C++ std library in this regard:

template inline Print &operator <<(Print &obj, T arg) { obj.print(arg); return obj; }

enum EndLineCode { endl };
inline Print &operator <<(Print &obj, EndLineCode arg) { obj.print(13, BYTE); obj.print(10, BYTE); return obj; }

With this you can do something like:

Serial << "Value printing on line one: " << value << endl << "Value2 printing on line two: " << value2 << endl;

Which prints out

Value printing on line one: 100
Value2 printing on line two: 200

This also takes the same amount of space as just writing a println (or writing out the CR & LF combo separately), so there’s no overhead with doing it this way.

I could add to the playground page if it’s useful.

Cheers,
Paul

Very good stuff. I’ll add it to my web page and the playground. Although wouldn’t this be better:

inline Print &operator <<(Print &obj, EndLineCode arg) { obj.println();  return obj; }

?

Mikal

Ah, yeah. I didn't realize you couldn't call println with no arguments. Yes, that's better.

-Paul

Thanks to Paul V. and Ben Combee for their useful suggestions on how to support line endings (C++ “endl”) and internal format manipulators, respectively, we now have a bona fide Streaming library.

With it, you can now write code like this:

  Serial << "A is " << lettera << "." << endl;
  lcd << "The current date is " << day << "-" << month << "-" << year << "." << endl;
  
  eth << "You can use modifiers too, for example:" << endl;
  Serial << _BYTE(lettera) << " is " << _HEX(lettera) << " in hex. " << endl;

And thanks very much for all the Arduinians who have used and commented on Streaming. Cool stuff.

The new library is available at http://arduiniana.org/libraries/streaming.

Mikal

Arduino version 0018 has added the capability to print floats specifying the number of digits after the decimal point.
Here is a modification to Mikal’s library to support this.

 /*
Streaming.h - Arduino library for supporting the << streaming operator
Copyright (c) 2009 Mikal Hart.  All rights reserved.

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

#ifndef ARDUINO_STREAMING
#define ARDUINO_STREAMING

#include <WProgram.h>

#define STREAMING_LIBRARY_VERSION 3  // modifed to support floating point digit argument - mem 20 Feb 2010

// Generic template
template<class T> 
inline Print &operator <<(Print &stream, const T arg) 
{ stream.print(arg); return stream; }

struct _BASED 
{ 
  long val; 
  int base;
  _BASED(long v, int b): val(v), base(b) 
  {}
};

struct _FLOAT 
{ 
  float val; 
  int digits;
  _FLOAT(double v, int d): val(v), digits(d) 
  {}
};

#define _HEX(a)     _BASED(a, HEX)
#define _DEC(a)     _BASED(a, DEC)
#define _OCT(a)     _BASED(a, OCT)
#define _BIN(a)     _BASED(a, BIN)
#define _BYTE(a)    _BASED(a, BYTE)

// Specialization for class _BASED
// Thanks to Arduino forum user Ben Combee who suggested this 
// clever technique to allow for expressions like
//   Serial << _HEX(a);

inline Print &operator <<(Print &obj, const _BASED &arg)
{ obj.print(arg.val, arg.base); return obj; } 

// Specialization for class _FLOAT
inline Print &operator <<(Print &obj, const _FLOAT &arg)
{ obj.print(arg.val, arg.digits); return obj; } 


// Specialization for enum _EndLineCode
// Thanks to Arduino forum user Paul V. who suggested this
// clever technique to allow for expressions like
//   Serial << "Hello!" << endl;

enum _EndLineCode { endl };

inline Print &operator <<(Print &obj, _EndLineCode arg) 
{ obj.println(); return obj; }

#endif

Thank you very much, mem. This is a nice improvement. I have posted your modifications as version 4 on the arduiniana website: http://arduiniana.org/libraries/streaming/.