Preview build — page text is a draft awaiting human review. Code badges come from real compiles. The flasher is real but not yet hardware-tested; the Playground is still a preview.

16x2 I2C LCD with NodeMCU ESP8266 — 5 V wiring and code

Run a 16x2 I2C LCD at 5 V from a NodeMCU ESP8266’s VIN, level-shift SDA/SCL to D2/D1, and print text and a custom degree symbol.

Arduino C++Verified — core esp8266 3.1.2, LiquidCrystal I2C 1.1.2, 3 Nov 2026Compile-only

Community draft — report a mistake

A 16x2 LCD with an I2C backpack needs only two signal wires, which suits the NodeMCU’s small number of free pins. The complication is voltage: the LCD wants 5 V for good contrast, and the ESP8266 is a 3.3 V chip.

So the LCD is powered from VIN, and a small BSS138 level shifter sits between D2/D1 and the backpack’s SDA/SCL. The sketch prints an uptime clock and a custom degree symbol, ready for a temperature display.

Wiring

NodeMCU ESP8266Only the pins used are shown · 3.3 V logic16×2 LCD + I2C backpackLV⇄HVLV⇄HVGNDVIND1D2GNDVCCSDASCL
Also needed: 2-channel (or 4-channel) BSS138 level shifter (LV = 3V3, HV = VIN 5 V, common GND).
Every connection
NodeMCU ESP826616×2 LCD + I2C backpackWireNotes
VINVCCred5 V from USB — the LCD needs it for contrast.
GNDGNDblack
D2SDAblueVia level shifter — D2 is GPIO4 (SDA).
D1SCLyellowVia level shifter — D1 is GPIO5 (SCL). Shifter LV = 3V3, HV = VIN (5 V), GND shared.

5 V (3.3 V versions exist) part, 3.3 V board. Most of these LCDs need 5 V for good contrast, and the backpack pulls SDA/SCL up to its own VCC. On ESP32 or Pico, put a BSS138 level shifter between the board and the backpack instead of wiring SDA/SCL directly.

Board quirks

  • The PCF8574 backpack pulls SDA and SCL up to its own VCC — 5 V here. ESP8266 pins are not specified for 5 V, so the level shifter keeps them at 3.3 V. (Wiring straight across often “works”; it is still outside the chip’s ratings.)
  • Run at 3.3 V instead and most 5 V LCDs show faint or no characters even with the contrast pot turned fully. Buy a 3.3 V LCD if you want to skip the shifter.
  • lcd.init() calls Wire.begin() for you, which on the ESP8266 means SDA = D2 and SCL = D1. To use other pins, call Wire.begin(sda, scl) before lcd.init() — but not D0, which can’t do I2C, and not D8, which the pull-ups would hold high at boot.
  • Arduino IDE warns that LiquidCrystal I2C “claims to run on avr architecture”. It is only a warning; the library works on the ESP8266.

Code

lcd-16x2-nodemcu.inoArduino C++Open in PlaygroundOpen in PlaygroundFlash
// 16x2 LCD with PCF8574 I2C backpack on a NodeMCU (ESP8266).
// VCC → VIN (5 V), GND → GND, SDA → level shifter → D2 (GPIO4), SCL → level shifter → D1 (GPIO5).
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 16, 2);  // 0x3F on backpacks with the PCF8574A chip
byte degree[8] = {0b00110, 0b01001, 0b01001, 0b00110, 0b00000, 0b00000, 0b00000, 0b00000};

void setup() {
  Serial.begin(115200);
  Serial.println();
  lcd.init();  // calls Wire.begin(): SDA = D2, SCL = D1 on the ESP8266
  lcd.backlight();
  lcd.createChar(0, degree);
  lcd.setCursor(0, 0);
  lcd.print("NodeMCU + LCD");
  Serial.println("LCD at 0x27 - if the screen stays blank, turn the blue contrast pot");
}

void loop() {
  unsigned long s = millis() / 1000;
  char line[17];
  snprintf(line, sizeof line, "Up %02lu:%02lu:%02lu", s / 3600, (s / 60) % 60, s % 60);
  lcd.setCursor(0, 1);
  lcd.print(line);
  lcd.print(' ');
  lcd.write(byte(0));  // custom degree symbol, just to show createChar works
  Serial.println(line);
  delay(1000);
}

Library: LiquidCrystal I2C (Frank de Brabander) — compiled with LiquidCrystal I2C 1.1.2.

Expected serial output

Serial Monitor · 115200Output
LCD at 0x27 - if the screen stays blank, turn the blue contrast pot
Up 00:00:00
Up 00:00:01
Up 00:00:02

Common errors

Backlight on, but only blocks or nothing

Turn the blue contrast pot on the backpack. If that doesn’t help, the address is 0x3F, not 0x27. Full fix.

Only the first letter of each word appears

A library version mismatch. Full fix.

“library claims to run on avr architecture” warning

Harmless. Why it appears.

↑↓ to move · Enter to open