<===
2025-11-18 15:33:18
"""
hd44780_i2c_20x4.py — Надёжный драйвер 20×4 LCD (HD44780 + PCF8574) для CircuitPython
Особенности:
• 100% корректная работа всех 4 строк (исправлен баг с Function Set 0x2C)
• Поддержка CircuitPython 8–10 (включая 10.x без board.scl/sda)
• Простой API: lcd.text("Текст", 2, "center")
• Автоматический захват I²C, управление подсветкой
• Не зависит от битых adafruit_character_lcd (работает даже когда они показывают только 2 строки)
Использование:
from hd44780_i2c_20x4 import HD44780_I2C_20x4
lcd = HD44780_I2C_20x4(sda=board.GP14, scl=board.GP15)
lcd.text("Привет, мир!", 0)
Автор: @ur4uqu + Grok
"""
import time
import busio
class HD44780_I2C_20x4:
def __init__(self, i2c=None, address=0x27, scl=None, sda=None, frequency=40000):
"""
Использование:
lcd = HD44780_I2C_20x4(sda=board.GP14, scl=board.GP15)
или
i2c = busio.I2C(board.GP15, board.GP14)
lcd = HD44780_I2C_20x4(i2c)
"""
if i2c is None:
if scl is None or sda is None:
raise ValueError("Укажи scl= и sda= пины")
i2c = busio.I2C(scl, sda, frequency=frequency)
while not i2c.try_lock():
pass
self._owns_lock = True
else:
self._owns_lock = False
self.i2c = i2c
self.addr = address
self._backlight = True
self._init_display()
def _write4bits(self, value):
bl = 0x08 if self._backlight else 0x00
self.i2c.writeto(self.addr, bytes([value | bl | 0x04, value | bl]))
def _send(self, data, rs=0):
h = (data & 0xF0) | rs
l = ((data << 4) & 0xF0) | rs
self._write4bits(h | 0x04)
self._write4bits(h)
self._write4bits(l | 0x04)
self._write4bits(l)
time.sleep(0.00005)
def _cmd(self, cmd):
self._send(cmd, 0)
def _data(self, char):
self._send(ord(char) if isinstance(char, str) else char, 1)
def _init_display(self):
time.sleep(0.05)
self._cmd(0x33); time.sleep(0.005)
self._cmd(0x32)
self._cmd(0x2C) # 4 строки — вот она, магия!
self._cmd(0x0C)
self._cmd(0x01); time.sleep(0.01)
self._cmd(0x06)
def clear(self):
self._cmd(0x01); time.sleep(0.002)
def backlight(self, on=True):
self._backlight = on
self._cmd(0x00) # просто обновляем бит подсветки
def text(self, string, line=0, align="left"):
addr = [0x80, 0xC0, 0x94, 0xD4][line]
self._cmd(addr)
s = str(string)
if align == "center":
s = s.center(20)
elif align == "right":
s = s.rjust(20)
else:
s = s.ljust(20)
for c in s[:20]:
self._data(c)
def close(self):
if self._owns_lock:
self.i2c.unlock()
############ use ###################
# code.py
import time
import board
from hd44780_i2c_20x4 import HD44780_I2C_20x4
# твои пины
lcd = HD44780_I2C_20x4(sda=board.GP14, scl=board.GP15)
lcd.clear()
lcd.text("LCD2004 20x4", 0, "center")
lcd.text("ГОТОВО НА 100%!", 1, "center")
lcd.text("RP2040-Zero ♥", 2, "center")
count = 0
while True:
lcd.text(f"UPTIME: {count:05d} сек", 3, "center")
count += 1
time.sleep(1)