With
I²C Display Module, you can easily connect character LCD (Liquid Crystal Display) to your Arduino via I²C protocol, thus saving a lot of valuable pins usually used for parallel connection (at least 6 pins: 2 control pins - RS and EN - and 4 data pins D7, D6, D5, and D4 for 4-bit mode). With I²C (a.k.a. TWI /
Two Wires Interface), you need only two pins. Even better, those two pins can also be shared with other I2C-based peripherals.
Note: in Arduino Uno, SDA is pin A4, SCL is pin A5. For other models, please check corresponding pin diagram.
The only drawback of using these modules is (beside a little additional cost for purchasing I²C display module) is speed reduction, but it's negligible since you don't need to update lot of data at high speed with such character-based display device (might be different story with graphics LCD, they
do need to fetch a lot of bitmap data).
You might want to use new
LiquidCrystal_I2C library, please download
most recent version (v1.2.1) in zipped file (485 Kb), generously contributed by F. Malpartida. Extract it to your Arduino working folder under
library
sub-folder (i.e.,
My Document\Arduino\libraries
).
There are several Character LCD I²C modules on the market, you should use correct initialization code which might be slightly different for each device.
Include required library at beginning of your sketch as follow:
#include 'Wire.h'
#include 'LiquidCrystal_I2C.h'
Next step is to instantiate the LCD object by calling LiquidCrystal_I²C class constructor. This constructor accepts parameter in following order:
addr, en, rw, rs, d4, d5, d6, d7, bl, blpol
addr
is I²C address of the module. It's unique for each device, check with your I²C module supplier to get the correct address. Usually, they are set to 0x20
, 0x27
, or 0x38
en
is bit index for Enable (EN) pin.
rw
is bit index for Read/Write Selector (RW) pin.
rs
is bit index for Register Selector (RS) pin.
d4, d5, d6, d7
are bit indexes for upper 4-bit of data pins
bl
is bit index for backlight pin.
blpol
polarity of backlight pin, might be differs according to the LCD being used. Value is either POSITIVE
or NEGATIVE
(enum declared in LCD.h
).
The first argument (
addr) is mandatory, that means you have to manually specify the address of your I²C device. Other arguments are optional, if not specified they will be set to default values (bit#6 for
en, bit#5 for
rw, bit#4 for
rs, bit#0 for
d4, bit#1 for
d5, bit#2 for
d6, bit#3 for
d7). If
bl is omitted, backlight state won't be modified (default to value set by the I²C module). Default value for
blpol is
POSITIVE
.
Those bit indexes are required for the library to send correct signal to appropriate pins since different I²C modules has different pin mapping.
Some example of initialization codes (try them to find one that suitable for your device), instantiated on object
lcd:
LiquidCrystal_I2C lcd (0x20,2,1,0,4,5,6,7,3,POSITIVE);
LiquidCrystal_I2C lcd (0x27,2,1,0,4,5,6,7,3,POSITIVE);
LiquidCrystal_I2C lcd (0x20,4,5,6,0,1,2,3,7,NEGATIVE);
Finally, initialize the LCD by invoking begin() method which accepts two arguments: column count and row count. Example: for 16x2 display, invoke lcd.begin(16,2)
; For 20x4 display, invoke lcd.begin(20,4)
;
I2C LCD Display 20x4 Sample Sketch
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// Instantiate lcd object
LiquidCrystal_I2C lcd( 0x20, 4, 5, 6, 0, 1, 2, 3, 7, NEGATIVE );
// Custom character patterns
const uint8_t charBitmap[][8] = {
{ 0xc, 0x12, 0x12, 0xc, 0, 0, 0, 0 },
{ 0x6, 0x9, 0x9, 0x6, 0, 0, 0, 0 },
{ 0x0, 0x6, 0x9, 0x9, 0x6, 0, 0, 0x0 },
{ 0x0, 0xc, 0x12, 0x12, 0xc, 0, 0, 0x0 },
{ 0x0, 0x0, 0xc, 0x12, 0x12, 0xc, 0, 0x0 },
{ 0x0, 0x0, 0x6, 0x9, 0x9, 0x6, 0, 0x0 },
{ 0x0, 0x0, 0x0, 0x6, 0x9, 0x9, 0x6, 0x0 },
{ 0x0, 0x0, 0x0, 0xc, 0x12, 0x12, 0xc, 0x0 }
};
void setup() {
// initialize the lcd
lcd.begin( 20, 4 );
// create custom chars
for( uint8_t i = 0; i < 8; i++ ) {
lcd.createChar ( i, (uint8_t *)charBitmap[ i ] );
}
lcd.setCursor( 3, 2 );
lcd.print( "LCD 20x4 DEMO" );
lcd.setCursor( 0, 3 );
lcd.print( "azTech @ vcc2gnd.com" );
}
void loop() {
register uint8_t i;
// Animate
lcd.home();
for( i = 20; i--; ) lcd.write( random( 8 ) );
lcd.setCursor( 0, 1 );
for( i = 20; i--; ) lcd.write( random( 8 ) );
delay( 200 );
}
Watch the result on demo video below...