Microchip PIC Library to Control a 20 by 4 LCD Over I2C

Introduction: Microchip PIC Library to Control a 20 by 4 LCD Over I2C

This Instructable presents a 'C' library for controlling a single 20 by 4 LCD based on the HD44780 LCD controller over I2C using the NXP PCF8574 Remote 8bit IO Expander. The LCD is configured for 4 bit interfacing and can be written to and read from via the microcontroller. In this case the PIC18F2685 running at 4MHz.

To use the source and create the microcontroller circuitry you will need to be reasonably au fait with Microchip microcontrollers, the 'C' programming language and electronics in general.

In short, it's not for the beginner. I have included the source code and MPLABX project to get you up and running quickly. It is provided free to use in what ever way you see fit (just make a mention of me), though it comes unsupported.

I used the following system set up;

  1. PIC18F2685 (4MHz XTAL). Purchased from MicrochipDIRECT. £5.30
  2. 20 by 4 2004A LCD based off HD44780. Purchased from Ebay £3.57.
  3. MPLABX IDE v2.15. Free from Microchip
  4. Microchip compiler XC8 v1.35. Free from Microchip
  5. I2C to 1602 convertor board. Purchased from Ebay £1.79
  6. MPLABX XC8 Peripheral Library. Free from Microchip.

I created the library as part of a project to build a bus pirate for my Scantronic 9800 house alarm. Its an old alarm and I want to add internet and GSM connectivity to it without paying the outrageous UK prices. This is part of the first steps to 'crack' the comms between control box and remote key pad.

As I couldn't find a well written library with all the functionality I wanted I decided to 'roll my own.'

Step 1: The Hardware

As mentioned earlier I used the PIC18F2685 primarily due to footprint and space constraints in the finished project.

This meant I was strapped for IO given this is a 28 pin PDIP package. As the peripheral comms was not particularly high speed and I wanted to add an EEPROM and an RTC the logical choice was for I2C as the comms to the LCD. Microchip offer an outstanding free Peripheral Library for the 8bit Microcontrollers which made life a lot easier.

I purchased a vanilla 2004A 20 by 4 LCD from Ebay (£3.57)

and a '1602LCD Display IIC/I2C/I/SPI Serial Interface Module Port For Arduino K6' (£1.79). I have no idea how Ebay sellers decide on these titles.

I soldered the two together and wired them up to the microcontroller as shown in the Pics above.

Step 2: The Software

As mentioned earlier I have included a zipped copy of the full source including the MPLABX project this should allow you to try out the code as quickly as possible (all the include paths are relative).

The software comprises 4 main parts;

  1. The LCD Driver Library : LCD_I2C_PCF8574.c and .h
  2. The I2C bus access code : I2C_UTILS.c and .h
  3. The time delay calls : DELAY.c and .h
  4. The main code : main.c

There are some other files; mcc.c/.h, pin_manager.c/.h. These were added by the Microchip code configurator and I left them in.

I looked at a few libraries (Arduino ones) to get inspiration. In LCD_I2C_PCF8574.c I have added a lot of background and links to where you can get hold of other source, documentation and data on the PIC18F2685, I2C, the LCD and IO expander should you be so inclined. I also added a link to the library I ripped for the character generation. Thanks Mario. This file also contains details on how you may want to customise to your implementation, these are tagged with 'TODO adapt' so you can use the MPLABX task list to grab them.

I took all my details/nomenclature etc. from an Hitachi hard copy LCD manual (yes hard copy, real paper an'all!) I obtained in the early 1980's when we were still printing on flattened trees.

The code in main.c exercises all the functionality of the display including reading DD and CG ram and the busy flag. It should give a good heads up on how to use the library. I included a link to a YouTube Video so you can see it's potential.

Happy experimenting.



    • Metalworking Contest

      Metalworking Contest
    • Creative Misuse Contest

      Creative Misuse Contest
    • Tiny Home Contest

      Tiny Home Contest

    12 Discussions

    Hi Steve!
    Can i configurate this code for PIC18F26k22?
    Is it even possible?
    I would use it on 16 by 2 LCD based on the HD44780 LCD controller over I2C using the NXP PCF8574 Remote 8bit IO Expander, it would have to work?

    1 reply

    Hi aivaras

    It's been a while since I did any PIC work. Its an 18F as was the device I used so the MPLABX XC8 Peripheral Library should be ok. You may need to play around with the row and columns though.



    Hi Steve, after i open the project with the file you provided. I face some errors like this. Please kindly guide us.

    1 reply

    Hi sshyang,

    By the look of the error message it seems as though the peripheral library header for i2c.h is missing or can't be found.

    It has been a while since I did any Microchip environment configuring, however I mention above you require the 'MPLABX XC8 Peripheral Library'

    Which you can get from here;


    If you choose default installation your i2c.h file should be here;

    C:\Program Files (x86)\Microchip\xc8\v1.35\include\plib\i2c.h

    The source of the peripheral library should be here;

    C:\Program Files (x86)\Microchip\xc8\v1.35\sources\pic18\plib\i2c



    Steve can you tell me how to change the cpu to a PIC24FV16KM202 ?

    1 reply

    Hi excessor,

    Porting to a PIC24FV16KM202 device would be none trivial as the example given has 8bit architecture (as does the PIC18F25K22 below) whereas the PIC24F is 16bit.

    I specifically chose the PIC18F2685 as it has reasonable processing 'clout' and I could use Microchip's free i2c library which was written for the 8bit microprocessor range.

    If you wanted to port the code you would need to write your own low level drivers (replacements for the i2c library) and modify the pin_manager and mcc files accordingly.

    However, if I've misunderstood the question, selecting a different processor is done by selecting the project in the project window, right click, select properties. Select 'Conf: [default]' in the 'Catagories' window and navigate to the PIC24F in the device dropdown. Then choose the X16 compiler and linker in the toolchain window (you will have to ensure you have installed them first).

    I hope this helps




    2 years ago

    Hi, SteveQuinn!

    Many thanks for your work!

    I moved your project on PIC18F25K22.

    It works great!

    But need to add line ANSELC = 0; to file pin_manager.c

    1 reply

    Hi vvs000

    Glad to hear you made it.

    I'm pleased you found it of some use.



    how compatible is your code to the dspic30f? Why pay if it is of no use?

    1 reply

    Sorry I don't understand your question, 'why pay if it is of no use', makes no sense.

    How compatible is this for a dspic30f MCU?

    1 reply


    The code, written in 'C' is not processor dependant. The low level drivers are however a different issue. I used the PIC18F2685 as Microchip very kindly supply an I2C library for this part.

    If you use a dspic30f so long as your low level I2C drivers work, so will the library.