Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Added typing and made an edit to fix a typing issue (non-breaking) #73

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Nov 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
144 changes: 80 additions & 64 deletions adafruit_character_lcd/character_lcd.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@
https://github.com/adafruit/Adafruit_CircuitPython_BusDevice

"""
try:
from typing import Union, Optional, List, Sequence
from circuitpython_typing import pwmio
except ImportError:
pass

import time
import digitalio
Expand Down Expand Up @@ -73,7 +78,7 @@
_LCD_ROW_OFFSETS = (0x00, 0x40, 0x14, 0x54)


def _set_bit(byte_value, position, val):
def _set_bit(byte_value: int, position: int, val: bool) -> int:
# Given the specified byte_value set the bit at position to the provided
# boolean value val and return the modified byte.
ret = None
Expand All @@ -84,7 +89,9 @@ def _set_bit(byte_value, position, val):
return ret


def _map(xval, in_min, in_max, out_min, out_max):
def _map(
xval: float, in_min: float, in_max: float, out_min: float, out_max: float
) -> float:
# Affine transfer/map with constrained output.
outrange = float(out_max - out_min)
inrange = float(in_max - in_min)
Expand All @@ -106,16 +113,26 @@ class Character_LCD:
:param ~digitalio.DigitalInOut d5: The data line 5
:param ~digitalio.DigitalInOut d6: The data line 6
:param ~digitalio.DigitalInOut d7: The data line 7
:param columns: The columns on the charLCD
:param lines: The lines on the charLCD
:param int columns: The columns on the charLCD
:param int lines: The lines on the charLCD

"""

LEFT_TO_RIGHT = const(0)
RIGHT_TO_LEFT = const(1)

# pylint: disable-msg=too-many-arguments
def __init__(self, rs, en, d4, d5, d6, d7, columns, lines):
def __init__(
self,
rs: digitalio.DigitalInOut,
en: digitalio.DigitalInOut,
d4: digitalio.DigitalInOut,
d5: digitalio.DigitalInOut,
d6: digitalio.DigitalInOut,
d7: digitalio.DigitalInOut,
columns: int,
lines: int,
) -> None:

self.columns = columns
self.lines = lines
Expand Down Expand Up @@ -147,7 +164,6 @@ def __init__(self, rs, en, d4, d5, d6, d7, columns, lines):
# Set entry mode
self._write8(_LCD_ENTRYMODESET | self.displaymode)
self.clear()

self._message = None
self._enable = None
self._direction = None
Expand All @@ -159,12 +175,12 @@ def __init__(self, rs, en, d4, d5, d6, d7, columns, lines):

# pylint: enable-msg=too-many-arguments

def home(self):
def home(self) -> None:
"""Moves the cursor "home" to position (0, 0)."""
self._write8(_LCD_RETURNHOME)
time.sleep(0.003)

def clear(self):
def clear(self) -> None:
"""Clears everything displayed on the LCD.

The following example displays, "Hello, world!", then clears the LCD.
Expand All @@ -186,21 +202,21 @@ def clear(self):
time.sleep(0.003)

@property
def column_align(self):
def column_align(self) -> bool:
"""If True, message text after '\\n' starts directly below start of first
character in message. If False, text after '\\n' starts at column zero.
"""
return self._column_align

@column_align.setter
def column_align(self, enable):
def column_align(self, enable: bool):
if isinstance(enable, bool):
self._column_align = enable
else:
raise ValueError("The column_align value must be either True or False")

@property
def cursor(self):
def cursor(self) -> bool:
"""True if cursor is visible. False to stop displaying the cursor.

The following example shows the cursor after a displayed message:
Expand All @@ -222,19 +238,19 @@ def cursor(self):
return self.displaycontrol & _LCD_CURSORON == _LCD_CURSORON

@cursor.setter
def cursor(self, show):
def cursor(self, show: bool) -> None:
if show:
self.displaycontrol |= _LCD_CURSORON
else:
self.displaycontrol &= ~_LCD_CURSORON
self._write8(_LCD_DISPLAYCONTROL | self.displaycontrol)

def cursor_position(self, column, row):
def cursor_position(self, column: int, row: int) -> None:
"""Move the cursor to position ``column``, ``row`` for the next
message only. Displaying a message resets the cursor position to (0, 0).

:param column: column location
:param row: row location
:param int column: column location
:param int row: row location
"""
# Clamp row to the last row of the display
if row >= self.lines:
Expand All @@ -249,7 +265,7 @@ def cursor_position(self, column, row):
self.column = column

@property
def blink(self):
def blink(self) -> bool:
"""
Blink the cursor. True to blink the cursor. False to stop blinking.

Expand All @@ -272,15 +288,15 @@ def blink(self):
return self.displaycontrol & _LCD_BLINKON == _LCD_BLINKON

@blink.setter
def blink(self, blink):
def blink(self, blink: bool) -> None:
if blink:
self.displaycontrol |= _LCD_BLINKON
else:
self.displaycontrol &= ~_LCD_BLINKON
self._write8(_LCD_DISPLAYCONTROL | self.displaycontrol)

@property
def display(self):
def display(self) -> bool:
"""
Enable or disable the display. True to enable the display. False to disable the display.

Expand All @@ -302,15 +318,15 @@ def display(self):
return self.displaycontrol & _LCD_DISPLAYON == _LCD_DISPLAYON

@display.setter
def display(self, enable):
def display(self, enable: bool) -> None:
if enable:
self.displaycontrol |= _LCD_DISPLAYON
else:
self.displaycontrol &= ~_LCD_DISPLAYON
self._write8(_LCD_DISPLAYCONTROL | self.displaycontrol)

@property
def message(self):
def message(self) -> Optional[str]:
"""Display a string of text on the character LCD.
Start position is (0,0) if cursor_position is not set.
If cursor_position is set, message starts at the set
Expand All @@ -335,7 +351,7 @@ def message(self):
return self._message

@message.setter
def message(self, message):
def message(self, message: str):
self._message = message
# Set line to match self.row from cursor_position()
line = self.row
Expand Down Expand Up @@ -377,7 +393,7 @@ def message(self, message):
# reset column and row to (0,0) after message is displayed
self.column, self.row = 0, 0

def move_left(self):
def move_left(self) -> None:
"""Moves displayed text left one column.

The following example scrolls a message to the left off the screen.
Expand All @@ -400,7 +416,7 @@ def move_left(self):
"""
self._write8(_LCD_CURSORSHIFT | _LCD_DISPLAYMOVE | _LCD_MOVELEFT)

def move_right(self):
def move_right(self) -> None:
"""Moves displayed text right one column.

The following example scrolls a message to the right off the screen.
Expand All @@ -424,7 +440,7 @@ def move_right(self):
self._write8(_LCD_CURSORSHIFT | _LCD_DISPLAYMOVE | _LCD_MOVERIGHT)

@property
def text_direction(self):
def text_direction(self) -> Optional[int]:
"""The direction the text is displayed. To display the text left to right beginning on the
left side of the LCD, set ``text_direction = LEFT_TO_RIGHT``. To display the text right
to left beginning on the right size of the LCD, set ``text_direction = RIGHT_TO_LEFT``.
Expand All @@ -448,33 +464,33 @@ def text_direction(self):
return self._direction

@text_direction.setter
def text_direction(self, direction):
def text_direction(self, direction: int) -> None:
self._direction = direction
if direction == self.LEFT_TO_RIGHT:
self._left_to_right()
elif direction == self.RIGHT_TO_LEFT:
self._right_to_left()

def _left_to_right(self):
def _left_to_right(self) -> None:
# Displays text from left to right on the LCD.
self.displaymode |= _LCD_ENTRYLEFT
self._write8(_LCD_ENTRYMODESET | self.displaymode)

def _right_to_left(self):
def _right_to_left(self) -> None:
# Displays text from right to left on the LCD.
self.displaymode &= ~_LCD_ENTRYLEFT
self._write8(_LCD_ENTRYMODESET | self.displaymode)

def create_char(self, location, pattern):
def create_char(self, location: int, pattern: Sequence[int]) -> None:
"""
Fill one of the first 8 CGRAM locations with custom characters.
The location parameter should be between 0 and 7 and pattern should
provide an array of 8 bytes containing the pattern. E.g. you can easily
design your custom character at http://www.quinapalus.com/hd44780udg.html
To show your custom character use, for example, ``lcd.message = "\x01"``

:param location: integer in range(8) to store the created character
:param ~bytes pattern: len(8) describes created character
:param int location: Integer in range(8) to store the created character.
:param Sequence[int] pattern: len(8) describes created character.

"""
# only position 0..7 are allowed
Expand All @@ -483,9 +499,9 @@ def create_char(self, location, pattern):
for i in range(8):
self._write8(pattern[i], char_mode=True)

def _write8(self, value, char_mode=False):
def _write8(self, value: int, char_mode: bool = False) -> None:
# Sends 8b ``value`` in ``char_mode``.
# :param value: bytes
# :param value: int
# :param char_mode: character/data mode selector. False (default) for
# data only, True for character bits.
# one ms delay to prevent writing too quickly.
Expand All @@ -506,7 +522,7 @@ def _write8(self, value, char_mode=False):
self.dl7.value = ((value >> 3) & 1) > 0
self._pulse_enable()

def _pulse_enable(self):
def _pulse_enable(self) -> None:
# Pulses (lo->hi->lo) to send commands.
self.enable.value = False
# 1microsec pause
Expand All @@ -530,8 +546,8 @@ class Character_LCD_Mono(Character_LCD):
:param ~digitalio.DigitalInOut d5: The data line 5
:param ~digitalio.DigitalInOut d6: The data line 6
:param ~digitalio.DigitalInOut d7: The data line 7
:param columns: The columns on the charLCD
:param lines: The lines on the charLCD
:param int columns: The columns on the charLCD
:param int lines: The lines on the charLCD
:param ~digitalio.DigitalInOut backlight_pin: The backlight pin
:param bool backlight_inverted: ``False`` if LCD is not inverted, i.e. backlight pin is
connected to common anode. ``True`` if LCD is inverted i.e. backlight pin is connected
Expand All @@ -542,16 +558,16 @@ class Character_LCD_Mono(Character_LCD):
# pylint: disable-msg=too-many-arguments
def __init__(
self,
rs,
en,
db4,
db5,
db6,
db7,
columns,
lines,
backlight_pin=None,
backlight_inverted=False,
rs: digitalio.DigitalInOut,
en: digitalio.DigitalInOut,
db4: digitalio.DigitalInOut,
db5: digitalio.DigitalInOut,
db6: digitalio.DigitalInOut,
db7: digitalio.DigitalInOut,
columns: int,
lines: int,
backlight_pin: Optional[digitalio.DigitalInOut] = None,
backlight_inverted: bool = False,
):

# Backlight pin and inversion
Expand All @@ -567,7 +583,7 @@ def __init__(
# pylint: enable-msg=too-many-arguments

@property
def backlight(self):
def backlight(self) -> Optional[bool]:
"""Enable or disable backlight. True if backlight is on. False if backlight is off.

The following example turns the backlight off, then displays, "Hello, world?", then turns
Expand All @@ -594,7 +610,7 @@ def backlight(self):
return self._enable

@backlight.setter
def backlight(self, enable):
def backlight(self, enable: bool) -> None:
self._enable = enable
if enable:
self.backlight_pin.value = not self.backlight_inverted
Expand All @@ -611,8 +627,8 @@ class Character_LCD_RGB(Character_LCD):
:param ~digitalio.DigitalInOut db5: The data line 5
:param ~digitalio.DigitalInOut db6: The data line 6
:param ~digitalio.DigitalInOut db7: The data line 7
:param columns: The columns on the charLCD
:param lines: The lines on the charLCD
:param int columns: The columns on the charLCD
:param int lines: The lines on the charLCD
:param ~pwmio.PWMOut,~digitalio.DigitalInOut red: Red RGB Anode
:param ~pwmio.PWMOut,~digitalio.DigitalInOut green: Green RGB Anode
:param ~pwmio.PWMOut,~digitalio.DigitalInOut blue: Blue RGB Anode
Expand All @@ -624,19 +640,19 @@ class Character_LCD_RGB(Character_LCD):
# pylint: disable-msg=too-many-arguments
def __init__(
self,
rs,
en,
db4,
db5,
db6,
db7,
columns,
lines,
red,
green,
blue,
read_write=None,
):
rs: digitalio.DigitalInOut,
en: digitalio.DigitalInOut,
db4: digitalio.DigitalInOut,
db5: digitalio.DigitalInOut,
db6: digitalio.DigitalInOut,
db7: digitalio.DigitalInOut,
columns: int,
lines: int,
red: Union[pwmio.PWMOut, digitalio.DigitalInOut],
green: Union[pwmio.PWMOut, digitalio.DigitalInOut],
blue: Union[pwmio.PWMOut, digitalio.DigitalInOut],
read_write: Optional[digitalio.DigitalInOut] = None,
) -> None:

# Define read_write (rw) pin
self.read_write = read_write
Expand All @@ -662,7 +678,7 @@ def __init__(
super().__init__(rs, en, db4, db5, db6, db7, columns, lines)

@property
def color(self):
def color(self) -> List[int]:
"""
The color of the display. Provide a list of three integers ranging 0 - 100, ``[R, G, B]``.
``0`` is no color, or "off". ``100`` is maximum color. For example, the brightest red would
Expand Down Expand Up @@ -693,7 +709,7 @@ def color(self):
return self._color

@color.setter
def color(self, color):
def color(self, color: Union[List[float], int]) -> None:
if isinstance(color, int):
if color >> 24:
raise ValueError("Integer color value must be positive and 24 bits max")
Expand Down
Loading