I'm drawing a bit of a blank with this. I have a 1602A-1 16x2 LCD screen hooked up to an i2c port expander chip.

I'm using the screen in 4 bit mode so I have DB4-7 hooked up to GPIO 0-3 respectively.

I have also hooked up RS, R/W and E to other GPIO pins.

enter image description here

I can see the function set binary string is 001010xx to set 4 bit mode with 2 display lines and 5x8 dots display mode. I am thus setting the GPIO 0-3 pins to 0010 and then setting the enable pin high. I set the enable pin back to low and set the GPIO 0-3 pins to 1000. Again, I pulse the enable pin.

All the time, the RS and R/W pins are low to signify Instruction Input & Write, respectively.

I've tested the pins output with a multimeter so I'm confident that they are high and low when they should be... however it's just not working. The screen does not change to 2 lines nor can I send 4 bit commands in a similar way, following this.

Anyone have any insights?

  • 1
    \$\begingroup\$ It would help to provide the specific I2C expander model/datasheet and a rough schematic of the connection rather than a text description. \$\endgroup\$
    – alexan_e
    Commented Jan 14, 2014 at 13:21

1 Answer 1


Do you have the bottom 4 bits of the data tied to ground?

You should first reset the LCD by sending the 0x30 command three times. Although the LCD will still be in 8-bit mode the bottom four bits are hardwired to 0 so you don't need to send the separate nibbles.

Now send the 0x20 command, again in 8 bit mode. When this command finishes the LCD will be in 4 bit mode.

To enable 2 rows, send command 0x28. Now you are in 4 bit mode so you need to send two nibbles.

Writing to the LCD through a port expander will require up to eight writes to the port expander for each byte written to the LCD. This is necessary because of the timing sequence required for the various control signals. The sequence I use is:

  1. Set the appropriate value on RS for data or command

  2. Set EN high

  3. Put bottom nibble of data/command on D[7:4]

  4. Bring EN low

  5. Bring EN high

  6. Put top nibble on D[7:4]

  7. Bring EN low

  8. Bring RS low (optional)

Remember that it takes a long time for the LCD to process a command and you must wait for it to finish before starting another command or sending another data byte. The LCD I am using needs many microseconds for some commands so I am using a system tick of 1ms and writing a byte at every tick interrupt. If you don't want to wait you need to observe the BUSY status on D7 instead.


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.