LiquidTWI2 – A Lean, High Performance I2C LCD Library for Arduino

I have released LiquidTWI2, a lean, high speed I2C LCD Library for Arduino. This library is an extension of the great work done by FalconFour on his LiquidTWI library.  Notable additions to LiquidTWI:

LiquidTWI2 also supports the Adafruit I2c Backpack (MCP23008-based) in I2C mode.  The library is a drop-in replacement for both the Adafruit LiquidCrystal Library (for the I2C backpack) and the Adafruit RGB LCD Shield Library.  By replacing either of Adafruit’s libraries with LiquidTWI2, memory use will decrease, and writing to the LCD will become blazingly fast.


  1. download LiquidTWI2 from github.
  2. copy the LiquidTWI2 folder to <arduinosketchbook>/libraries/LiquidTWI2


I2C Backpack or compatible MCP23008-based module

#include <Wire.h>
#include <LiquidTWI2.h>
LiquidTWI2 lcd(0); // 0 = i2c address
void setup() {
lcd.setMCPType(LTI_TYPE_MCP23008); // must be called before begin()
lcd.setBacklight(HIGH); // only supports HIGH or LOW
void loop() {
lcd.print(“Hello World!”);

RGB LCD Shield or compatible MCP23017-based module

#include <Wire.h>
#include <LiquidTWI2.h>
LiquidTWI2 lcd(0);

void setup() {
lcd.setMCPType(LTI_TYPE_MCP23017); // must be called before begin()
lcd.setBacklight(WHITE); // see LiquidTWI2.h for color options
void loop() {
lcd.print(“Hello World!”);
uint8_t btns = readButtons();

Note that you must call setMCPType() with the correct module type prior to the first call to begin().  The module type can be switched at any time during runtime by merely calling setMCPType() and begin() again. This allows you to create a single firmware which can run with either module, and store the module type in EEPROM.

When working in a memory-constrained environment, you can save memory by disabling the unneeded support.  Edit LiquidTWI2.h and comment out the #define for either MCP23008 or MCP23017.

For further speed gains, you can tweak the speed of the I2C bus.  See the included i2c_perftest example sketch.


Related Post: LiquidTWI2 v1.1.0 Released

34 thoughts on “LiquidTWI2 – A Lean, High Performance I2C LCD Library for Arduino”

  1. Just tried your library, it is real fast!

    Your example program took 4722 bytes, the old library needed 6122 bytes
    Default speed was 327 msec on the old and 100 on the new

    Great work.

    1. I just optimized it a bit. The size is increased by 14 bytes, but the speed for drawing 47 characters speed up from 99ms to 76ms! Try the latest from github

      1. I have never been a big fan of templates. Though they make for easy to read code, they result in bulkier runtimes because the code is essentially duplicated. In the severely memory constrained environment that this code was written for, I feel that code size/efficiency takes priority over readability, especially for simple logic.

    1. Sorry I can’t tell from that listing. It doesn’t have a schematic or even specify which chipset it uses.

  2. I tried your library. It worked great for displaying text on my RGB i2c adafruit lcd.
    However, I’m having trouble reading the push buttons. UP and LEFT buttons don’t seem to be detected, but the others are OK.
    All buttons are correctly detected in the Adafruit library, so my board is electrically OK.

    Any ideas?

    1. Hmm. I just tried it with my Adafruit RGB LCD shield on both Arduino 0023 and 1.0.2 on a Duemilanove, and I can read all 5 buttons. What board/version of arduino are you using?

          1. Sorry, I don’t have a Leonardo to test on, but if it’s reading some of the keys, they should all be reading OK. I don’t know what could be causing your problem.

          2. @Bob Rushby, OK, I figured out what was causing the unreadable buttons.. I inadvertently uploaded a version with PANELOLU2 enabled by default. Go into LiquidTWI2.h and comment out the PANELOLU2 line like so:

            //#define PANELOLU2

            and it will fix the problem

  3. Good news. I tried commenting out the line you suggested and all the buttons work properly now. Thanks for your help!

  4. Do you have any plans to port this to the Raspberry Pi? I’m coding a control system in C for the Pi (Raspbian) and have only found Python libraries for the Adafruit LCD 2×16 backpack for the Pi, and C libraries for the Arduino…

    Or if you know anyone who has done this, I’d appreciate a pointer.


    1. I probably will, at some point, but I haven’t had much time to play with my RPi yet, so it’s pretty low priority.
      It shouldn’t be terribly hard to translate the Python code to C. Where is the code?

  5. Any thoughts on using this with just an MCP23017 without the backpack? I’ve tried reading through the library, but I can match the pins on the HD44780 to the pins on the MCP.

      1. As part of a project I’m working on, I’m looking to use your Library to drive LCDs that are not part of the Adafruit backpack, but are HD44780 compliant.

  6. First, nice work! I found this while looking for information about driving an HD44780 LCD using the MCP23017. I’m designing my own hardware for this and my pin-mapping is different from Adafruit’s, so I had to adapt the code to match. In the process of figuring it out, I noticed a possible significant performance improvement.

    Every byte written is sent in its own i2c packet, which is several bytes of overhead. The MCP23017 can be configured to write repeatedly to the same register, so you can collect a sequence into a single packet and send it at once. This is particularly helpful in 4-bit mode where it takes at least 4 bytes (I’m using 6) to toggle in the two nybbles.

    Running the i2c_perftest with this change, I get about 51 ms for the default speed. I have not compared code size, but it might actually be smaller.

      1. My code’s a bit rough right now because I’ve been doing a lot of experimenting. My files won’t work for you as-is, because I’ve modified the code to match my hardware and pulled out some stuff I didn’t need. However, I send you the changed files, or I can provide the code changes and some commentary so you can try it out.

        Where can I send this?

      1. I tried – and you were right, it didn’t work. Was worth the try – and rather than rewriting the library to work, it’d probably be easier to switch out my LCD.

Leave a Reply