Interfacing an I2C LCD Display to PIC


There are many versions of a 16 character by 2 line LCD panel with an I2C interface on the market. They all seem to use nearly identical versions of LCD panel and similar I2C-to-Parallel converter boards…with only slight differences. The LCD modules are controlled by parallel digital signals, thus the I2C-to-Parallel board is required to convert the serial data from the I2C bus to individual I/O lines. The most common difference found is the I2C address assigned to the module. This address can usually be changed by removing or adding jumpers and resistors to the board.

I purchased an LCD module and I2C converter board combination for around 5 bucks from some place in China…that included shipping via US Postal. The sender’s address was actually in China…the module was shipped halfway around the world for virtually zero cost. I don’t know how they do it, but there are other products handled the same way.

To find some of these modules, search the Internets with the phrase “I2C LCD 16×2”.

You can also purchase various versions directly from AdaFruit. These cost 10 to 20 bucks but at least you can get some technical support. Beware that some of their LCDs don’t have the I2C interface included…you may have to order it separately:

AdaFruit ~ i2c / SPI character LCD backpack PRODUCT ID: 292

The above board is really nice because it also allows for controlling the LCD via an SPI bus. The A2,A1,A0 pads allow the address to be set by shorting across as desired.

The basic LCD from AdaFruit is:

Assembled Standard LCD 16×2 + extras – White on Blue

You can control this one directly with 6 digital I/O lines or add the I2C/SPI backpack board in order to use fewer lines. The I2C bus does require 2 lines, but those same 2 lines can control many other devices on the same bus…so long as each has a unique address.

AdaFruit also has displays with multi-color back lights and more character lines. The displays usually come with a potentiometer which is required to control the contrast.

On many models, if you connect the back light (A & K) pins directly to power, it will destroy the light immediately. The LCD will still be usable, but it will have no back light. You should use a 100 ohm or greater resistor to connect the A line to +5V to prevent this. The larger the resistor, the dimmer the light will be but the less power it will consume.

Note that if you add the I2C backpack board, a contrast potentiometer and back light resistor are already built in for convenience.

Programming

For example code, refer to post:

Interfacing an I2C LCD Display to PIC Example Code

Search the code for “LCD” and “i2c” to find all relevant portions. This code is meant for the PIC16f1459, but the concepts can be ported over into several other PIC variants.

Addressing

The trickiest part is determining the address of the module. When purchased from the better vendors such as AdaFruit, the accompanying documentation will clearly specify the address and explain how to change it if desired. Some of the other vendors tell you to try a couple of different addresses…and this note is buried somewhere in a text file.

For the most common I2C configuration, the device addresses are 7 bits. The I2C-to-Parallel Adapter Chip itself will set the upper 4 bits. If the documentation does not specify the address, you must find the Product Data Sheet online for the chip installed on the adapter board. A link for the data sheet for the PCF8574 chip is included below.

Looking at the table in the datasheet, it can be seen that the PCF8574 chip uses address 0100xxx whereas the PCF8574A chip uses 0111xxx. The ‘x’ positions are determined by the jumpering of the A2,A1,A0 inputs to the chip. As seen above, most boards have jumpers or resistors to set these inputs.

Addressing

 

In the LCD Driver I2C Board Schematic linked below, the pins A2,A1,A0 are all pulled up to 1 (+5V) via R6,R5,R4. If left in this state, the lower address three bits would be 111. Three jumper positions are also provided to pull any combination of the inputs to 0, so the address can be changed by jumpering across the desired pads. The resistors do not have to be removed and can be left in place even if a line is jumpered.

In the example code:

LCD_ADDR        EQU     b'0111111'

LCD_WRITE_ID    EQU     (LCD_ADDR << 1) | 0
LCD_READ_ID     EQU     (LCD_ADDR << 1) | 1

The address is set by changing the value of LCD_ADDR. In this case, the address works for a PCF8574A chip with A2,A1,A0 all pulled high as shown on the schematic; the upper 4 bits are 0111 and the lower 3 bits are 111.

When the address is sent to the I2C device, it must be shifted up 1 bit so the lowest bit can be used to specify a Read or Write operation. This is handled by the next two lines in the code which set the value for LCD_WRITE_ID and LCD_READ_ID. As can be seen above, the address is shifted left one bit using the << operator and the lowest bit is set to 0 for the Write command and 1 for the Read command.

Connecting the Module to the PIC

The I2CSDA (data line) is connected to RB4 of the PIC.
The I2CSCL (clock line) is connected to RB6 of the PIC.

These maybe referred to as “DATA”, “DAT”, “CLOCK”, “CLK”, etc. depending on the manufacturer.

Note that the SCL and SDA lines must be pulled up to +5V…this is usually done with a 5K resistor. The attached schematic shows that the I2c-to-Parallel board provides these pull-up resistors. However, if multiple such boards are attached to the I2C bus, there will be too many pull-up resistors and the bus will fail. The resistors should be removed from all the boards except one. Ideally, none of the boards would have pull-up resistors and they would instead be implemented on the main board with the PIC.

Going Further

There are many functions in the LCD module such as blinking cursors, screen shift options, and custom characters. With the proper coding, longer messages can be scrolled across the screen or up the screen. Future versions of the example code will incorporate some of these ideas.

Reading the I2C-to-Parallel Chip and LCD Display manuals carefully and comparing with the example code will answer most questions. Getting I2C code to work can be a real chore in the PIC if starting from scratch. There is nothing like working example code to really clear up a mystery!

In future posts, more detail on the “why’s and how’s” of the code will be covered.

Reference:

PCF8574 I2C to Parallel Adapter Chip Product Data Sheet

LCD Driver I2C Board Schematic using PCF8574 Chip

LCD1602 Data Manual LCD IE-H1602B

LCD1602 Data Manual from another manufacturer

Interfacing an I2C LCD Display to PIC Example Code


Leave a Reply

Your email address will not be published. Required fields are marked *