This is a driver package for Liquid Crystal displays like the common 1602 and 2004 models using the I2C bus. It has been optimized for speed, yielding typically an order of magnitude improvement. It is compatible with both Arduino and Raspberry Pi Pico environments. For the Pi Pico, both C++ and C interfaces are available. (Arduino uses the C++ interface only)
Liquid Crystal (LCD) displays with 2 lines of 16 characters (model 1602) and 4 lines of 20 characters (model 2004) are inexpensive but versatile and fun displays to add to a micro-controller. Versions with an I2C bus adapter built in are also available and attractive because they only need two output pins for the I2c bus. There are numerous tutorials about these displays on-line, and multiple packages of software.
Unfortunately, most of the common packages are quite slow when updating the display. No, you cannot notice how long it takes to print "Hello World", but if you are trying to update several fields on the screen fairly quickly, you may find the response to other user and peripheral inputs begins to suffer. That was the motivation for this project.
These benchmarks are against popular and commonly used (anonymous) repositories. The benchmark is:
- Update 4 fields of 6 characters each on the display. The fields are assumed to be in different locations, requiring the cursor to be positioned for each one.
- The I2C bus speed is the typical default of 100,000 bits/second
- Hardware is a Pi Pico.
Environment | Conventional Driver | Fast LCD I2C | Improvement |
---|---|---|---|
Arduino | 39.55 mSec | 11.62 mSec | 3.4x |
Pi Pico | 136.97 mSec | 11.56 mSec | 11.8x |
Download the repository. On Arduino, the easiest is to simply download the zip file and unzip it somewhere convenient. For Pi Pico, you more likely should clone the repository into a convenient place.
Note that on all platforms, the complete documentation can be accessed with a web browser at /docs/html/index.html
or you can
view it online here.
- Once you have downloaded the repository, create a new folder called
LCD_I2C
under the folder namedlibraries
in your Arduino sketchbook folder. (Create the folderlibraries
if it does not already exist.) - Copy all the files from the
Arduino_Library
directory into theLCD_I2C
folder.
Copy the contents of the Arduino_Examples
directory to your Arduino sketchbook folder and try them out!
To use the library in your own sketch:
- select LCD_I2C from Sketch > Import Library.
- Also select Wire from Sketch > Import Library.
This will add the following to your sketch:
#include <Wire.h>
#include <LCD_I2C.h>
See the documentation sections on the C++ Interface, and Arduino Differences.
On the Pi Pico, programming in C++ will make all of the features of this package available. This will also make some advanced cases like multiple displays very easy. However, if you prefer to work in C, a reasonably complete subset of the program interface is available with almost all of the functionality of the C++ version. There are examples included for both languages.
In your development environment (IDE) you need:
- The Pi Pico SDK installed with the environmental PATH variables set.
- CMAKE installed.
- MAKE installed.
You also need a display connected to the default Pi Pico I2C bus pins. Make sure that you use a level shifter chip if you are running the display on 5 volts!
The cleanest approach is to build the libraries on your system, and include them in the CMakeLists files for your project as demonstrated in the next section. However, if you want to be as simple as possible...
The fastest way to get started using the driver is to copy the sources and include
files to your project directory and add the sources to your add_executable
CMake command.
(The sources are in /src
and the includes are in /src/include
.) For C++ projects, you only need
LCD_I2C.cpp
and LCD_I2C.hpp
. For C projects, you need all the source and header files,
but you should include only LCD_I2C-C.h
in your program.
Running CMAKE in the base directory of the repository will create the library and examples in a directory tree
in the build
folder. From there you can load the examples into the Pi Pico.
You must add a library target of type IMPORT
for LCD_I2C and tell CMake where to find it,
as well as the include files. This is done by adding an add_libraries
command to
your CMakeLists
file. The following CMakeLists is for the HelloWorld example, but it has been moved outside
the Fast-LCD-I2C project. You must modify the set(LCD_I2C_PROJECT_PATH ...)
line to match
your environment.
# Set minimum required version of CMake
cmake_minimum_required(VERSION 3.12)
# Include build functions from Pico SDK
include($ENV{PICO_SDK_PATH}/external/pico_sdk_import.cmake)
# Set name of project (as PROJECT_NAME) and C/C++ standards
project(HelloWorld
LANGUAGES C CXX ASM)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)
# Set the path to the LCD_I2C Project Directory
set(LCD_I2C_PROJECT_PATH "<Path to the repository location>")
# Creates a pico-sdk subdirectory in our project for the libraries
pico_sdk_init()
# Tell CMake where to find the executable source file
add_executable(HelloWorld HelloWorld.c )
#Add the imported library from LCD_I2C
add_library(LCD_I2C STATIC IMPORTED)
# and set the path to find it
set_target_properties(LCD_I2C PROPERTIES
IMPORTED_LOCATION ${LCD_I2C_PROJECT_PATH}/build/src/libLCD_I2C.a
INTERFACE_INCLUDE_DIRECTORIES ${LCD_I2C_PROJECT_PATH}/src/include)
# Create map/bin/hex/uf2 files
pico_add_extra_outputs(HelloWorld)
# Link to LCD_I2C library, pico_stdlib (gpio, time, etc. functions) and the hardware_i2c library
target_link_libraries(HelloWorld LCD_I2C pico_stdlib hardware_i2c)
# Enable usb output, disable uart output
pico_enable_stdio_usb(HelloWorld 1)
pico_enable_stdio_uart(HelloWorld 0)
See the documentation sections on the C++ Interface, and I2C Initialization.
If you prefer to write in C, there is an interface that "wraps" the C++ interface and makes a subset of the functions available in C. See the documentation section for the C Interface for the limitations and detailed usage information. Also see the documentation section for I2C Initialization.
- VSCODE and the MinGW tools
- Raspberry Pi Pico SDK
- Keith Standiford - KStandiford
This project is licensed under the MIT License - see the LICENSE file for details
- Adafruit, whose dedication to documenting their products made it easy to find the documentation to figure this stuff out.
- Cristian Cristea, who's code taught me a lot about modern professional C++.
- Stan Reynolds, an old mentor and friend who once said "If you're going to do something stupid, at least make sure that it's fast!