User Tools

Site Tools


module:micropython:esp32lcdisplayi2c:esp32lcdisplayi2c

Esp32LCDisplayI2C

Übersicht

  • Esp32-Ansteuerung eines LCDisplays mit I2C-Interface(PCF8574)
  • das LCDisplay besitzt 4 Zeilen und 20 Spalten

Quell-Code

Main-Program: CheckEsp32LCDisplayI2C.py

#
import time
import machine
import LCDisplayI2C
#
I2CADDRESS_LCDISPLAY_T  = 0x27
I2CADDRESS_LCDISPLAY_A  = 0x3F
#
LCDISPLAY_COUNT_ROWS    = 4
LCDISPLAY_COUNT_COLUMNS = 20
#
def TestLoop():
    for S in range(0, 10):
        LCDisplay.MoveTo(0, 0)
        LCDisplay.PutText('********************')
        LCDisplay.MoveTo(1, 0)
        LCDisplay.PutText('* Esp32LCDisplay   *')
        LCDisplay.MoveTo(2, 0)
        LCDisplay.PutText('* Version 01V01    *')
        LCDisplay.MoveTo(3, 0)
        LCDisplay.PutText('********************')
        time.sleep_ms(2000)
        LCDisplay.Clear()
        for P in range(0, 30):
            LCDisplay.MoveTo(0, 0)
            LCDisplay.PutText('Line0[{}]'.format(time.ticks_ms()))
            LCDisplay.MoveTo(1, 0)
            LCDisplay.PutText('Line1[{}]'.format(time.ticks_ms()))
            LCDisplay.MoveTo(2, 0)
            LCDisplay.PutText('Line2[{}]'.format(time.ticks_ms()))
            LCDisplay.MoveTo(3, 0)
            LCDisplay.PutText('Line3[{}]'.format(time.ticks_ms()))
    #
#-------------------------------------------------------------    
if '__main__' == __name__:
    print('*** CheckEsp32LCDisplayI2C: begin')
    #
    I2CDisplay = machine.SoftI2C(scl=machine.Pin(22), sda=machine.Pin(21), freq=2000000) 
    LCDisplay = LCDisplayI2C.CLCDisplayI2C(I2CDisplay, I2CADDRESS_LCDISPLAY_T, \
                                           LCDISPLAY_COUNT_ROWS, LCDISPLAY_COUNT_COLUMNS)
    #
    TestLoop()
    #
    print('*** CheckEsp32LCDisplayI2C: end')
    #
#

Library-Module: LCDisplayI2C.py (derived from Basic-Class)

#
"""Implements a HD44780 character LCD connected via PCF8574 on I2C"""
#
from LCDisplay import CLCDisplay
from time import sleep_ms
#
# The PCF8574 has a jumper selectable address: 0x20 - 0x27
DEFAULT_I2C_ADDR = 0x27
#
MASK_RS = 0x01
MASK_RW = 0x02
MASK_E = 0x04
SHIFT_BACKLIGHT = 3
SHIFT_DATA = 4
#
class CLCDisplayI2C(CLCDisplay):
    #
    def __init__(self, i2c, i2caddress, countrows, countcolumns):
        self.I2C = i2c
        self.I2CAddress = i2caddress
        self.I2C.writeto(self.I2CAddress, bytearray([0]))
        sleep_ms(20)   # Allow LCD time to powerup
        # Send reset 3 times
        self.hal_write_init_nibble(self.LCD_FUNCTION_RESET)
        sleep_ms(5)    # need to delay at least 4.1 msec
        self.hal_write_init_nibble(self.LCD_FUNCTION_RESET)
        sleep_ms(1)
        self.hal_write_init_nibble(self.LCD_FUNCTION_RESET)
        sleep_ms(1)
        # Put LCD into 4 bit mode
        self.hal_write_init_nibble(self.LCD_FUNCTION)
        sleep_ms(1)
        CLCDisplay.__init__(self, countrows, countcolumns)
        cmd = self.LCD_FUNCTION
        if countrows > 1:
            cmd |= self.LCD_FUNCTION_2LINES
        self.hal_write_command(cmd)
    #
    def hal_write_init_nibble(self, nibble):
        byte = ((nibble >> 4) & 0x0f) << SHIFT_DATA
        self.I2C.writeto(self.I2CAddress, bytearray([byte | MASK_E]))
        self.I2C.writeto(self.I2CAddress, bytearray([byte]))
    #
    def hal_backlight_on(self):
        self.I2C.writeto(self.I2CAddress, bytearray([1 << SHIFT_BACKLIGHT]))
    #
    def hal_backlight_off(self):
        self.I2C.writeto(self.I2CAddress, bytearray([0]))
    #
    def hal_write_command(self, cmd):
        """Data is latched on the falling edge of E."""
        byte = ((self.Backlight << SHIFT_BACKLIGHT) | (((cmd >> 4) & 0x0f) << SHIFT_DATA))
        self.I2C.writeto(self.I2CAddress, bytearray([byte | MASK_E]))
        self.I2C.writeto(self.I2CAddress, bytearray([byte]))
        byte = ((self.Backlight << SHIFT_BACKLIGHT) | ((cmd & 0x0f) << SHIFT_DATA))
        self.I2C.writeto(self.I2CAddress, bytearray([byte | MASK_E]))
        self.I2C.writeto(self.I2CAddress, bytearray([byte]))
        if cmd <= 3: # The home and clear commands require a worst case delay of 4.1 msec
            sleep_ms(5)
    #
    def hal_write_data(self, data):
        byte = (MASK_RS | (self.Backlight << SHIFT_BACKLIGHT) | (((data >> 4) & 0x0f) << SHIFT_DATA))
        self.I2C.writeto(self.I2CAddress, bytearray([byte | MASK_E]))
        self.I2C.writeto(self.I2CAddress, bytearray([byte]))
        byte = (MASK_RS | (self.Backlight << SHIFT_BACKLIGHT) | ((data & 0x0f) << SHIFT_DATA))
        self.I2C.writeto(self.I2CAddress, bytearray([byte | MASK_E]))
        self.I2C.writeto(self.I2CAddress, bytearray([byte]))
    #
#    

Library-Module: LCDisplay.py (Basic-Class)

"""Provides an API for talking to HD44780 compatible character LCDs."""
#
import time
#
class CLCDisplay:
    # HD44780 LCD controller command set
    LCD_CLR = 0x01              # DB0: clear display
    LCD_HOME = 0x02             # DB1: return to home position
    #
    LCD_ENTRY_MODE = 0x04       # DB2: set entry mode
    LCD_ENTRY_INC = 0x02        # --DB1: increment
    LCD_ENTRY_SHIFT = 0x01      # --DB0: shift
    #
    LCD_ON_CTRL = 0x08          # DB3: turn lcd/cursor on
    LCD_ON_DISPLAY = 0x04       # --DB2: turn display on
    LCD_ON_CURSOR = 0x02        # --DB1: turn cursor on
    LCD_ON_BLINK = 0x01         # --DB0: blinking cursor
    #
    LCD_MOVE = 0x10             # DB4: move cursor/display
    LCD_MOVE_DISP = 0x08        # --DB3: move display (0-> move cursor)
    LCD_MOVE_RIGHT = 0x04       # --DB2: move right (0-> left)
    #
    LCD_FUNCTION = 0x20         # DB5: function set
    LCD_FUNCTION_8BIT = 0x10    # --DB4: set 8BIT mode (0->4BIT mode)
    LCD_FUNCTION_2LINES = 0x08  # --DB3: two lines (0->one line)
    LCD_FUNCTION_10DOTS = 0x04  # --DB2: 5x10 font (0->5x7 font)
    LCD_FUNCTION_RESET = 0x30   # See "Initializing by Instruction" section
    #
    LCD_CGRAM = 0x40            # DB6: set CG RAM address
    LCD_DDRAM = 0x80            # DB7: set DD RAM address
    #
    LCD_RS_CMD = 0
    LCD_RS_DATA = 1
    #
    LCD_RW_WRITE = 0
    LCD_RW_READ = 1
    #
    def __init__(self, num_lines, num_columns):
        self.num_lines = num_lines
        if self.num_lines > 4:
            self.num_lines = 4
        self.num_columns = num_columns
        if self.num_columns > 40:
            self.num_columns = 40
        self.CursorY = 0
        self.CursorX = 0
        self.ImpliedNewline = False
        self.Backlight = True
        self.DisplayOff()
        self.BacklightOn()
        self.Clear()
        self.hal_write_command(self.LCD_ENTRY_MODE | self.LCD_ENTRY_INC)
        self.HideCursor()
        self.DisplayOn()
    #
    def Clear(self):
        self.hal_write_command(self.LCD_CLR)
        self.hal_write_command(self.LCD_HOME)
        self.CursorY = 0
        self.CursorX = 0
    #
    def ShowCursor(self):
        self.hal_write_command(self.LCD_ON_CTRL | self.LCD_ON_DISPLAY |
                               self.LCD_ON_CURSOR)
    #
    def HideCursor(self):
        self.hal_write_command(self.LCD_ON_CTRL | self.LCD_ON_DISPLAY)
    #
    def BlinkCursorOn(self):
        self.hal_write_command(self.LCD_ON_CTRL | self.LCD_ON_DISPLAY |
                               self.LCD_ON_CURSOR | self.LCD_ON_BLINK)
    #
    def BlinkCursorOff(self):
        self.hal_write_command(self.LCD_ON_CTRL | self.LCD_ON_DISPLAY |
                               self.LCD_ON_CURSOR)
    #
    def DisplayOn(self):
        self.hal_write_command(self.LCD_ON_CTRL | self.LCD_ON_DISPLAY)
    #
    def DisplayOff(self):
        self.hal_write_command(self.LCD_ON_CTRL)
    #
    def BacklightOn(self):
        self.backlight = True
        self.hal_backlight_on()
    #
    def BacklightOff(self):
        self.backlight = False
        self.hal_backlight_off()
    #
    def MoveTo(self, cursory, cursorx):
        self.CursorY = cursory
        self.CursorX = cursorx
        Address = cursorx & 0x3f
        if cursory & 1:
            Address += 0x40    # Lines 1 & 3 add 0x40
        if cursory & 2:     # Lines 2 & 3 add number of columns
            Address += self.num_columns
        self.hal_write_command(self.LCD_DDRAM | Address)
    #
    def PutCharacter(self, character):
        if character == '\n':
            if self.implied_newline:
                self.implied_newline = False
            else:
                self.CursorX = self.num_columns
        else:
            self.hal_write_data(ord(character))
            self.CursorX += 1
        if self.CursorX >= self.num_columns:
            self.CursorX = 0
            self.CursorY += 1
            self.implied_newline = (character != '\n')
        if self.CursorY >= self.num_lines:
            self.CursorY = 0
        self.MoveTo(self.CursorY, self.CursorX)
    #
    def PutText(self, text):
        for C in text:
            self.PutCharacter(C)
    #
    def custom_char(self, location, charmap):
        location &= 0x7
        self.hal_write_command(self.LCD_CGRAM | (location << 3))
        self.hal_sleep_us(40)
        for i in range(8):
            self.hal_write_data(charmap[i])
            self.hal_sleep_us(40)
        self.MoveTo(self.cursor_y, self.cursor_x)
    #
    def hal_backlight_on(self):
        pass
    #
    def hal_backlight_off(self):
        pass
    #
    def hal_write_command(self, cmd):
        raise NotImplementedError
    #
    def hal_write_data(self, data):
        raise NotImplementedError
    #
    def hal_sleep_us(self, usecs):
        time.sleep_us(usecs)  
    #
#

Entwicklung

211216 : Esp32LCDisplayI2C 01V01

VSCode: Testprogramm Esp32LCDisplayI2C 01V01
2112161443_VSCodeEsp32LCDisplayI2C.jpg

Funktionsweise Ansteuerung LCDisplayI2C

211216 : DokuWiki:Esp32LCDisplayI2C

  • WICHTIG: LCDisplayI2C(PCF8574T) 4row x 20columns muss mit 5V betrieben werden!
  • Versuch, die Github-Original-Files zu minimieren und optimieren

211215 : Erster Versuch Esp32-LCDisplayI2C


Open Hard- & Software [ DokuWiki WebSites MediaWiki NextCloud ]

module/micropython/esp32lcdisplayi2c/esp32lcdisplayi2c.txt · Last modified: 2022/09/13 11:58 by 127.0.0.1