ESP32-C6 I2C LCD: Wiring, Code and Simulator

To build this ESP32-C6 I2C LCD project you need an ESP32-C6 DevKitC-1 and a 16x2 LCD. Hardware I2C on IO6 (SDA) and IO7 (SCL) scans the bus and drives a 16x2 LCD with a PCF8574 backpack. Make the 4 connections in the wiring table, upload the MicroPython code, and change the text on the first line. Connect the logic analyzer to IO6 and IO7 to see each I2C byte.

Open this circuit in the free ESP32-C6 DevKitC-1 simulator

Parts list

QtyPartWhat it does
1ESP32-C6 DevKitC-1the microcontroller board
116x2 LCDCharacter LCD (HD44780). Wiring "full": RS, E and D4–D7 to pins (LiquidCrystal). Wiring "i2c": SDA to A4, SCL to A5 (LiquidCrystal_I2C, address 0x27).

Wiring

#FromTo
1ESP32-C6 DevKitC-1 IO616x2 LCD SDA
2ESP32-C6 DevKitC-1 IO716x2 LCD SCL
3ESP32-C6 DevKitC-1 5V16x2 LCD VCC
4ESP32-C6 DevKitC-1 GND16x2 LCD GND

Step by step

  1. Open the simulator. Open the BitForBytes Embedded Lab in your browser and start from the ESP32-C6 DevKitC-1. No install or account is needed.
  2. Add the parts. Add a 16x2 LCD from the parts palette.
  3. Wire 1. Connect ESP32-C6 DevKitC-1 IO6 to 16x2 LCD SDA.
  4. Wire 2. Connect ESP32-C6 DevKitC-1 IO7 to 16x2 LCD SCL.
  5. Wire 3. Connect ESP32-C6 DevKitC-1 5V to 16x2 LCD VCC.
  6. Wire 4. Connect ESP32-C6 DevKitC-1 GND to 16x2 LCD GND.
  7. Paste the MicroPython code. Paste the MicroPython code below into the code editor.
  8. Run it. Press Run. Change the text on the first line. Connect the logic analyzer to IO6 and IO7 to see each I2C byte.

MicroPython code

# ESP32-C6: an I2C LCD (16x2 with a PCF8574 backpack at 0x27).
# Hardware I2C on SDA = IO6, SCL = IO7; the LCD is driven nibble by nibble.
from machine import Pin, I2C
import time

i2c = I2C(0, scl=Pin(7), sda=Pin(6), freq=100000)
print("I2C devices:", [hex(a) for a in i2c.scan()])

def nib(v, rs):
    d = (v << 4) | 0x08 | rs
    i2c.writeto(0x27, bytes([d | 0x04, d]))

def send(v, rs=0):
    nib(v >> 4, rs)
    nib(v & 15, rs)

def line(text, row):
    send(0x80 | (0x40 * row))
    for ch in "{:<16}".format(text)[:16]:
        send(ord(ch), 1)

time.sleep_ms(50)
for _ in range(3):
    nib(3, 0)
    time.sleep_ms(5)
nib(2, 0)
for c in (0x28, 0x0C, 0x06, 0x01):
    send(c)
time.sleep_ms(2)
line("Hello, ESP32-C6", 0)
n = 0
while True:
    line("uptime %d s" % n, 1)
    n += 1
    time.sleep(1)

What to try

Change the text on the first line. Connect the logic analyzer to IO6 and IO7 to see each I2C byte.

Frequently asked questions

How do I wire the I2C LCD project on an ESP32-C6 DevKitC-1?

Make 4 connections: ESP32-C6 DevKitC-1 IO6 to 16x2 LCD SDA; ESP32-C6 DevKitC-1 IO7 to 16x2 LCD SCL; ESP32-C6 DevKitC-1 5V to 16x2 LCD VCC; ESP32-C6 DevKitC-1 GND to 16x2 LCD GND.

What parts do I need for this ESP32-C6 project?

An ESP32-C6 DevKitC-1 and a 16x2 LCD.

Can I simulate this ESP32-C6 project online for free?

Yes. The BitForBytes Embedded Lab runs this exact circuit and MicroPython code in your browser for free, with no install and no hardware. The ESP32-C6 is emulated instruction by instruction on its RISC-V core, running its own ROM and the official MicroPython firmware.

What does the code do?

Hardware I2C on IO6 (SDA) and IO7 (SCL) scans the bus and drives a 16x2 LCD with a PCF8574 backpack.

More ESP32-C6 DevKitC-1 projects