< Back 

SolidCrystalI2C

2026-01-28

High performance and easy to use modern driver for LCD displays based on the HD44780 controller. Runs on AVR/Arduino systems.

C++AVREmbedded
Go to technical view

SolidCrystalI2C: simple, smooth LCD screens on Arduino

The little 16x2 and 20x4 LCD screens found in thousands of Arduino projects run on a chip called the HD44780, and they usually connect with just four wires thanks to a small I2C module soldered on the back. SolidCrystalI2C is a library that lets you write to them easily, without your program sitting around waiting for the screen.

What problem does it solve?

That I2C module is cheap and convenient, but slow: showing a single letter takes several messages over the wire, and redrawing a full 16x2 screen takes about 58 milliseconds (an estimate based on the bus timings). In that time an Arduino could have run almost a million clock cycles. On top of that, the classic library for these screens has gone unmaintained for years.

How does it solve it?

SolidCrystalI2C keeps a copy of what the screen is showing in the Arduino’s memory. When something changes, it compares the two and sends only the characters that are different, instead of rewriting everything. It also includes:

  • A second layer for things that should appear on top of the text without erasing it, like menu arrows.
  • Custom characters (icons, arrows, progress bars) with a cache that avoids reloading the ones already stored on the screen.
  • A comfortable syntax: you write with <<, just like in C++, so lcd << "Temp: " << 23 does what you’d expect.
  • Small, fixed memory use: it allocates what it needs once at startup and doesn’t use String, so it runs well on AVR boards with little RAM, like the Arduino Uno or Nano.

It was written from scratch from the HD44780 and PCF8574 datasheets, not adapted from another library.

Example

#include <SolidCrystalI2C.h>

LCD lcd(0x27, 16, 2, true);   // I2C address, columns, rows, overlay enabled

void setup()
{
    lcd.start();
    lcd << "Hello, world!" << cchar::endl;
    lcd.flush();   // only what changed gets sent to the screen
}

void loop()
{
}

Licensed under the MIT License - Copyright (c) 2026 Mastedore.