Last time I was blogging about LCD display connected via shift register. It was elegant way how to connect LCD using just three GPIOs on the CPU. Today I would like to push the limits and interface LCD with two wires only. As the title says, I will utilize I2C 8-bit port extender. Don't want to repeat my self with the LCD display theory, 'cause I did it in previous article. So, let's go directly to port extender.
Meeting PCF8574P, an 8-bit port extender
Port extender is an integrated circuit that extends available GPIOs on the CPU. It means that, if the CPU has unsufficient number of GPIOs for given application, it can be extended for additional 8, 16 or more GPIOs. Port extenders are usually connected via I2C or SPI bus. There are plenty of port extenders on the market from different manufacturers with different properties.
I've decide to go with PCF8574P from NXP, since it's the real port extender. It means, that there is no complicated communication protocol for writing and reading particular bits. All it takes, is just send one byte via I2C, that it's immediately reflected to the outputs. Or read one byte from I2C, which contains status of all bits.
As it's been said PCF8574P communicates via I2C bus, so it needs some bus address. According to PCF8574P documentation, address is given by this formula 0 1 0 0 A2 A1 A0. Referring to circuit on the picture, where all address pins are set to high the address is 0 1 0 0 1 1 1 = 0x27.
Connecting LCD using CF8574P. Big Endian wiring
Just one more ITransferProvider
Bansky.SPOT.LCD library has the class LCD4Bit providing API for HD44780 as it was discussed last time. This class relies on some ITransferProvider, which transfer HD44780 commands on selected medium. It means that I've just extended Bansky.SPOT.LCD for one small class called PCF8574P utilizing ITransferProvider interface. I believe that this class can be used with other I2C port extenders as well but I didn't test it.
Following code demonstrates how to write message on display utilizing PCF8574P class. Consider, that I've extended constructors of ITransferProvider objects with bool bigEndian arguments, which specifies the bit order for transfer. Basically it's because the layout of the connector and other circuits on PCB maybe better, when the LCD inputs and PCF8574P are connected in reverse order.
I2CDevice I2Cbus = new I2CDevice(new I2CDevice.Configuration(0, 100)); // Create instance of PCF8574P PCF8574P expander = new PCF8574P( I2Cbus, // I2C bus instance 0x27, // Address on I2C bus true); // Use big endian // Create new LCD instance and use shift register as a transport layer LCD4Bit lcd = new LCD4Bit(expander); // Turn display on, turn back light on, hide small cursor, show big blinking cursor lcd.Display(true, true, false, true); lcd.Clear(); // Clear screen lcd.Write("Hello world!"); // Write message lcd.SetPosition(40); // Move to second line lcd.Write("Micro Framework"); // Write second line of message
The demo project is included in the previous file for download. The original file growth a bit in size but demonstrates, that besides the transfer provider initialization the codes are totally same for shift register demo as well as for PCF8574P.
Note: The I2C bus requires pul up resistors on SDA and SCL lines. Anything from 1K8 ohms to 4K7 ohms works fine.
Demo project and library: AlphanumericLCD_library.zip [77,6 Kb] 19 Oct 2008