#
# MicroPython LCD1602 ASCII-SCREEN driver, 4-bit interfaces
#
import time
from machine import Pin
from micropython import const
class LCD1602:
# commands
LCD_CLEARDISPLAY = const(0x01)
LCD_RETURNHOME = const(0x02)
LCD_ENTRYMODESET = const(0x04)
LCD_DISPLAYCONTROL = const(0x08)
LCD_CURSORSHIFT = const(0x10)
LCD_FUNCTIONSET = const(0x20)
LCD_SETCGRAMADDR = const(0x40)
LCD_SETDDRAMADDR = const(0x80)
# flags for display entry mode
LCD_ENTRYRIGHT = const(0x00)
LCD_ENTRYLEFT = const(0x02)
LCD_ENTRYSHIFTINCREMENT = const(0x01)
LCD_ENTRYSHIFTDECREMENT = const(0x00)
# flags for display on/off control
LCD_DISPLAYON = const(0x04)
LCD_DISPLAYOFF = const(0x00)
LCD_CURSORON = const(0x02)
LCD_CURSOROFF = const(0x00)
LCD_BLINKON = const(0x01)
LCD_BLINKOFF = const(0x00)
# flags for display/cursor shift
LCD_DISPLAYMOVE = const(0x08)
LCD_CURSORMOVE = const(0x00)
# flags for display/cursor shift
# LCD_DISPLAYMOVE = const(0x08)
# LCD_CURSORMOVE = const(0x00)
# LCD_MOVERIGHT = const(0x04)
# LCD_MOVELEFT = const(0x00)
#
# # flags for function set
# LCD_8BITMODE = const(0x10)
# LCD_4BITMODE = const(0x00)
# LCD_2LINE = const(0x08)
# LCD_1LINE = const(0x00)
# LCD_5x10DOTS = const(0x04)
# LCD_5x8DOTS = const(0x00)
'''
pins_db = [DB7, DB6, DB5, DB4]
'''
def __init__(self, pin_rs, pin_rw, pin_e, pins_db):
self.pin_rs = pin_rs
self.pin_rw = pin_rw
self.pin_e = pin_e
self.pins_db = pins_db
self.pin_rs.init(Pin.OUT)
self.pin_rw.init(Pin.OUT)
self.pin_e.init(Pin.OUT)
for aPin in self.pins_db:
aPin.init(Pin.OUT)
# self.pin_rw.init(self.pin_rw.OUT) # for debug
self.lcd1602_init()
def bus_write_4bits(self, aByte, rs_mode=False):
self.pin_rs.value(rs_mode)
self.pin_rw.value(False) # write
# high-4bit
time.sleep_us(400) # 400us
self.pin_e.value(True)
time.sleep_us(400) # 400us
for i in range(4):
if aByte & 0x80:
self.pins_db[i].value(True)
# print(f"pin:{pins_db[i]}, 1") # only for debug
else:
self.pins_db[i].value(False)
# print(f"pin:{pins_db[i]}, 0") # only for debug
aByte <<= 1
time.sleep_us(380) # ok!!, tDSW
self.pin_e.value(False)
time.sleep_us(400) # 400us, tH
# low-4bit
time.sleep_us(400) # 400us
self.pin_e.value(True)
time.sleep_us(400) # 100us
for i in range(4):
if aByte & 0x80:
self.pins_db[i].value(True)
# print(f"pin:{pins_db[i]}, 1") # only for debug
else:
self.pins_db[i].value(False)
# print(f"pin:{pins_db[i]}, 0") # only for debug
aByte <<= 1
time.sleep_us(400) # tDSW
self.pin_e.value(False)
time.sleep_us(400) # 100us, tH
# print("") # only for debug
def bus_send_cmd(self, aByte):
self.bus_write_4bits(aByte)
def bus_send_data(self, aByte):
self.bus_write_4bits(aByte, True)
def lcd1602_init(self):
self.bus_send_cmd(0x33) # set 8bit mode, twice
self.bus_send_cmd(0x32) # set 8bit mode, then 4bit mode
self.bus_send_cmd(0x28) # set 4bit mode, 2-line, 5x7 mode
self.bus_send_cmd(0x0f) # Display On, Cursor On, Cursor Blink
self.bus_send_cmd(0x01) # Display Clear
self.bus_send_cmd(0x06) # Entry Mode, cursor moves to next
self.bus_send_cmd(0x80) # Initialize DDRAM address to zero
def message(self, text):
""" Send string to LCD. Newline wraps to second line"""
self.bus_send_cmd(0x80) # next line
for char in text:
if char == '\n':
self.bus_send_cmd(0xc0) # next line
else:
self.bus_send_data(ord(char))
def clear_display(self):
self.bus_send_cmd(self.LCD_CLEARDISPLAY)
# time.sleep_ms(100)
# ---- main ----
if __name__ == "__main__":
obj_1602 = LCD1602(pin_rs=Pin(13), pin_rw=Pin(12), pin_e=Pin(14), pins_db=[Pin(5), Pin(18), Pin(19), Pin(21)])
# obj_1602 = LCD1602(pin_rs=Pin(32), pin_rw=Pin(33), pin_e=Pin(17), pins_db=[Pin(12), Pin(14), Pin(27), Pin(16)])
obj_1602.message("Hello,\nZhang!")
time.sleep_ms(5000)
obj_1602.clear_display()
obj_1602.message("2nd message here.")