1602 LCD/Inside the two chips/07. Eight pins, one byte at a time
Inside the two chips · 07 of 11

Eight pins, one byte at a time

The expander has eight outputs and the controller wants eleven signals. The way that is squared off explains the backlight call, the 100 kHz limit, and why redrawing the whole screen is something you can watch happen.

Eleven signals into eight outputs

The controller wants RS, RW, E and eight data lines. The expander has eight outputs. The saving comes from two decisions somebody made when this board was laid out:

  • Four-bit mode. The controller can take a byte as two halves, four data lines each, so D0 to D3 are left unconnected. That is four outputs saved and twice as many transfers spent.
  • RW tied to write. Nothing ever reads back from the display, so the read line is held low and costs nothing.

That leaves RS, E and four data lines: six. The seventh output drives the backlight through a transistor, and the eighth is spare.

Eight outputs, six transfers, one character
transfer 0 of 6
What the sketch asked for
Transfers per character
6
One character
1.3 ms
All 32 cells
42 ms
The difference between a command and a character is one bit, and it is bit 0. RS low means “this is an instruction”, RS high means “this is a character to display”. Everything else about the six transfers is identical — which is why the expander needs no direction pin and no second bus.

It is also why a full redraw is visible. Six transfers of two bytes each, at the 100 kHz this expander is specified to, is about 1.3 ms per character and 42 ms for all thirty-two cells. Redraw the whole screen in a loop and you are watching it repaint.

Six transfers per character

Watch the run. One character is two nibbles, and each nibble is written three times: the data with E low, the same data with E high, the same data with E low again. The controller latches on the falling edge, so the pulse is the point and the repetition is what it costs.

Six transfers of two bytes each, every one with its own start and stop condition. At the 100 kHz this expander is specified to, that is roughly a millisecond and a third per character.

Which is why a redraw is visible

Thirty-two cells at that rate is about forty milliseconds. That is long enough to see as a wipe across the screen, and long enough to matter: I²C is blocking, so nothing else on the bus moves and your loop does not advance either.

The conclusion is not to make the bus faster — the expander does not have another speed. It is to write less. Redraw the characters that changed rather than the screen, and never call clear() in a loop. Numbers that change is that habit, built out of the bug it prevents.

The one bit that separates a command from a character

RS, the expander's bit 0. Low means the byte is an instruction — clear, home, set cursor. High means it is a character to draw. Everything else about the six transfers is identical, which is why this needs no direction pin and no second bus.

When it does not work

lcd.backlight() does nothing

The backlight is one of the expander's eight outputs, so it is switched by the same I²C writes as everything else. If nothing at all reaches the expander, the backlight stays wherever it was — usually on, because that is the state a fresh chip powers up in. A backlight you cannot turn off is a bus that is not working.

The display is fine at 100 kHz and wrong at 400 kHz

That is the expander's specification, not a defect. TI's datasheet gives it a 100 kHz clock. Some chips will run faster on a short wire on a warm day, which is a worse outcome than failing outright because it works until it does not.

Why are only four of the eight data lines used?

Four-bit mode. The controller accepts a byte as two nibbles, each latched by its own enable pulse, which is how eleven signals fit into eight outputs. It costs twice the transfers per character and saves four wires — a trade the expander makes for you.

Writing to the screen makes my sensor readings stutter

A full redraw is about forty milliseconds of blocking I²C. Nothing else on that bus moves during it, and neither does your loop. Redraw only the cells that changed, or move the redraw behind a millis() check.

Where this goes next

Why row 1 is address 0x40, and where the other twenty-four columns went.

Two rows, forty columns

Edit this page — content/books/lcd1602/eight-pins-one-byte-at-a-time.mdx

Community

Questions about this product

See what other owners have asked, and read their solutions.

Ask a question ↗

3-Pack 1602 LCD Display Module, I2C 16x2 Blue

Loading discussions…

Discuss this article

Ask about this page. The answer stays here, on the page it belongs to, for whoever hits the same wall next.

Browse Modules and blocks on the forum