Streaming

Streaming C++-style Output with Operator <<

Note: Streaming 5 is now Arduino 1.0 compatible.

New users sometimes wonder why the “Arduino language” doesn’t provide the kind of concatenation or streaming operations they have become accustomed to in Java/VB/C#/C++, etc.

// This doesn't work in Arduino.  Too bad.
lcd.print("The button was pressed " + counter + " times");

Meanwhile, experienced programmers chafe at having to synthesize streams with clumsy blocks of repetitive code like this:

lcd.print("GPS #");
lcd.print(gpsno);
lcd.print(" date: ");
lcd.print(day);
lcd.print("-");
lcd.print(month);
lcd.print("-");
lcd.println(year); // ugh!!

The Streaming library gives you the option of compressing those into “insertion style” code that, if not exactly the same, is reminiscent of the concatenation above:

lcd &lt;&lt; "GPS #" &lt;&lt; gpsno &lt;&lt; " date: " &lt;&lt;
    day &lt;&lt; "-" &lt;&lt; month &lt;&lt; "-" &lt;&lt; year &lt;&lt; endl;

This library works for any class that derives from Print:

Serial &lt;&lt; "Counter: " &lt;&lt; counter;
lcd &lt;&lt; "Temp: " &lt;&lt; t.get_temperature() &lt;&lt; " degrees";
my_pstring &lt;&lt; "Hi Mom!" &lt;&lt; endl;

With the new library you can also use formatting manipulators like this:

Serial &lt;&lt; "Byte value: " &lt;&lt; _HEX(b) &lt;&lt; endl;
lcd &lt;&lt; "The key pressed was " &lt;&lt; _BYTE(c) &lt;&lt; endl;

This syntax is familiar to many, is easy to read and learn, and, importantly, consumes no resources. (Because the operator functions are essentially just inline aliases for their print() counterparts, no sketch gets larger or consumes more RAM as a result of their inclusion.)

I hope someday that this simple template will become part of the Arduino core as a stylistic option to writing series of prints. In the meanwhile, I use it in every sketch I build now!

Download

The latest version of Streaming is available at Streaming5.zip.

Version

You can get the current version number of the library by inspecting STREAMING_LIBRARY_VERSION.

Page last updated on July 31, 2024 at 8:06 am
115 Responses → “Streaming”

  1. Johann

    14 years ago

    Great library!

    Had a small issue to stream PStrings: Serial << myPString;

    error: passing ‘const PString’ as ‘this’ argument of ‘PString::operator const char*()’ discards qualifiers

    Removing the “const” in line29 of streaming.h seems to work
    inline Print &operator <<(Print &stream, const T arg)
    inline Print &operator <<(Print &stream, T arg)

    A bit less type checking, but not sure if it has memory implications…

    -kellerza


  2. Mikal

    14 years ago

    Very nice (and important) find. Thank you.

    I’ll be posting a new version shortly.

    Thanks again.

    Mikal

    [6 January: Version 3 of Streaming now addresses this problem.] — mh


  3. Soilboy

    14 years ago

    Hi Mikal

    Love the library, I use it as standard now. However I have come across an issue when using it in conjunction with your Flash library.
    I get the following type errors if I include both Flash.h AND Streaming.h:

    error: ‘endl’ was not declared in this scope

    when trying to do the following:

    Serial << data << endl;

    It’s probably something to do with the multiple of overloads of << but I’m no expert. I was hoping you may be able to shed some light on the issue.

    Cheers

    Soilboy


  4. Mikal

    14 years ago

    Soilboy —

    Thanks for the feedback. Yes, there are one or two interdependencies between Flash and Streaming that I need to sort out, but for now the solution is to #include Streaming.h BEFORE Flash.h.

    Thanks for the kind comments! I use that Streaming library in every sketch myself! :)

    Mikal


  5. Godstroke

    14 years ago

    Hello, I’m getting an “no such file” error while including WProgram.h in Streaming.h why may that be? Thanks.


  6. Mikal

    14 years ago

    @Godstroke,

    Hmmm. I don’t know. What version of the Arduino software are you using?

    M


  7. fredde

    14 years ago

    only one word needs to be said : AWESOME


  8. Mikal

    14 years ago

    Hey, thanks Fredde! I find it useful.

    Mkal


  9. Edoardo

    13 years ago

    Hi, this lib is a God-sent gift!
    I have a question though: how can you choose how many digits of a float number print?
    I tried (floatNumber, 4) like you do in println(), but that doesn’t work.

    Edoardo


  10. Mikal

    13 years ago

    Hey, thanks, Edoardo.

    What you want to do in this special case is use this syntax:


    Serial << _FLOAT(floatNumber, 4);

    This prints the value with 4 digits of precision.

    Mikal


  11. scruss

    13 years ago

    Great stuff, Mikal!

    I know it would add code, but any chance of a _HEX(value, digits) to produce zero-padded values?


  12. Mikal

    13 years ago

    @scruss,

    I like the idea, but I think any code that makes rendering decisions is more properly placed in Print.cpp and not in Streaming.


  13. Brad

    13 years ago

    Thank you very much. Very useful to a beginner that is reading C and C++ books with a vengeance yet running up against “Arduino specific” roadblocks.

    Very much appreciated. :)


  14. Richard

    13 years ago

    Hi, I would like to serial print Data from six potentiometers, each split by the tab key “\t” and start a new line after the sixth reading. to look like this-

    10 90 120 30 40 50
    11 91 121 31 39 51
    12 92 120 32 38 52

    Is this possible with this library? Any advice is great?
    Thanks Richard.


  15. Mikal

    13 years ago

    Yup. Here you go:

    Serial << p1 << "\t" << p2 << "\t" << p3 << "\t" << p4 << "\t" << p5 << "\t" << p6 << endl;

    Mikal


  16. Basile

    13 years ago

    I tried using the streaming library in combination with SoftwareSerial, but it failed.

    SoftwareSerial myLCD = SoftwareSerial(LCD_RX_PIN, LCD_TX_PIN);

    void setup() {
    myLCD << _BYTE(254) << _BYTE(1);
    }

    Error generated is ”
    error: no match for ‘operator<<' in 'myLCD << _BASED(254l, 0)'
    Streaming.h:51: note: candidates are: Print& operator<<(Print&, const _BASED&)
    Streaming.h:69: note: Print& operator<<(Print&, const _FLOAT&)
    Streaming.h:80: note: Print& operator<<(Print&, _EndLineCode)
    "

    Is there any solution about this?


  17. Mikal

    13 years ago

    @Basile, I think that the print(x, BYTE) mechanism was removed from recent versions of Arduino, so this is something I will have to fix.

    EDIT: I think it may be planned to be removed, but it’s still there as of today.


  18. Basile

    13 years ago

    Thank you for the fast answer.

    The line that I wanted to streamify is
    myLCD.print(254, BYTE); myLCD.print(1, BYTE);
    and it is working just fine.

    If there is anything I can do to help just contact me.


  19. Mikal

    13 years ago

    @Basile, this code compiles fine for me:


    void setup()
    {
    Serial.begin(115200);
    Serial << _BYTE(254) << _BYTE(1);
    }

    void loop()
    {}

    I can’t see why your example wouldn’t, frankly.


  20. Basile

    13 years ago

    The problem is with the SoftwareSerial. With the Serial it works like a charm.
    The myLCD is not a Serial, but a SoftwareSerial connected to pin 3


  21. Basile

    13 years ago

    Just found it.
    I was using the arduino version of SoftwareSerial. Once I added to my libraries folder your version of SoftwareSerial (v11 beta) it all compiled ok.

    Thank for all the help.


  22. hguhf

    13 years ago

    hello, how to add scroll to lcd thank you for this libary


  23. Mikal

    13 years ago

    @hguhf,

    I’m afraid none of my libraries provide any kind of scroll facility. Doesn’t the LiquidCrystal library support scrolling?


  24. Eddie

    13 years ago

    Serial << The people over at Arduino should hire you <<endl;


  25. Mikal

    13 years ago

    @Eddie:

    :)


  26. Roman

    13 years ago

    How to print LCD.print((char)223) with this Library?


  27. Mikal

    13 years ago

    LCD << (char)223;


  28. JlyanYdrael

    13 years ago

    Hi. is this library for outputting data only ??
    in c++ there’s a thing like cin>>data>>data1>>etc..
    Can i do it using this or an library? thanks.
    any advise would be great.


  29. Mikal

    13 years ago

    Good proposal: making an input streaming component. I don’t know of anyone who does that but it seems like a good idea. Thanks.


  30. john raines

    13 years ago

    I downloaded Arduino 1.0 beta 3 this morning, looked at what should be needed to update my version of LiquidCrystal that handles 40×4 LCDs and fixes various bugs for the new version (basically should be just declaring return type of write as size_t and returning 1, assuming success).

    My test program uses Streaming.h e.g.:
    “lcd(0,i%nRows)<<"no cursor"<<i;"

    and gets multiple errors that look like:

    "Please use Serial.write() instead.LCDtestUserBusyMega:725: error: 'BYTE' was not declared in this scope

    As of Arduino 1.0, the 'BYTE' keyword is no longer supported."

    As you know, final release for Arduino 1.0 is planned next week.


  31. john raines

    13 years ago

    looks like the line
    #define BYTE 0
    was removed from print.h
    I think there is also a general change from wprogram.h to arduino.h


  32. Volker Kuhlmann

    13 years ago

    Hi, thanks for the Streaming.h library! I am using this all the time. However describing it as “uses no resources” is not correct. The Print class can at least generate function calls with 1 and 2 byte operands as well, but your <<_BYTE() (as well as all the other integer ones) always create a 4-byte argument. That's hugely expensive on 8-bit microcontrollers!

    Can you think of a way to make this efficient for 1-byte and 2-byte arguments? I can't, but my C++ is not that good.

    Greetings -Volker


  33. Mikal

    13 years ago

    @Volker,

    Do these 4-byte arguments have lifespans beyond the function call? If so, then I agree that I should optimize them.

    M


  34. Julio Terra

    13 years ago

    This is a truly great little piece of functionality. I’m sorry that it took me so long to find it. Thank you!


  35. ghoti

    13 years ago

    Hi, Just to say thanks for your work on this.
    Interestingly, in my tests, I actually saved 6 bytes using your lib versus the standard print routing. (ok it was only 1 print line… but I like it!)

    Cheers again!


  36. Volker Kuhlmann

    12 years ago

    Do you have a version for Arduino 1.0?
    Sorry but that new string stuff with new()/free() on a 32kbyte 8bit microcontroller is just a laugh.


  37. Randall W

    12 years ago

    Or you could just use sprintf(), since the Arduino language is just C, and have all the joy of easy formatted printing. To paraphrase the example above:
    // This does work in Arduino. Hooray!
    char msg[128];
    sprintf(msg,”The button was pressed %d times”,counter);
    lcd.print(msg);

    Even better, by using sprintf() you can control the width of fields etc. All formatted printing problems can be solved easily using the standard C libraries.


  38. Ralf Kramer

    12 years ago

    With the new Arduino 1.0, it is possible to use

    Serial.print(F(“Test”)); // stored in flash

    How can I use it with the streaming.h ?

    Serial << F("Test");

    doesn't work!

    Ralf Kramer


  39. Shibu

    12 years ago

    Hi, Mikal,
    Thanks for the lib.
    I tried the Streaming library on Maple (http://leaflabs.com/) and it worked straight away.

    I faced only one problem. When I tried _FLOAT, it spits out error ‘_FLOAT was not declared in this scope.
    For the time being, I can live with the default precision of two decimal places for floats. However in future, I may want to adjust the precision. Is there a way out?

    TIA

    Shibu


  40. Norm

    12 years ago

    Can you furnish a few examples of formatting output? I had to resort to
    “client.print(x,2);” In order to get a formatted float.


  41. Mikal

    12 years ago

    Yep, Streaming now works in Arduino 1.0.

    M


  42. Mikal

    12 years ago

    @Ralf,

    Yep, the new Streaming library should work with that syntax.


  43. Mikal

    12 years ago

    @Shibu,

    I think the problem mus be that the Maple version was derived from an older version of Arduino software — one that didn’t support the capability to specify the floating precision. The code in question is wrapped in

    #if ARDUINO >= 18

    so I think Maple must be less than version 18?


  44. Mikal

    12 years ago

    Hi Norm,

    Sorry it’s not clear. You’d probably just do something like:

    Serial << _FLOAT(1.2345, 3) << endl;


  45. Norm

    12 years ago

    I’m not finding documentation on _FLOAT() although it seems to work. Is there a way to add leading zeros? Better yet, can you point me to docs?


  46. Shibu

    12 years ago

    Hi Mikal,

    Maple is derived from Arduino-18. But probably they have removed the variable ‘Arduino’.
    I added “#define ARDUINO 18” to the top of my code and it works fine.

    Thanks for the lead.

    PS: I wrote a library for reading from Sensirion temperature and humidity sensor SHT-15 which work OK (on Maple). But when I try it with streaming library, thing become flakey. Some sketches compile while others don’t. Error messages are not at all helpful. The error messages are popping-up at linking stage – not compile stage. I don’t know if you can help me on this

    Regards,

    Shibu

4 Trackbacks For This Post
  1. New Streaming Library | Arduiniana

    […] Streaming […]

  2. RobotGrrl.com » Blog Archive » Arduino SSC32 Library

    […] SSC32 library uses the Arduiniana Streaming library. Be sure to download and install it into your sketches/libraries/ […]

  3. Arduino net connected clock tells weather not time

    […] were used; PStringto handle parsing the incoming website, Flash for memory management, and Streaming for easier coding. Source:Sean Carney’s Weather Clock/ Please post a comment or leave a […]

  4. Pin Sleep Xbee with Arduino Host | Ponderings

    […] Streaming C++ style Output – print and println gets to be a pain after a while […]

Leave a Reply