from machine import Pin
from machine import I2C
import utime
print("Test-Script for LCD Dispay with HD44780 Controller and I2C Interfache Chip PCF8574")
# Initialize I2C with pins SDA=GP0 (Pico-Pin1), SDL=GP1 (Pico-Pin2) :: LCD VCC=+5V SDA/SDL 3.3V Logic
i2c=machine.I2C(0, sda=machine.Pin(0), scl=machine.Pin(1), freq=100000)
# Scan I2C BUS to Display correct wired I2C devices
devices = i2c.scan()
for d in devices:
print('I2C Device found at Address: ',hex(d))
#For I2C Controller PCF8574 with HD44780 LCD 2x16 or 4x40 Hardware Wiering Parameter
I2C_LCD_Addr = 0x27 # Must bee one of the scanned I2C Adresses!
LCD_RS = 0x01 # am PFC01 needed for Selecting 0=Command 1=DAta
LCD_RW = 0x02 # am PFC02 propably not connect and at the LCD fix to GND
LCD_E = 0x04 # am PFC03 needed to transfer the Data
LCD_LED= 0x08 # am PFC04 propably not connect and at the LCD fix to On
LCD_D4 = 0x10 # am PFC05
LCD_D5 = 0x20 # am PFC06
LCD_D6 = 0x40 # am PFC07
LCD_D7 = 0x80 # am PFC08
# LCD Service Routines
def LCD_WriteCmd4(Zeichen): # Commands in zwei Nibbles übermitteln
i2c.writeto(I2C_LCD_Addr, bytes([(Zeichen & 0x0F0)+LCD_LED] ) ) # 4-Bit-Data=0x?0 + 00-Register
i2c.writeto(I2C_LCD_Addr, bytes([(Zeichen & 0x0F0)+LCD_LED+LCD_E]) ) # 4-Bit-Data=0x?0 + 04-Enable + 00-Register
i2c.writeto(I2C_LCD_Addr, bytes([(Zeichen & 0x0F0)+LCD_LED]) ) # 4-Bit-Data=0x?0 + 00-Register
def LCD_WriteCmd(Zeichen): # Commands in zwei Nibbles übermitteln
i2c.writeto(I2C_LCD_Addr, bytes([(Zeichen & 0x0F0)+LCD_LED] ) ) # 4-Bit-Data=0x?0 + 00-Register
i2c.writeto(I2C_LCD_Addr, bytes([(Zeichen & 0x0F0)+LCD_LED+LCD_E]) ) # 4-Bit-Data=0x20 + 04-Enable + 00-Register
i2c.writeto(I2C_LCD_Addr, bytes([(Zeichen & 0x0F0)+LCD_LED]) ) # 4-Bit-Data=0x20 + 00-Register
Zeichen = Zeichen << 4
i2c.writeto(I2C_LCD_Addr, bytes([(Zeichen & 0x0F0)+LCD_LED]) ) # 4-Bit-Data=0x?0 + 00-Register
i2c.writeto(I2C_LCD_Addr, bytes([(Zeichen & 0x0F0)+LCD_LED+LCD_E]) ) # 4-Bit-Data=0x20 + 04-Enable + 00-Register
i2c.writeto(I2C_LCD_Addr, bytes([(Zeichen & 0x0F0)+LCD_LED])) # 4-Bit-Data=0x?0 + 08-Licht
def LCD_WriteChar(Zeichen): # Zeichen in zwei Nibbles übermitteln
i2c.writeto(I2C_LCD_Addr, bytes([(Zeichen & 0x0F0)+LCD_LED+LCD_RS])) # 4-Bit-Data=0x?0 + 08-Licht + 01-Register
i2c.writeto(I2C_LCD_Addr, bytes([(Zeichen & 0x0F0)+LCD_LED+LCD_RS+LCD_E])) # Data=0x?0 + 04-Enable, 01-Register
i2c.writeto(I2C_LCD_Addr, bytes([(Zeichen & 0x0F0)+LCD_LED+LCD_RS])) # 4-Bit-Data=0x?0 + 08-Licht + 01-Register
Zeichen = Zeichen << 4
i2c.writeto(I2C_LCD_Addr, bytes([(Zeichen & 0x0F0)+LCD_LED+LCD_RS])) # 4-Bit-Data=0x?0 + 08-Licht + 01-Register
i2c.writeto(I2C_LCD_Addr, bytes([(Zeichen & 0x0F0)+LCD_LED+LCD_RS+LCD_E])) # Data=0x?0 + 04-Enable, 01-Register
i2c.writeto(I2C_LCD_Addr, bytes([(Zeichen & 0x0F0)+LCD_LED+LCD_RS])) # 4-Bit-Data=0x?0 + 08-Licht + 01-Register
def LCD_Init():
try: # Catch I2C Communication Error
LCD_WriteCmd4(0x30) # 0011 D7-D4 HiNibble = SoftReset Sequenz1
except: # Set HD44780 Controller with 4-Bit and Init for use
print("I2C Communiation to " + hex(I2C_LCD_Addr) + "h failed - please Check as the I2C Address ist valid")
import sys
sys.exit("I2C Communiation Error") # TERMINATE SCRIPT ON ERROR
utime.sleep_ms(5) # Delay 5ms SoftReset Sequenz1 zu SoftReset Sequenz2
LCD_WriteCmd4(0x30) # 0011 D7-D4 HiNibble = SoftReset Sequenz2
utime.sleep_ms(1) # Delay 1ms SoftReset Sequenz2 zu SoftReset Sequenz3
LCD_WriteCmd4(0x30) # 0011 D7-D4 HiNibble = SoftReset Sequenz3
utime.sleep_ms(1) # Delay 1ms SoftReset Sequenz3 zu 4-Bit Init
LCD_WriteCmd4(0x20) # 0010 D7-D4 HiNibble = 4-Bit Mode Init
LCD_WriteCmd(0x28) # 0010 1000 - 4Bit Mode Activate
LCD_WriteCmd(0x0C) # 0000 1100 - Display ON, Cursor Off, Cursor Blinking Off
LCD_WriteCmd(0x06) # 0000 0110 - Entry Mode, Increment cursor position, No display shift
LCD_WriteCmd(0x01) # 0000 0001 - Clear Display and Set Cursor to pos 0
utime.sleep_ms(5) # Controller needs Time to Clear the Display
LCD_WriteCmd(0x02) # 0000 0010 - Set Cursor to home Pos=0 needs 1.52mS
utime.sleep_ms(2) # Controller needs Time to Set Cursor Home, needs 1.52mS
def LCD_GotoXY(Position): # Somme HD44780 2end row starts at pos 41 others at 64
if Position > 0x7F : Position=0x7F
LCD_WriteCmd(0x80+Position) # 1000 0000 - 0x80 + Position
def LCD_CLR(): # LCD Löschen via Kommando HD44780
LCD_WriteCmd(0x01) # 0000 0001 - Display Löschen und Cursor auf 0
utime.sleep_ms(2) # Controller needs Time to Clear the Display, needs 1.52mS
def LCD_Print(LCDText): # Print String at the actal position
for Zeichen in LCDText: # Send Character by character
LCD_WriteChar(ord(Zeichen))
# *** MAIN PROGRAMM ***
LCD_Init() # Set HD44780 Controller with 4-Bit and Init for use
LCD_CLR() # Not Needed here, is with Init allready done
LCD_Print("** Hello World **")
LCD_GotoXY(64) # Pos 64 (or 40) is second row
LCD_Print("LCD-I2C HD44780 Cont")
LCD_GotoXY(20) # Pos 20 is 3th row on 4x20 Display
import sys # Onely needed for the Output of the Python Version
LCD_Print("Python: " + sys.version[0:6])
LCD_GotoXY(84) # Pos 84 (64+20) is 4th row on 4x20 Display
try: # Protect Script if it runs not on a Raspberry Pico Board
from machine import ADC
machine.Pin(29, machine.Pin.IN) # the ADC i.o. Pin needs to set as imput, for correct value turn off pull up/down
LCD_Print("V-SYS: " + str(machine.ADC(3).read_u16()*3.23*3/65535)[0:6] + " Volt")
except:
LCD_Print("V-SYS: No ADC present")
# *** ENDE OF MAIN PROGRAMM ***