-
Notifications
You must be signed in to change notification settings - Fork 59
ioClass: hd44780_I2Cexp
The hd44780_I2Cexp ioClass is used to control LCDs which use i2c i/o expander chips (PCF8574 or MCP23008) on backpacks
The goal of the hd44780_I2Cexp i/o class was to create as close to a plug and play experience for LCD backpacks as possible, including the low cost backpacks readily available from places like Ebay.
With other i2c LCD libraries you must specify the I2C address. Most libraries, including the IDE library manager LiquidCrystal_I2C library are also hard coded to work with single backpack design that use a specific pin mapping between the PCF8574 and the hd44780 LCD display and if your backpack doesn't use that pin mapping, it won't work.
A few libraries, like fm's NewLiquidCrystal library allow the sketch to configure the PCF8574 pin mappings and backlight control.
If the pin mappings are not specified correctly, it will not work.
The hd44780 library can auto detect everything, the i2c address, the pin mappings, and the backlight control.
The hd44780 library does allow specifying the i2c address in the constructor should auto i2c address location not be desired.
For nearly all the PCF8574 based backpacks and the AdaFruit #292 backkpack in i2c mode, the library should be able to auto self configure and "just work".
The hd44780_I2Cexp i/o class includes a diagnostic sketch I2CexpDiag which will test the i2c signals and internal RAM of the LCD module to verify that the the library is properly communicating with the LCD module.
It is highly recommended to run this diagnostic sketch first to verify that the library is properly talking to your backpack and LCD module.
Read the instructions in the sketch for how to run it and what to expect on the serial monitor.
Using the Arduino IDE, I2cexpDiag can be found here:
[File]->Examples->hd44780->ioClass->hd44780_I2Cexp->I2CexpDiag
Using the Arduino IDE GUI, hd44780_I2cexp examples can be found here:
[File]->Examples->hd44780->ioClass->hd44780_I2Cexp
Using the IDE GUI to bring up the included HelloWorld sketch for a minimal example of how to declare the lcd constructor and initialize the LCD you would click on
[File]->Examples->hd44780->ioClass->hd44780_I2Cexp->HelloWorld
If the sketch code was previously using another library then all that is necessary is to change the header file includes and the lcd object constructor.
No other code changes should be necessary.
change this:
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,16,2); // set the LCD address to 0x27 for a 16 chars and 2 line display
To this:
#include <Wire.h>
#include <hd44780.h> // main hd44780 header
#include <hd44780ioClass/hd44780_I2Cexp.h> // i2c expander i/o class header
hd44780_I2Cexp lcd(0x27,16,2); // declare lcd object at address 0x27 (use i2c address zero to auto locate address)
The hd44780_I2Cexp i/o class also supports auto location and auto configuration using LiquidCrystal API
compatible begin()
change this:
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,16,2); // set the LCD address to 0x27 for a 16 chars and 2 line display
To this:
#include <Wire.h>
#include <hd44780.h> // main hd44780 header
#include <hd44780ioClass/hd44780_I2Cexp.h> // i2c expander i/o class header
hd44780_I2Cexp lcd; // declare lcd object: auto locate i2c address & auto config expander chip pin mapping
and change any call to init() to begin(cols, rows)
If you want/need to use a specific i2c address you can configure the i2c address in the constructor:
hd44780_I2Cexp lcd(0x27); // declare lcd object: 0x27 i2c address & auto config expander chip pin mapping
change this:
#include <Wire.h> // note: this include may or may not be in the sketch
#include <LCD.h> // note: this include may or may not be in the sketch
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
to this:
#include <Wire.h>
#include <hd44780.h> // main hd44780 header
#include <hd44780ioClass/hd44780_I2Cexp.h> // i2c expander i/o class header
hd44780_I2Cexp lcd; // declare lcd object: auto locate i2c address & auto config expander chip pin mapping
If you want/need to use a specific i2c address you can configure the i2c address in the constructor:
hd44780_I2Cexp lcd(0x27); // declare lcd object: 0x27 i2c address & auto config expander chip pin mapping
change this:
#include <LiquidCrystal.h>
// initialize the library by associating any needed LCD interface pin
// with the arduino pin number it is connected to
const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
to this:
#include <Wire.h>
#include <hd44780.h> // main hd44780 header
#include <hd44780ioClass/hd44780_I2Cexp.h> // i2c expander i/o class header
hd44780_I2Cexp lcd; // declare lcd object: auto locate & auto config expander chip
A relatively small number of vendors have created PCF8574 based backpacks that have a backlight circuit design (they use FETs or incorrectly hooked up their transistor) which does not allow the backlight active level control to be automatically correctly determined by the library. In these cases the lcd backlight will operate backwards. i.e. backlight() will turn the backlight off and noBacklight() will turn the backlight on. The lcd will have to be manually configured to operate correctly.
The diagnostic sketch is useful for determining if this is the case for the backpack and for the the necessary manual configuration parameters.
While both the PCF8574 and the MCP23008 i/o expanders perform more than adequate to drive a text based LCD,
from a performance/speed perspective, the PCF8574 will always be a bit faster that the MCP23008 for a given i2c clock speed since the MCP23008 has more i2c overhead to control the output port. That said, the MCP23008 can be clocked faster than the PCF8574 which, if clocked faster than what is supported by the PCF8574, can more than make up for the additional overhead.
Newer Wire libraries have a Wire.setClock(clockspeed) function that can be called to set the i2c clock to be faster than the default 100kHz rate.
PCF8574 datasheet:
MCP23008 datasheet:
Arduino Board pinouts: