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 << "GPS #" << gpsno << " date: " <<
    day << "-" << month << "-" << year << endl;

This library works for any class that derives from Print:

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

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

Serial << "Byte value: " << _HEX(b) << endl;
lcd << "The key pressed was " << _BYTE(c) << 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 2, 2013 at 9:31 pm
102 Responses → “Streaming”

  1. Johann

    7 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

    7 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

    7 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

    7 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

    6 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

    6 years ago

    @Godstroke,

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

    M


  7. fredde

    6 years ago

    only one word needs to be said : AWESOME


  8. Mikal

    6 years ago

    Hey, thanks Fredde! I find it useful.

    Mkal


  9. Edoardo

    6 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

    6 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

    6 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

    6 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

    6 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

    6 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

    6 years ago

    Yup. Here you go:

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

    Mikal


  16. Basile

    5 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

    5 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

    5 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

    5 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

    5 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

    5 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

    5 years ago

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


  23. Mikal

    5 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

    5 years ago

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


  25. Mikal

    5 years ago

    @Eddie:

    :)


  26. Roman

    5 years ago

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


  27. Mikal

    5 years ago

    LCD << (char)223;


  28. JlyanYdrael

    5 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

    5 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

    5 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

    5 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

    5 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

    5 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

    5 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

    5 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

    5 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

    5 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

    5 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

    5 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

    5 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

    5 years ago

    Yep, Streaming now works in Arduino 1.0.

    M


  42. Mikal

    5 years ago

    @Ralf,

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


  43. Mikal

    5 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

    5 years ago

    Hi Norm,

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

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


  45. Norm

    5 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

    5 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


  47. wea

    5 years ago

    wow !great library, and very very useful more power to you ! u help a lot of people like


  48. Daniel

    5 years ago

    hi,
    would it be possible to include this snippet in a future release in Streaming.h ?
    it only appends a carriage return instead of CR,LF ( as endl) some hardware only want a carriage return as an end of message sentinel and get upset if they get a line feed as well.

    enum _CarriagReturnCode { crl };

    inline Print &operator <<(Print &obj, _CarriagReturnCode arg)
    { obj.print("\r"); return obj; }
    "


  49. Mikal

    4 years ago

    @Daniel,

    Good thought–I think about it.

    M


  50. matt

    4 years ago

    I wanna send a command to an rfid reader/writer and i need an explination of how to do it, the data sheet: http://www.elechouse.com/elechouse/images/product/13.56MHZ_RFID_Module/13.56MHZ_RFID_Manual.pdf

    Can someone cook up some example code? THANKS GUYS! YOU’RE AWESOME!

15 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 [...]

  5. WiFly Shield Ruining Your Weekend? | Mike Newell

    [...] Download the Streaming library. [...]

  6. ATUP » Concatenation on Arduino

    [...] just found the Steaming library which allows you concatenate your strings using [...]

  7. Contributed chipKIT™ Libraries | chipKIT™ Development Platform

    [...] not ported Streaming Lib Maintainer Page [...]

  8. Contributed chipKIT Libraries | chipKIT Development Platform

    [...] not ported Streaming Lib Maintainer Page [...]

  9. Wifi shield configuration from SD card | chipKIT Development Platform

    [...] Streaming  http://arduiniana.org/libraries/streaming/ [...]

  10. arduino教程:从arduino发送格式化文本和数字 | 机器人哥

    [...] 或者用C++一样的流式输出,由MIKAL HART写的库: [...]

  11. How to use infrared remote in your project | My Robot Lab

    [...] Here is an example that prints out the decoded hexadecimal number of the received IR signal (if possible), and the protocol that the IR signal used: First of all, install the Streaming library at http://arduiniana.org/libraries/streaming/. [...]

  12. Building an Android frontend - Page 2

    [...] is the sensor value. I know the << isn't normal Arduino stuff, it's part of the streaming library Reply With Quote vBulletin.events.SkimlinksActivate.subscribe(function() [...]

  13. Google Play Music Internet Radio (Raspberry Pi and Arduino) -Use Arduino for Projects

    [...] will also need some additional Arduino libraries before the script will compile, namely Streaming, CmdMessenger and Encoder. Once theese are in your libraries folder you should be good to [...]

  14. Tema 6 – Comunicaciones con Arduino (3) | Aprendiendo Arduino

    [...] Streaming: http://arduiniana.org/libraries/streaming/ [...]

  15. Google Play Music Internet Radio (Raspberry Pi and Arduino) -Arduino for Projects

    [...] will also need some additional Arduino libraries before the script will compile, namely Streaming, CmdMessenger and Encoder. Once theese are in your libraries folder you should be good to [...]

Leave a Reply