Home Raspberry Pi 20x4 LCD i2c C++ Driver
Post
Cancel

Raspberry Pi 20x4 LCD i2c C++ Driver

Introduction

I have written a C++ driver for the common 20x4 LCD using i2c on the Raspberry Pi. These LCDs are based on HD47780. Most examples I found are using the pins directly and not through i2c. I2c uses a lot less pins than directly connecting the LCD. I originally wrote this in C and then decided to convert to C++, as I am re-learning C++!

Breadboard Layout

It is important to use a level shifter to protect the Raspberry Pi's input pins as they are only 3.3v while the 20x4 LCD is 5v. If you measure the SDA/SCL pins with a voltmeter they are giving out around 4.8V. With a level shifter there is no need to worry and other devices that need 5v can be connected. There was no fritzing diagram of my level shifter which has slightly different markings so the above diagram is an example of how it could be connected.

Driver Functions Available

Last year I created a weatherStation and as part of that project used an LCD display. The implementation was crude and cleared the display upon any change, it wasn't very efficient so I have implemented the functions I thought were useful.

Here is a list of functions available:

voidlcdSendCommand(unsignedchar command);
voidlcdString(constchar* message);
voidsetCursorPositionRowCol(int row, int col);
voidclearColumnsRowCol(int row, int colToClearTo, int colToClearFrom);
voidblinkCursor();
voidenableUnderlineCursor();
voidclearDisplayClearMem();
voidclearDisplayKeepMem();
voidsetEntryMode();
voidsetDisplayOnCursorOff();
voidset4Bit2Line();
voidset8Bit2Line();
voidmoveCursorRight();
voidmoveCursorLeft();
voidresetCursorPosition();
voidscroll1CharRightAllLines();
voidscroll1CharLeftAllLines();
voidclearLine(int lineNo);

The most important functions available allow you to clear certain parts of the display and then move the cursor to any position. This allows you to write logic to update only what has changed etc.

An example:

I wanted to keep the i2c and LCD parts separate as you don't want to call the LCD driver just to open the i2c bus for another i2c device. As a result the LcdDriver constructor takes a pointer to an i2c object.

int main(int argc, char *argv[])
{
I2cControl *i2c = new I2cControl(1);
LcdDriver lcd(lcdAdd, i2c);

lcd.lcdSendCommand(LCD_BEG_LINE_1);
lcd.lcdString("SensorID:");
lcd.setCursorPositionRowCol(1,11);
lcd.lcdString("Here");

lcd.setCursorPositionRowCol(2,0);
lcd.lcdString("Temp: ");
lcd.setCursorPositionRowCol(2,8);
lcd.lcdString("22.4 C");

lcd.setCursorPositionRowCol(3,0);
lcd.lcdString("Battery: ");
lcd.setCursorPositionRowCol(3,11);
lcd.lcdString("45%");

//Sleep for 4 seconds so we can observe the display
std::this_thread::sleep_for(std::chrono::milliseconds(4000));

//Change battery to the word humidity
lcd.clearColumnsRowCol(3,8,0);
lcd.setCursorPositionRowCol(3,0);
lcd.lcdString("Humidity:");

return0;
}

Code

I have now published the code to github.

RaspLCDDriver Github

I have left the C code in the git project as well as the re-factored C++ code. The C++ code can be built with "gcc i2cControl.cpp lcdDriver.cpp test.cpp -o lcdDriverCPlusPlus -lstdc++" and run with ./lcdDriverCPlusPlus.
To use in your own code, just add the header files and declare the objects:
I2cControl *i2c = new I2cControl(1);
LcdDriver lcd(0x27, i2c);

Video Demo

https://youtu.be/l5CS7Rvel_0

This post is licensed under CC BY 4.0 by the author.

If you have found this site useful, please consider buying me a coffee :)

Proud supporter of the Gnome Foundation

Become a Friend of GNOME

Contents

FreeNAS Failed to create mountpoint

LVM Transaction ID mismatch and metadata resize error

Comments powered by Disqus.