{"product_id":"lcd1602-i2c-character-display-16x2-pcf8574-5v","title":"LCD1602 I2C Character Display 16x2, Blue (PCF8574, 5V)","description":"\u003cp\u003eA 16 character x 2 line LCD with a blue screen and an I2C (IIC) adapter built on the PCF8574. The I2C interface needs only two signal wires plus power, which saves GPIO pins on your microcontroller compared with a standard parallel 1602 LCD.\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003e16x2 character display (LCD1602), blue screen\u003c\/li\u003e\n\u003cli\u003eI2C \/ IIC interface via PCF8574 adapter\u003c\/li\u003e\n\u003cli\u003e5V operation - this needs 5V to work reliably!\u003c\/li\u003e\n\u003cli\u003eBacklit screen for easy reading\u003c\/li\u003e\n\u003cli\u003eWorks with Arduino and similar microcontrollers\u003c\/li\u003e\n\u003c\/ul\u003e\n\u003cp\u003eA simple, readable text display for sensor readouts, menus and status messages in your projects.\u003c\/p\u003e\n\u003cp\u003eWant to get started right away - here is code I've tested with my screen. It runs through samples of what is possible, so it's a great place to get started. Modify it to make it your own! \u003c\/p\u003e\n\u003cp\u003e \u003c\/p\u003e\n\u003cpre data-lang=\"PlatformIO, can be pasted into Arduino IDE\"\u003e\u003ccode\u003e\/\/ 16x2 I2C LCD test (ESP32) - PCF8574 backpack at 0x27\n\/\/\n\/\/ Wiring (4 lines):\n\/\/   LCD GND -\u0026gt; ESP32 GND\n\/\/   LCD VCC -\u0026gt; ESP32 5V (VIN)\n\/\/   LCD SDA -\u0026gt; GPIO 21\n\/\/   LCD SCL -\u0026gt; GPIO 22\n\/\/\n\/\/ If the backlight is on but no text shows (or you see a row of solid\n\/\/ blocks), turn the blue contrast pot on the back of the backpack.\n\/\/\n\/\/ No library needed. Backpack pin mapping (standard):\n\/\/   P0 = RS, P1 = RW, P2 = EN, P3 = backlight, P4..P7 = D4..D7\n\n#include \u0026lt;Arduino.h\u0026gt;\n#include \u0026lt;Wire.h\u0026gt;\n\n#define PIN_SDA 21\n#define PIN_SCL 22\n\nstatic uint8_t lcdAddr = 0x27;\n\n#define BIT_RS 0x01\n#define BIT_EN 0x04\n#define BIT_BL 0x08\n\nstatic uint8_t backlight = BIT_BL;\n\n\/\/ ---------- low-level I2C ----------\n\nstatic void pcfWrite(uint8_t val) {\n  Wire.beginTransmission(lcdAddr);\n  Wire.write(val | backlight);\n  Wire.endTransmission();\n}\n\nstatic void lcdPulse(uint8_t val) {\n  pcfWrite(val | BIT_EN);\n  delayMicroseconds(1);\n  pcfWrite(val \u0026amp; ~BIT_EN);\n  delayMicroseconds(50);\n}\n\nstatic void lcdWrite4(uint8_t nibble, uint8_t mode) {\n  uint8_t val = (nibble \u0026lt;\u0026lt; 4) | mode;\n  pcfWrite(val);\n  lcdPulse(val);\n}\n\nstatic void lcdSend(uint8_t byte, uint8_t mode) {\n  lcdWrite4(byte \u0026gt;\u0026gt; 4, mode);\n  lcdWrite4(byte \u0026amp; 0x0F, mode);\n}\n\nstatic void lcdCommand(uint8_t cmd) { lcdSend(cmd, 0); }\nstatic void lcdData(uint8_t data) { lcdSend(data, BIT_RS); }\n\n\/\/ ---------- LCD text ----------\n\nstatic void lcdClear() {\n  lcdCommand(0x01);\n  delay(2);\n}\n\nstatic void lcdSetCursor(uint8_t col, uint8_t row) {\n  lcdCommand((row == 0 ? 0x80 : 0xC0) | col);\n}\n\nstatic void lcdPrint(const char *s) {\n  while (*s) lcdData(*s++);\n}\n\n\/\/ Print text on a row, padded with spaces to clear old characters\nstatic void lcdLine(uint8_t row, const char *s) {\n  char buf[17];\n  snprintf(buf, sizeof(buf), \"%-16s\", s);\n  lcdSetCursor(0, row);\n  lcdPrint(buf);\n}\n\nstatic void lcdCreateChar(uint8_t slot, const uint8_t pattern[8]) {\n  lcdCommand(0x40 | ((slot \u0026amp; 7) \u0026lt;\u0026lt; 3));\n  for (int i = 0; i \u0026lt; 8; i++) lcdData(pattern[i]);\n}\n\nstatic void lcdBacklight(bool on) {\n  backlight = on ? BIT_BL : 0;\n  pcfWrite(0);\n}\n\nstatic void lcdInit() {\n  delay(50);\n  pcfWrite(0);\n  delay(10);\n\n  \/\/ HD44780 4-bit wake-up sequence\n  lcdWrite4(0x03, 0);\n  delay(5);\n  lcdWrite4(0x03, 0);\n  delay(5);\n  lcdWrite4(0x03, 0);\n  delayMicroseconds(150);\n  lcdWrite4(0x02, 0);  \/\/ switch to 4-bit mode\n\n  lcdCommand(0x28);  \/\/ 4-bit bus, 2 lines, 5x8 font\n  lcdCommand(0x0C);  \/\/ display on, cursor off, blink off\n  lcdClear();\n  lcdCommand(0x06);  \/\/ left-to-right, no shift\n}\n\n\/\/ ---------- bus scan ----------\n\nstatic bool i2cPresent(uint8_t addr) {\n  Wire.beginTransmission(addr);\n  return Wire.endTransmission() == 0;\n}\n\nstatic void scanBus() {\n  Serial.println(\"I2C scan:\");\n  int found = 0;\n  for (uint8_t a = 1; a \u0026lt; 127; a++) {\n    if (i2cPresent(a)) {\n      Serial.printf(\"  found 0x%02X\\n\", a);\n      found++;\n    }\n  }\n  if (!found) Serial.println(\"  nothing found - check wiring\/power\");\n\n  \/\/ PCF8574 lives at 0x20-0x27, PCF8574A at 0x38-0x3F\n  for (uint8_t a = 0x27; a \u0026gt;= 0x20; a--) {\n    if (i2cPresent(a)) { lcdAddr = a; break; }\n  }\n  if (!i2cPresent(lcdAddr)) {\n    for (uint8_t a = 0x3F; a \u0026gt;= 0x38; a--) {\n      if (i2cPresent(a)) { lcdAddr = a; break; }\n    }\n  }\n  Serial.printf(\"Using LCD at 0x%02X\\n\", lcdAddr);\n}\n\n\/\/ ---------- demo ----------\n\nstatic const uint8_t heart[8] = {0x00, 0x0A, 0x1F, 0x1F, 0x0E, 0x04, 0x00, 0x00};\nstatic const uint8_t smiley[8] = {0x00, 0x0A, 0x0A, 0x00, 0x11, 0x0E, 0x00, 0x00};\nstatic const uint8_t block[8] = {0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F};\n\nvoid setup() {\n  Serial.begin(115200);\n  delay(500);\n  Serial.println(\"\\n16x2 LCD test\");\n\n  Wire.begin(PIN_SDA, PIN_SCL);\n  Wire.setClock(100000);\n\n  scanBus();\n  lcdInit();\n\n  lcdCreateChar(0, heart);\n  lcdCreateChar(1, smiley);\n  lcdCreateChar(2, block);\n  lcdSetCursor(0, 0);  \/\/ leave CGRAM mode\n\n  lcdLine(0, \"Hello, World!\");\n  lcdLine(1, \"LCD 16x2 OK\");\n  delay(2000);\n}\n\nvoid loop() {\n  \/\/ 1. Backlight on\/off blink\n  lcdLine(0, \"Backlight test\");\n  for (int i = 0; i \u0026lt; 3; i++) {\n    lcdLine(1, \"\u0026gt; OFF\");\n    lcdBacklight(false);\n    delay(500);\n    lcdLine(1, \"\u0026gt; ON\");\n    lcdBacklight(true);\n    delay(500);\n  }\n\n  \/\/ 2. Full block fill - spots dead pixels or missing segments\n  lcdClear();\n  for (uint8_t row = 0; row \u0026lt; 2; row++) {\n    lcdSetCursor(0, row);\n    for (int i = 0; i \u0026lt; 16; i++) lcdData(2);\n  }\n  delay(1500);\n\n  \/\/ 3. Character set check\n  lcdLine(0, \"ABCDEFGHIJKLMNOP\");\n  lcdLine(1, \"0123456789!?#\u0026amp;*%\");\n  delay(2000);\n  lcdLine(0, \"abcdefghijklmnop\");\n  lcdLine(1, \"qrstuvwxyz\u0026lt;\u0026gt;()[]\");\n  delay(2000);\n\n  \/\/ 4. Custom characters\n  lcdClear();\n  lcdSetCursor(0, 0);\n  lcdData(0);\n  lcdPrint(\" Custom chars \");\n  lcdData(0);\n  lcdSetCursor(4, 1);\n  for (int i = 0; i \u0026lt; 4; i++) {\n    lcdData(1);\n    lcdData(' ');\n  }\n  delay(2000);\n\n  \/\/ 5. Scrolling message\n  const char *msg = \"                This is a scrolling test message...                \";\n  int len = strlen(msg);\n  lcdLine(0, \"Scroll test:\");\n  for (int i = 0; i \u0026lt;= len - 16; i++) {\n    char buf[17];\n    memcpy(buf, msg + i, 16);\n    buf[16] = '\\0';\n    lcdSetCursor(0, 1);\n    lcdPrint(buf);\n    delay(150);\n  }\n\n  \/\/ 6. Live uptime counter\n  lcdLine(0, \"Uptime:\");\n  for (int i = 0; i \u0026lt; 50; i++) {\n    char buf[17];\n    snprintf(buf, sizeof(buf), \"%lu.%lu s\", millis() \/ 1000, (millis() \/ 100) % 10);\n    lcdLine(1, buf);\n    delay(100);\n  }\n}\u003c\/code\u003e\u003c\/pre\u003e\n\n  If you are using PlatformIO and an ESP32, you might want to try my .ini file too - but always change your .ini file to match your board.\n\n  \u003cpre data-lang=\"platformio.ini\"\u003e\u003ccode\u003e; PlatformIO Project Configuration File\n;\n;   Build options: build flags, source filter\n;   Upload options: custom upload port, speed and extra flags\n;   Library options: dependencies, extra library storages\n;   Advanced options: extra scripting\n;\n; Please visit documentation for the other options and examples\n; https:\/\/docs.platformio.org\/page\/projectconf.html\n\n[env:esp32dev]\nplatform = espressif32\nboard = esp32dev\nframework = arduino\nmonitor_speed = 115200\u003c\/code\u003e\u003c\/pre\u003e","brand":"Tinker Tailor","offers":[{"title":"Default Title","offer_id":67614861033705,"sku":"LCD1602-I2C","price":12.99,"currency_code":"CAD","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0790\/8006\/3209\/files\/rn-image_picker_lib_temp_3059beee-ba92-4ee9-848b-2b7708841951.jpg?v=1791406329","url":"https:\/\/www.tinkertailor.ca\/products\/lcd1602-i2c-character-display-16x2-pcf8574-5v","provider":"Tinker Tailor","version":"1.0","type":"link"}