235 lines
6.3 KiB
Python
235 lines
6.3 KiB
Python
# SPDX-FileCopyrightText: 2017 Scott Shawcroft, written for Adafruit Industries
|
|
# SPDX-FileCopyrightText: Copyright (c) Waveshare
|
|
# SPDX-FileCopyrightText: Copyright (c) 2022 Neradoc
|
|
#
|
|
# SPDX-License-Identifier: MIT
|
|
#
|
|
# In order to keep basic compatibility with the orifinal library, ignore "bad" names.
|
|
# pylint: disable=invalid-name
|
|
"""
|
|
`waveshare_lcd1602`
|
|
================================================================================
|
|
|
|
Drive for Waveshare's I2C character display LCD1602.
|
|
A port of Waveshare's RGB1602 Micropython library.
|
|
|
|
* Author(s): Neradoc
|
|
|
|
Implementation Notes
|
|
--------------------
|
|
|
|
**Hardware:**
|
|
|
|
* `Waveshare LCD1602 RGB Module <https://www.waveshare.com/wiki/LCD1602_RGB_Module>`_
|
|
|
|
**Software and Dependencies:**
|
|
|
|
* Adafruit CircuitPython firmware for the supported boards:
|
|
https://circuitpython.org/downloads
|
|
* Adafruit's Bus Device library: https://github.com/adafruit/Adafruit_CircuitPython_BusDevice
|
|
"""
|
|
|
|
import time
|
|
from adafruit_bus_device.i2c_device import I2CDevice
|
|
|
|
try:
|
|
from typing import Union
|
|
import busio
|
|
except ImportError:
|
|
pass
|
|
|
|
__version__ = "0.0.0-auto.0"
|
|
__repo__ = "https://github.com/Neradoc/Circuitpython_Waveshare_LCD1602.git"
|
|
|
|
# Device I2C Arress
|
|
LCD_ADDRESS = 0x7C >> 1
|
|
RGB_ADDRESS = 0xC0 >> 1
|
|
|
|
# color define
|
|
|
|
REG_RED = 0x04
|
|
REG_GREEN = 0x03
|
|
REG_BLUE = 0x02
|
|
REG_MODE1 = 0x00
|
|
REG_MODE2 = 0x01
|
|
REG_OUTPUT = 0x08
|
|
LCD_CLEARDISPLAY = 0x01
|
|
LCD_RETURNHOME = 0x02
|
|
LCD_ENTRYMODESET = 0x04
|
|
LCD_DISPLAYCONTROL = 0x08
|
|
LCD_CURSORSHIFT = 0x10
|
|
LCD_FUNCTIONSET = 0x20
|
|
LCD_SETCGRAMADDR = 0x40
|
|
LCD_SETDDRAMADDR = 0x80
|
|
|
|
# flags for display entry mode
|
|
LCD_ENTRYRIGHT = 0x00
|
|
LCD_ENTRYLEFT = 0x02
|
|
LCD_ENTRYSHIFTINCREMENT = 0x01
|
|
LCD_ENTRYSHIFTDECREMENT = 0x00
|
|
|
|
# flags for display on/off control
|
|
LCD_DISPLAYON = 0x04
|
|
LCD_DISPLAYOFF = 0x00
|
|
LCD_CURSORON = 0x02
|
|
LCD_CURSOROFF = 0x00
|
|
LCD_BLINKON = 0x01
|
|
LCD_BLINKOFF = 0x00
|
|
|
|
# flags for display/cursor shift
|
|
LCD_DISPLAYMOVE = 0x08
|
|
LCD_CURSORMOVE = 0x00
|
|
LCD_MOVERIGHT = 0x04
|
|
LCD_MOVELEFT = 0x00
|
|
|
|
# flags for function set
|
|
LCD_8BITMODE = 0x10
|
|
LCD_4BITMODE = 0x00
|
|
LCD_2LINE = 0x08
|
|
LCD_1LINE = 0x00
|
|
LCD_5X8DOTS = 0x00
|
|
|
|
|
|
class LCD1602:
|
|
"""
|
|
Setup a new RGB LCD1602 display
|
|
|
|
:param busio.I2C i2c: I2C bus object to use.
|
|
:param int columns: The number of columns on the display.
|
|
:param int rows: The number of rows on the display.
|
|
"""
|
|
|
|
def __init__(self, i2c: busio.I2C, columns: int, rows: int):
|
|
self.lcd_device = I2CDevice(i2c, LCD_ADDRESS)
|
|
#self.rgb_device = I2CDevice(i2c, RGB_ADDRESS)
|
|
self._row = rows
|
|
self._col = columns
|
|
|
|
self._showfunction = LCD_4BITMODE | LCD_1LINE | LCD_5X8DOTS
|
|
self.begin(self._row, self._col)
|
|
|
|
def command(self, cmd: int):
|
|
"""
|
|
Send a command.
|
|
|
|
:param int cmd: The command code.
|
|
"""
|
|
with self.lcd_device:
|
|
self.lcd_device.write(bytes([0x80]) + chr(cmd))
|
|
|
|
def write(self, data: int):
|
|
"""
|
|
Write a data byte.
|
|
|
|
:param int data: The data byte to write.
|
|
"""
|
|
with self.lcd_device:
|
|
self.lcd_device.write(bytes([0x40]) + chr(data))
|
|
|
|
def setReg(self, reg, data):
|
|
"""
|
|
Set the value of a register.
|
|
|
|
:param int reg: The register to write to.
|
|
:param int data: The data byte to write.
|
|
"""
|
|
#with self.rgb_device:
|
|
# self.rgb_device.write(bytes([reg]) + chr(data))
|
|
|
|
def setRGB(self, r, g, b):
|
|
"""
|
|
Set the color of the RGB backlight.
|
|
|
|
:param int r: Red byte.
|
|
:param int g: Green byte.
|
|
:param int b: Blue byte.
|
|
"""
|
|
self.setReg(REG_RED, r)
|
|
self.setReg(REG_GREEN, g)
|
|
self.setReg(REG_BLUE, b)
|
|
|
|
def setCursor(self, col, row):
|
|
"""
|
|
Place the cursor on the display.
|
|
|
|
:param int col: The column.
|
|
:param int row: The row.
|
|
"""
|
|
if row == 0:
|
|
col |= 0x80
|
|
else:
|
|
col |= 0xC0
|
|
with self.lcd_device:
|
|
self.lcd_device.write(bytearray([0x80, col]))
|
|
|
|
def clear(self):
|
|
"""Clear the display."""
|
|
self.command(LCD_CLEARDISPLAY)
|
|
time.sleep(0.002)
|
|
|
|
def printout(self, arg: Union[str, int]):
|
|
"""
|
|
Print a string to the display. Ints are converted to strings.
|
|
|
|
:param str|int arg: The string or int to printout.
|
|
"""
|
|
if isinstance(arg, int):
|
|
arg = str(arg)
|
|
|
|
for x in bytearray(arg, "utf-8"):
|
|
self.write(x)
|
|
|
|
def display(self):
|
|
"""Turn on the display."""
|
|
self._showcontrol |= LCD_DISPLAYON
|
|
self.command(LCD_DISPLAYCONTROL | self._showcontrol)
|
|
|
|
def begin(self, columns: int, rows: int): # pylint: disable=unused-argument
|
|
"""
|
|
Initial configuration, called from init.
|
|
|
|
:param int columns: The number of columns on the display.
|
|
:param int rows: The number of rows on the display.
|
|
"""
|
|
if rows > 1:
|
|
self._showfunction |= LCD_2LINE
|
|
|
|
self._numlines = rows
|
|
self._currline = 0
|
|
|
|
time.sleep(0.05)
|
|
|
|
# Send function set command sequence
|
|
self.command(LCD_FUNCTIONSET | self._showfunction)
|
|
# delayMicroseconds(4500); # wait more than 4.1ms
|
|
time.sleep(0.005)
|
|
# second try
|
|
self.command(LCD_FUNCTIONSET | self._showfunction)
|
|
# delayMicroseconds(150);
|
|
time.sleep(0.005)
|
|
# third go
|
|
self.command(LCD_FUNCTIONSET | self._showfunction)
|
|
# finally, set # lines, font size, etc.
|
|
self.command(LCD_FUNCTIONSET | self._showfunction)
|
|
# turn the display on with no cursor or blinking default
|
|
self._showcontrol = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF
|
|
self.display()
|
|
# clear it off
|
|
self.clear()
|
|
# Initialize to default text direction (for romance languages)
|
|
self._showmode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT
|
|
# set the entry mode
|
|
self.command(LCD_ENTRYMODESET | self._showmode)
|
|
# backlight init
|
|
self.setReg(REG_MODE1, 0)
|
|
# set LEDs controllable by both PWM and GRPPWM registers
|
|
self.setReg(REG_OUTPUT, 0xFF)
|
|
# set MODE2 values
|
|
# 0010 0000 -> 0x20 (DMBLNK to 1, ie blinky mode)
|
|
self.setReg(REG_MODE2, 0x20)
|
|
self.setColorWhite()
|
|
|
|
def setColorWhite(self):
|
|
"""Set the color of the RGB backlight to white."""
|
|
self.setRGB(255, 255, 255)
|