I'm working with I2C to work with my LCD 1602 and the I2C adapter.

This module has 16 pins and I don't know how to communicate with it.

I2C sends 8-bit packets. What are the commands to deal with this module, because it has 16 pins?

This is my current code:

void I2C_init(void);
void I2C_start(void);
void I2C_stop(void);
void I2C_tx(uint8_t data);
void I2C_TWSR_Check(void);

void setup() {
  // put your setup code here, to run once:

void loop() {
  uint8_t i;

  for (i = 0; i < 5; i++)

void I2C_init(void) {
  //set SCL to 100kHz
  TWSR = 0x00;
  TWBR = 0x48;
  //enable TWI
  TWCR = (1 << TWEN);

void I2C_start(void) {
  TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN);
  while (!(TWCR & (1 << TWINT)));

void I2C_stop(void) {
  TWCR = (1 << TWINT) | (1 << TWSTO) | (1 << TWEN);

void I2C_tx(uint8_t u8data) {
  TWDR = u8data;
  while (!(TWCR & (1 << TWINT)));

void I2C_TWSR_Check(void) {
  uint8_t Status;
  Status = TWSR & 0xF8;
  switch (Status)   {
    case 0x08:    // start OK
      Serial.println("Start is OK");
    case 0x10:    // Re start
      Serial.println("Re start");
    case 0x18:        // SLA+W OK ACK
      Serial.println("SLA+W OK ACK");
    case 0x20:        // SLA+W no ACK
      Serial.println("SLA+W no ACK");
    case 0x28:        // data OK ACK
      Serial.println("data OK ACK");
    case 0x30:        // data OK no ACK
      Serial.println("data OK no ACK");
    case 0x38:        // arbitration lost in SLA+W or data TX
      Serial.println("arbitration lost in SLA+W or data TX");

I don't know I get first case working all the time. I can't proceed to sending the data.

This is the most I got from google images: PCF8574 I2C backpacks for HD44780 Compatible LCD Module Arduino Raspberry

  • Re all the strings in I2C_TWSR_Check(), surround them with F() to store the strings in PROGMEM rather than also in RAM. Re the “first case working” issue, you might need to describe at more length what happens. May 3, 2017 at 16:00

1 Answer 1


The tronixstuff page about PCF8574-based backpacks for LCD modules and Arduino (with material that also appears in an instructable) includes a sketch that most likely will work with that backpack.

Once you've identified which I2C library to use, and the appropriate object instantiation, most of the general API description (that is, “the commands to deal with this module”) as shown at arduino.cc's LCDi2c Library page and at arduino.cc's LCD API 1.0 page will apply.

The I2C library-include and the appropriate object instantiation for the backpack shown in your link probably will look much like:

#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,2,1,0,4,5,6,7);

For documentation of what the numbers mean, see lines 82 to 90 of LiquidCrystal_I2C.h:

@param      lcd_Addr[in] I2C address of the IO expansion module. [...]
@param      En[in] LCD En (Enable) pin connected to the IO extender module
@param      Rw[in] LCD Rw (Read/write) pin connected to the IO extender module
@param      Rs[in] LCD Rs (Reset) pin connected to the IO extender module
@param      d4[in] LCD data 0 pin map on IO extender module
@param      d5[in] LCD data 1 pin map on IO extender module
@param      d6[in] LCD data 2 pin map on IO extender module
@param      d7[in] LCD data 3 pin map on IO extender module

Briefly, 0x27 is the I2C address of the PCF8574 chip on the backpack. Note, if your backpack has a PCF8574A, its address is 0x3F.

The other seven numbers describe which PCF8574 output pin is connected for each designated purpose. Most PCF8574/PCF8574A I2C backpacks are wired the same and numbers 2,1,0,4,5,6,7 are appropriate.

Edit 1: If you write an LCD-with-backpack library of your own and expect to publish it, it is reasonable to comply with the LCD API mentioned earlier. By using standard interface functions, you will make it possible for users to plug in your library in place of others with the same interface. In addition, the availability of sketches using the LCD API provides you with a range of test material to verify your drivers.

In writing an LCD-with-backpack library, start by solidifying your understanding of each of the parts – LCD and backpack – separately.

LCD: Get some HD44780-based LCD units; hook one up using direct wiring or a shield rather than a backpack; install a known-good library and sketch; run tests to verify the wiring. With the wiring known to work, develop an LCD control library. This may require detailed study of the Hitachi HD44780U data sheet or other HD44780 data sheets. The necessary timing for LCD control is picky enough that it would be a fool's errand to not verify the wiring using known-good software before writing your own.

Backpack: Plug the 16 pins of a backpack into a breadboard, and attach LED cathodes to all the breadboard pins that connect to PCF8574 output pins. Use appropriate resistors to V+ on the anode sides of the LEDs. Connect the backpack's SDA, SCL, V+, and ground to that of your Arduino. Write simple test software using Wire.h calls to send data to the PCF8574, verifying proper operation using the LEDs. This may require detailed study of the Texas Instruments PCF8574 Remote 8-Bit I/O Expander for I2C Bus data sheet. Write your PCF8574 control library. Adapt your LCD control software to send data via the PCF8574 library instead of via direct wiring.

  • I'm sorry I didn't mention that I want to develop a C code by my self, because I want to develop my own libraries so I have more programing knowledge and skills, and not only use pre-written libraries like Arduino libraries. Because C++ codes and libraries are my next goal after I have enough experience with C.
    – R1S8K
    May 3, 2017 at 12:58
  • 1
    @PerchEagle, set edit 1 May 3, 2017 at 14:44
  • Yes, absolutely :) thank you very much for reply and help I really appreciate the help I get for engineers these days, I now working to get the I2C protocol in a clear picture so I can get to work with many I2C modules I have. In regard to your reply, I did a 4-bit interface and I did it good enough. Now I want to connect it with the I2C so I save pins and get advantage of the I2C because it allows you to work with many devices at the same two lines.
    – R1S8K
    May 3, 2017 at 15:51
  • I uploaded my code in the main post. Regards,
    – R1S8K
    May 3, 2017 at 15:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.