The Noiasca Buffer Print Arduino Library

The Noiasca Buffer Print is a Library very similar to Print.h but will buffer outputs until flush is called. Despite other libraries, this class calls flush at the end of each print call. Why this is necessary and which possibilities are offered should be explained on this page.

I split this page in following chapters

  • Idea: Why a buffered print
  • Example and Proof of Concept
  • Important Member Functions
  • Comparision / differences to other Streaming Libraries

Idea: Why do we need a Buffer Print Library?

The Arduino Print.h serializes outputs made by print/println into single characters and calls write for each character printed to the output designation. This is fine for serial transmission, but might cause protocol overhead for slow hardware interfaces of if they add a time consuming transmission for each separate communication.

Hence Noiasca BufferPrint will collect data in an internal buffer and transmit data at the end of print only.

Lets see an I2C LCD transmission for a PCF8574 expander which uses the common 4bit mode and let print 4 characters.

The first figure shows the I2C communication based on Print sending 4 characters. We need 4 I2C transmission. Each single I2C transmission sends the I2C address, the high/low nibbles of the character, 5 acknowledgements, a final stop condition and will pause the sketch to give the display time to process the command:

This is an example with BufferPrint.h: we store the data in a buffer and do one single I2C transmission for all 4 characters. We send the I2C Address once, we have one start condition, one stop condition, 17 acknowledgements and one delay for the display:

Buffered print will process all steps without the need of a manual / explicit call of flush(). Each print/println() should be able to finalize the output to the designation flush().

Examples and Proof of Concepts

Example Basic Hello World

The library comes with a basic "Hello World" examples. It shows how to define a class inherited from BufferPrint.h and a simple implementation which does a buffered print to the hardware serial interface.

Proof of Concept: Modbus RTU Sender

Modbus RTU is a communication protocol on top of RS485.

To enable a buffered print, we can use the internal buffer of NoiascaBufferPrint to collect data before starting a Modbus RTU transmission.

This is used in several of my Modbus Master examples.

Proof of Concept: Faster I2C LCD Communication

Due to the default print/write concept, communication with I2C LCD gets quite slow. If you take a common PCF8574 port expander for a LCD and print the line "Hello World" to the display each single character will be sent separately to the display. For each character the two 4bit nibbles will be sent, the enable line pulsed and the pause time applied. 11 characters - 11 times. The LCD supports a multi-character write also, but this is not used by most of the libraries. Do overcome this flaw we must inherit the LCD Class not from print.h but from NoiascaBufferPrint.h. The write method can be reused as you are used to from other Print libraries. The flush() method must be implemented in the derived class and should stream the internal buffer into two 4bit nibbles, set the RS/RW lines, respect the backlight pin and finally send the to the I2C interface:

    void flush()  // only pseudo code
    {
      Wire.beginTransmission(lcdAddr);           // initialize I2C communication
      // set RS/RW/backlight line
      for (size_t i = 0; i < getActualBufferSize(); i++)
      {
        // byte value = internal[i];  // one value from the internal buffer
        // Wire.write  add high nibble to I2C buffer with respect of RS/RW/backlight state
        // Wire.write  add low nibble to I2C buffer with respect of RS/RW/backlight state
        // Wire.write  set enable pin with respect of RS/RW/Backlight
        // Wire.write  unset enable pin with respect of RS/RW/Backlight
      }
      // set backlight pin according backlight state
      Wire.endTransmission();                    // transmit the I2C buffer
      delayMicroseconds(waitshort);              // standard delay after send
      setActualBufferSize(0);                    // reset buffer to 0
    }

The write method still can be implemented to print one character in a single I2C transmission.

If you are just interested in a faster I2C LCD implementation, have a look on my NoiascaLiquidCrystal and its lcd_PCF8574_fast.h which will come with a full working example using Noiasca Buffer Print

Deep dive into NoiascaBufferPrint

NoiascaBufferPrint is quite similar to the original Print implementation.

print() and its variants calls add (instead of write) for each character handed over and will fill the buffer. All print variants have a new optional parameter to enable/disable the flush after the end of the print. This is also used internally for the println() variants as they just call their print() counterpart with disabled flush add \r\n to the buffer a final call of flush at the end of println().

add() takes a single character and adds it to the buffer. If the internal buffer is full, flush() will be called.

flush() will empty the buffer to it's designation. This virtual member function has to be implemented in your derived class and should do an optimized output of data to the designation. flush() will be either called at the end of the print statement or if the buffer has reached its buffer size.

write() - a virtual member function - must be implemented in the derived class for a single character transmission to the designation.

getBufferLength() will return the number of bytes in the buffer.

resetBuffer() will set the actual buffer to 0 and should be called at the end of your flush method.

Sidenote

Currently Printable() is currently not implemented.

Comparision

Finally let's compare the NoiascaBufferPrint.h with several other "Print" and "Helper" classes

Print.h by Arduino

Print.h serializes prints into single "characters", will do several number formats, you can specify decimals, and you have an easy access to the F-Makro / values in PROGMEM. It is used in a lot of other Libraries, mainly communication and displays.

StreamLib.h by Juraj Andrassy

StreamLib.h inherits from Print.h and uses its own internal buffer. But you must to a final "flush" when you want the output transmitted to your destination. There's nothing wrong with this library - I'm still it using it and recommend it for Arduino Ethernet clients.

PString.h by Mikal Hart

PString.h inherits from Print and uses its own internal buffer.  It's a very lightweight library to collect data into a buffer.

NoiascaBufferPrint.h from this page

As written above, NoiascaBufferPrint.h doesn't inherit from Print.h - it uses copies of Print.h print/println methods to give the user the same API experience like the default Print.h. Each print/println was adopted to do a final flush. It's main purpose is to automize the flush after a (buffered) print.

Summary

With the additional language converters it becomes very easy to convert from letters with diacritic signs to the printable ASCII letters. If you are from an European country and you need better support of Latin1-4 letters you should consider to buy a SPLC780D1 LCD - which is also supported by this library.

Links

  • Download the NoaiscaBufferPrint Library
  • LCD Display on Aliexpress (* Affiliate - Advertisement)
  • LCD Display on Amazon (* Affiliate - Advertisement)

(*) Disclosure: Some of the links above are affiliate links, meaning, at no additional cost to you I will earn a (little) comission if you click through and make a purchase. I only recommend products I own myself and I'm convinced they are useful for other makers.

History

First upload: 2021-11-19 | Version: 2021-12-07