<===

ProNotes

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)
← Previous Next →
Back to list