import time
from machine import I2C, Pin
class LcdApi:
def __init__(self, num_lines, num_columns):
self.num_lines = num_lines
self.num_columns = num_columns
self.cursor_x = 0
self.cursor_y = 0
self.backlight = True
self.display = True
self.blink = False
self.cursor = False
def init_lcd(self):
self.write_cmd(self.LCD_FUNCTION_RESET)
time.sleep(0.050)
self.write_cmd(self.LCD_FUNCTION_RESET)
time.sleep(0.005)
self.write_cmd(self.LCD_FUNCTION_RESET)
time.sleep(0.005)
self.write_cmd(self.LCD_FUNCTION)
time.sleep(0.005)
self.write_cmd(self.LCD_FUNCTION)
self.write_cmd(self.LCD_FUNCTION_2_LINES)
self.write_cmd(self.LCD_DISPLAY_OFF)
self.write_cmd(self.LCD_CLEAR)
self.write_cmd(self.LCD_ENTRY_MODE)
self.write_cmd(self.LCD_DISPLAY_ON)
def write_cmd(self, cmd):
raise NotImplementedError
def write_data(self, data):
raise NotImplementedError
def clear(self):
self.write_cmd(self.LCD_CLEAR)
self.cursor_x = 0
self.cursor_y = 0
time.sleep(0.002)
def home(self):
self.write_cmd(self.LCD_HOME)
self.cursor_x = 0
self.cursor_y = 0
time.sleep(0.002)
def set_cursor_pos(self, row, col):
if row > self.num_lines - 1:
row = self.num_lines - 1
if col > self.num_columns - 1:
col = self.num_columns - 1
self.cursor_x = col
self.cursor_y = row
addr = col & 0x3F
if row & 1:
addr += 0x40
self.write_cmd(self.LCD_DDRAM | addr)
def write_char(self, char):
if char == '\n':
self.cursor_x = 0
self.cursor_y += 1
if self.cursor_y >= self.num_lines:
self.cursor_y = 0
self.set_cursor_pos(self.cursor_y, self.cursor_x)
return
self.write_data(ord(char))
self.cursor_x += 1
if self.cursor_x >= self.num_columns:
self.cursor_x = 0
self.cursor_y += 1
if self.cursor_y >= self.num_lines:
self.cursor_y = 0
self.set_cursor_pos(self.cursor_y, self.cursor_x)
def write_string(self, string):
for char in string:
self.write_char(char)
def display_on(self):
self.display = True
self.write_cmd(self.LCD_DISPLAY_ON)
def display_off(self):
self.display = False
self.write_cmd(self.LCD_DISPLAY_OFF)
def cursor_on(self):
self.cursor = True
self.write_cmd(self.LCD_CURSOR_ON)
def cursor_off(self):
self.cursor = False
self.write_cmd(self.LCD_CURSOR_OFF)
def blink_on(self):
self.blink = True
self.write_cmd(self.LCD_BLINK_ON)
def blink_off(self):
self.blink = False
self.write_cmd(self.LCD_BLINK_OFF)
def backlight_on(self):
self.backlight = True
def backlight_off(self):
self.backlight = False
LCD_CLEAR = 0x01
LCD_HOME = 0x02
LCD_ENTRY_MODE = 0x04
LCD_ENTRY_INC = 0x02
LCD_ENTRY_SHIFT = 0x01
LCD_DISPLAY_ON = 0x0C
LCD_DISPLAY_OFF = 0x08
LCD_CURSOR_ON = 0x0A
LCD_CURSOR_OFF = 0x08
LCD_BLINK_ON = 0x09
LCD_BLINK_OFF = 0x08
LCD_DDRAM = 0x80
LCD_FUNCTION = 0x20
LCD_FUNCTION_2_LINES = 0x08
LCD_FUNCTION_RESET = 0x30
I2C_ADDR = 0x27
class I2cLcd(LcdApi):
def __init__(self, i2c, i2c_addr, num_lines, num_columns):
self.i2c = i2c
self.i2c_addr = i2c_addr
self.num_lines = num_lines
self.num_columns = num_columns
self.backlight = True
self.write_cmd(self.LCD_FUNCTION)
self.write_cmd(self.LCD_FUNCTION)
self.write_cmd(self.LCD_FUNCTION)
self.write_cmd(self.LCD_FUNCTION)
self.write_cmd(self.LCD_FUNCTION_2_LINES)
self.write_cmd(self.LCD_DISPLAY_ON)
self.write_cmd(self.LCD_CLEAR)
self.write_cmd(self.LCD_ENTRY_MODE)
self.write_cmd(self.LCD_HOME)
time.sleep(0.1)
def write_cmd(self, cmd):
self.i2c.writeto(self.i2c_addr, bytearray([0x00, cmd]))
def write_data(self, data):
self.i2c.writeto(self.i2c_addr, bytearray([0x40, data]))
def backlight_on(self):
self.backlight = True
def backlight_off(self):
self.backlight = False
# Define I2C pins
i2c = I2C(0, sda=Pin(0), scl=Pin(1), freq=400000)
I2C_ADDR = 0x27
# Initialize the LCD
lcd = I2cLcd(i2c, I2C_ADDR, 2, 16) # 2 rows and 16 columns
# Display text
lcd.clear()
lcd.putstr("Hello, World!")
lcd.move_to(0, 1)
lcd.putstr("Raspberry Pi Pico")