Skip to content

Commit c7bd36e

Browse files
authored
Merge pull request #80 from dhalbert/faster-I2C
Speed up I2C by not setting the MCP23008 bits one at a time.
2 parents 2ec52f9 + 683d68c commit c7bd36e

File tree

5 files changed

+63
-28
lines changed

5 files changed

+63
-28
lines changed

.pre-commit-config.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ repos:
1818
- id: end-of-file-fixer
1919
- id: trailing-whitespace
2020
- repo: https://github.com/pycqa/pylint
21-
rev: v2.17.4
21+
rev: v3.3.1
2222
hooks:
2323
- id: pylint
2424
name: pylint (library code)

.pylintrc

+1-1
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,7 @@ valid-metaclass-classmethod-first-arg=mcs
361361
[DESIGN]
362362

363363
# Maximum number of arguments for function / method
364-
max-args=5
364+
max-args=13
365365

366366
# Maximum number of attributes for a class (see R0902).
367367
# max-attributes=7

adafruit_character_lcd/character_lcd.py

+13-15
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ def _map(
103103
return ret
104104

105105

106-
# pylint: disable-msg=too-many-instance-attributes
106+
# pylint: disable=too-many-instance-attributes
107107
class Character_LCD:
108108
"""Base class for character LCD.
109109
@@ -121,7 +121,7 @@ class Character_LCD:
121121
LEFT_TO_RIGHT = const(0)
122122
RIGHT_TO_LEFT = const(1)
123123

124-
# pylint: disable-msg=too-many-arguments
124+
# pylint: disable=too-many-positional-arguments
125125
def __init__(
126126
self,
127127
reset_dio: digitalio.DigitalInOut,
@@ -163,9 +163,10 @@ def __init__(
163163
# Set entry mode
164164
self._write8(_LCD_ENTRYMODESET | self.displaymode)
165165
self.clear()
166-
self._message = None
167-
self._enable = None
168-
self._direction = None
166+
167+
self._message = ""
168+
self._backlight_on = False
169+
self._direction = self.LEFT_TO_RIGHT
169170
# track row and column used in cursor_position
170171
# initialize to 0,0
171172
self.row = 0
@@ -535,7 +536,7 @@ def _pulse_enable(self) -> None:
535536
# pylint: enable-msg=too-many-instance-attributes
536537

537538

538-
# pylint: disable-msg=too-many-instance-attributes
539+
# pylint: disable=too-many-instance-attributes
539540
class Character_LCD_Mono(Character_LCD):
540541
"""Interfaces with monochromatic character LCDs.
541542
@@ -554,7 +555,7 @@ class Character_LCD_Mono(Character_LCD):
554555
555556
"""
556557

557-
# pylint: disable-msg=too-many-arguments
558+
# pylint: disable=too-many-positional-arguments
558559
def __init__(
559560
self,
560561
reset_dio: digitalio.DigitalInOut,
@@ -607,15 +608,12 @@ def backlight(self) -> Optional[bool]:
607608
time.sleep(5)
608609
609610
"""
610-
return self._enable
611+
return self._backlight_on
611612

612613
@backlight.setter
613-
def backlight(self, enable: bool) -> None:
614-
self._enable = enable
615-
if enable:
616-
self.backlight_pin.value = not self.backlight_inverted
617-
else:
618-
self.backlight_pin.value = self.backlight_inverted
614+
def backlight(self, enable):
615+
self._backlight_on = enable
616+
self.backlight_pin.value = enable ^ self.backlight_inverted
619617

620618

621619
class Character_LCD_RGB(Character_LCD):
@@ -637,7 +635,7 @@ class Character_LCD_RGB(Character_LCD):
637635
638636
"""
639637

640-
# pylint: disable-msg=too-many-arguments
638+
# pylint: disable=too-many-positional-arguments
641639
def __init__(
642640
self,
643641
reset_dio: digitalio.DigitalInOut,

adafruit_character_lcd/character_lcd_i2c.py

+46-10
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
https://github.com/adafruit/Adafruit_CircuitPython_BusDevice
2828
2929
"""
30+
import time
31+
3032
try:
3133
from typing import Optional
3234
import busio
@@ -41,7 +43,7 @@
4143

4244

4345
class Character_LCD_I2C(Character_LCD_Mono):
44-
# pylint: disable=too-few-public-methods, too-many-arguments
46+
# pylint: disable=too-few-public-methods
4547
"""Character LCD connected to I2C/SPI backpack using its I2C connection.
4648
This is a subclass of `Character_LCD_Mono` and implements all the same
4749
functions and functionality.
@@ -57,6 +59,7 @@ class Character_LCD_I2C(Character_LCD_Mono):
5759
lcd = Character_LCD_I2C(i2c, 16, 2)
5860
"""
5961

62+
# pylint: disable=too-many-positional-arguments
6063
def __init__(
6164
self,
6265
i2c: busio.I2C,
@@ -71,18 +74,51 @@ def __init__(
7174
"""
7275

7376
if address:
74-
mcp = MCP23008(i2c, address=address)
77+
self.mcp = MCP23008(i2c, address=address)
7578
else:
76-
mcp = MCP23008(i2c)
79+
self.mcp = MCP23008(i2c)
7780
super().__init__(
78-
mcp.get_pin(1),
79-
mcp.get_pin(2),
80-
mcp.get_pin(3),
81-
mcp.get_pin(4),
82-
mcp.get_pin(5),
83-
mcp.get_pin(6),
81+
self.mcp.get_pin(1), # reset
82+
self.mcp.get_pin(2), # enable
83+
self.mcp.get_pin(3), # data line 4
84+
self.mcp.get_pin(4), # data line 5
85+
self.mcp.get_pin(5), # data line 6
86+
self.mcp.get_pin(6), # data line 7
8487
columns,
8588
lines,
86-
backlight_pin=mcp.get_pin(7),
89+
backlight_pin=self.mcp.get_pin(7),
8790
backlight_inverted=backlight_inverted,
8891
)
92+
93+
def _write8(self, value: int, char_mode: bool = False) -> None:
94+
# Sends 8b ``value`` in ``char_mode``.
95+
# :param value: bytes
96+
# :param char_mode: character/data mode selector. False (default) for
97+
# data only, True for character bits.
98+
# one ms delay to prevent writing too quickly.
99+
time.sleep(0.001)
100+
101+
# bits are, MSB (7) to LSB (0)
102+
# backlight: bit 7
103+
# data line 7: bit 6
104+
# data line 6: bit 5
105+
# data line 5: bit 4
106+
# data line 4: bit 3
107+
# enable: bit 2
108+
# reset: bit 1
109+
# (unused): bit 0
110+
111+
reset_bit = int(char_mode) << 1
112+
backlight_bit = int(self.backlight ^ self.backlight_inverted) << 7
113+
114+
# Write char_mode and upper 4 bits of data, shifted to the correct position.
115+
self.mcp.gpio = reset_bit | backlight_bit | ((value & 0xF0) >> 1)
116+
117+
# do command
118+
self._pulse_enable()
119+
120+
# Write char_mode and lower 4 bits of data, shifted to the correct position.
121+
self.mcp.gpio = reset_bit | backlight_bit | ((value & 0x0F) << 3)
122+
123+
# do command
124+
self._pulse_enable()

adafruit_character_lcd/character_lcd_spi.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,8 @@ class Character_LCD_SPI(Character_LCD_Mono): # pylint: disable=too-few-public-m
5959
lcd = character_lcd.Character_LCD_SPI(spi, latch, 16, 2)
6060
"""
6161

62-
def __init__( # pylint: disable=too-many-arguments
62+
# pylint: disable=too-many-positional-arguments
63+
def __init__(
6364
self,
6465
spi: busio.SPI,
6566
latch: digitalio.DigitalInOut,

0 commit comments

Comments
 (0)