Skip to content

Commit bae21e5

Browse files
committed
set all the MCP23008 gpio bits at once to speed up I2C
1 parent e00f577 commit bae21e5

File tree

4 files changed

+71
-77
lines changed

4 files changed

+71
-77
lines changed

.pre-commit-config.yaml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,21 @@
44

55
repos:
66
- repo: https://github.com/python/black
7-
rev: 20.8b1
7+
rev: 23.3.0
88
hooks:
99
- id: black
1010
- repo: https://github.com/fsfe/reuse-tool
11-
rev: v0.12.1
11+
rev: v1.1.1
1212
hooks:
1313
- id: reuse
1414
- repo: https://github.com/pre-commit/pre-commit-hooks
15-
rev: v2.3.0
15+
rev: v4.4.0
1616
hooks:
1717
- id: check-yaml
1818
- id: end-of-file-fixer
1919
- id: trailing-whitespace
2020
- repo: https://github.com/pycqa/pylint
21-
rev: v2.11.1
21+
rev: v3.3.1
2222
hooks:
2323
- id: pylint
2424
name: pylint (library code)

.pylintrc

Lines changed: 9 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
1+
# SPDX-FileCopyrightText: 2017 Scott Shawcroft, written for Adafruit Industries
22
#
33
# SPDX-License-Identifier: Unlicense
44

@@ -9,11 +9,11 @@
99
# run arbitrary code
1010
extension-pkg-whitelist=
1111

12-
# Add files or directories to the blacklist. They should be base names, not
12+
# Add files or directories to the ignore-list. They should be base names, not
1313
# paths.
1414
ignore=CVS
1515

16-
# Add files or directories matching the regex patterns to the blacklist. The
16+
# Add files or directories matching the regex patterns to the ignore-list. The
1717
# regex matches against base names, not paths.
1818
ignore-patterns=
1919

@@ -26,7 +26,7 @@ jobs=1
2626

2727
# List of plugins (as comma separated values of python modules names) to load,
2828
# usually to register additional checkers.
29-
load-plugins=
29+
load-plugins=pylint.extensions.no_self_use
3030

3131
# Pickle collected data for later comparisons.
3232
persistent=yes
@@ -54,8 +54,8 @@ confidence=
5454
# --enable=similarities". If you want to run only the classes checker, but have
5555
# no Warning level messages displayed, use"--disable=all --enable=classes
5656
# --disable=W"
57-
# disable=import-error,print-statement,parameter-unpacking,unpacking-in-except,old-raise-syntax,backtick,long-suffix,old-ne-operator,old-octal-literal,import-star-module-level,raw-checker-failed,bad-inline-option,locally-disabled,locally-enabled,file-ignored,suppressed-message,useless-suppression,deprecated-pragma,apply-builtin,basestring-builtin,buffer-builtin,cmp-builtin,coerce-builtin,execfile-builtin,file-builtin,long-builtin,raw_input-builtin,reduce-builtin,standarderror-builtin,unicode-builtin,xrange-builtin,coerce-method,delslice-method,getslice-method,setslice-method,no-absolute-import,old-division,dict-iter-method,dict-view-method,next-method-called,metaclass-assignment,indexing-exception,raising-string,reload-builtin,oct-method,hex-method,nonzero-method,cmp-method,input-builtin,round-builtin,intern-builtin,unichr-builtin,map-builtin-not-iterating,zip-builtin-not-iterating,range-builtin-not-iterating,filter-builtin-not-iterating,using-cmp-argument,eq-without-hash,div-method,idiv-method,rdiv-method,exception-message-attribute,invalid-str-codec,sys-max-int,bad-python3-import,deprecated-string-function,deprecated-str-translate-call
58-
disable=print-statement,parameter-unpacking,unpacking-in-except,old-raise-syntax,backtick,long-suffix,old-ne-operator,old-octal-literal,import-star-module-level,raw-checker-failed,bad-inline-option,locally-disabled,locally-enabled,file-ignored,suppressed-message,useless-suppression,deprecated-pragma,apply-builtin,basestring-builtin,buffer-builtin,cmp-builtin,coerce-builtin,execfile-builtin,file-builtin,long-builtin,raw_input-builtin,reduce-builtin,standarderror-builtin,unicode-builtin,xrange-builtin,coerce-method,delslice-method,getslice-method,setslice-method,no-absolute-import,old-division,dict-iter-method,dict-view-method,next-method-called,metaclass-assignment,indexing-exception,raising-string,reload-builtin,oct-method,hex-method,nonzero-method,cmp-method,input-builtin,round-builtin,intern-builtin,unichr-builtin,map-builtin-not-iterating,zip-builtin-not-iterating,range-builtin-not-iterating,filter-builtin-not-iterating,using-cmp-argument,eq-without-hash,div-method,idiv-method,rdiv-method,exception-message-attribute,invalid-str-codec,sys-max-int,bad-python3-import,deprecated-string-function,deprecated-str-translate-call,import-error,bad-continuation,unspecified-encoding
57+
# disable=import-error,raw-checker-failed,bad-inline-option,locally-disabled,file-ignored,suppressed-message,useless-suppression,deprecated-pragma,deprecated-str-translate-call
58+
disable=raw-checker-failed,bad-inline-option,locally-disabled,file-ignored,suppressed-message,useless-suppression,deprecated-pragma,import-error,pointless-string-statement,unspecified-encoding
5959

6060
# Enable the message, report, category or checker with the given id(s). You can
6161
# either give multiple identifier separated by comma (,) or put this option
@@ -225,12 +225,6 @@ max-line-length=100
225225
# Maximum number of lines in a module
226226
max-module-lines=1000
227227

228-
# List of optional constructs for which whitespace checking is disabled. `dict-
229-
# separator` is used to allow tabulation in dicts, etc.: {1 : 1,\n222: 2}.
230-
# `trailing-comma` allows a space between comma and closing bracket: (a, ).
231-
# `empty-line` allows space-only lines.
232-
no-space-check=trailing-comma,dict-separator
233-
234228
# Allow the body of a class to be on the same line as the declaration if body
235229
# contains single statement.
236230
single-line-class-stmt=no
@@ -252,53 +246,34 @@ ignore-docstrings=yes
252246
ignore-imports=yes
253247

254248
# Minimum lines number of a similarity.
255-
min-similarity-lines=4
249+
min-similarity-lines=12
256250

257251

258252
[BASIC]
259253

260-
# Naming hint for argument names
261-
argument-name-hint=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
262-
263254
# Regular expression matching correct argument names
264255
argument-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
265256

266-
# Naming hint for attribute names
267-
attr-name-hint=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
268-
269257
# Regular expression matching correct attribute names
270258
attr-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
271259

272260
# Bad variable names which should always be refused, separated by a comma
273261
bad-names=foo,bar,baz,toto,tutu,tata
274262

275-
# Naming hint for class attribute names
276-
class-attribute-name-hint=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$
277-
278263
# Regular expression matching correct class attribute names
279264
class-attribute-rgx=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$
280265

281-
# Naming hint for class names
282-
# class-name-hint=[A-Z_][a-zA-Z0-9]+$
283-
class-name-hint=[A-Z_][a-zA-Z0-9_]+$
284-
285266
# Regular expression matching correct class names
286267
# class-rgx=[A-Z_][a-zA-Z0-9]+$
287268
class-rgx=[A-Z_][a-zA-Z0-9_]+$
288269

289-
# Naming hint for constant names
290-
const-name-hint=(([A-Z_][A-Z0-9_]*)|(__.*__))$
291-
292270
# Regular expression matching correct constant names
293271
const-rgx=(([A-Z_][A-Z0-9_]*)|(__.*__))$
294272

295273
# Minimum line length for functions/classes that require docstrings, shorter
296274
# ones are exempt.
297275
docstring-min-length=-1
298276

299-
# Naming hint for function names
300-
function-name-hint=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
301-
302277
# Regular expression matching correct function names
303278
function-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
304279

@@ -309,21 +284,12 @@ good-names=r,g,b,w,i,j,k,n,x,y,z,ex,ok,Run,_
309284
# Include a hint for the correct naming format with invalid-name
310285
include-naming-hint=no
311286

312-
# Naming hint for inline iteration names
313-
inlinevar-name-hint=[A-Za-z_][A-Za-z0-9_]*$
314-
315287
# Regular expression matching correct inline iteration names
316288
inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$
317289

318-
# Naming hint for method names
319-
method-name-hint=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
320-
321290
# Regular expression matching correct method names
322291
method-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
323292

324-
# Naming hint for module names
325-
module-name-hint=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$
326-
327293
# Regular expression matching correct module names
328294
module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$
329295

@@ -339,9 +305,6 @@ no-docstring-rgx=^_
339305
# to this list to register other decorators that produce valid properties.
340306
property-classes=abc.abstractproperty
341307

342-
# Naming hint for variable names
343-
variable-name-hint=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
344-
345308
# Regular expression matching correct variable names
346309
variable-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
347310

@@ -398,7 +361,7 @@ valid-metaclass-classmethod-first-arg=mcs
398361
[DESIGN]
399362

400363
# Maximum number of arguments for function / method
401-
max-args=5
364+
max-args=13
402365

403366
# Maximum number of attributes for a class (see R0902).
404367
# max-attributes=7
@@ -433,4 +396,4 @@ min-public-methods=1
433396

434397
# Exceptions that will emit a warning when being caught. Defaults to
435398
# "Exception"
436-
overgeneral-exceptions=Exception
399+
overgeneral-exceptions=builtins.Exception

adafruit_character_lcd/character_lcd.py

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ def _map(xval, in_min, in_max, out_min, out_max):
9696
return ret
9797

9898

99-
# pylint: disable-msg=too-many-instance-attributes
99+
# pylint: disable=too-many-instance-attributes
100100
class Character_LCD:
101101
"""Base class for character LCD.
102102
@@ -114,9 +114,8 @@ class Character_LCD:
114114
LEFT_TO_RIGHT = const(0)
115115
RIGHT_TO_LEFT = const(1)
116116

117-
# pylint: disable-msg=too-many-arguments
117+
# pylint: disable=too-many-positional-arguments,invalid-name
118118
def __init__(self, rs, en, d4, d5, d6, d7, columns, lines):
119-
120119
self.columns = columns
121120
self.lines = lines
122121
# save pin numbers
@@ -148,9 +147,9 @@ def __init__(self, rs, en, d4, d5, d6, d7, columns, lines):
148147
self._write8(_LCD_ENTRYMODESET | self.displaymode)
149148
self.clear()
150149

151-
self._message = None
152-
self._enable = None
153-
self._direction = None
150+
self._message = ""
151+
self._backlight_on = False
152+
self._direction = self.LEFT_TO_RIGHT
154153
# track row and column used in cursor_position
155154
# initialize to 0,0
156155
self.row = 0
@@ -484,6 +483,7 @@ def create_char(self, location, pattern):
484483
self._write8(pattern[i], char_mode=True)
485484

486485
def _write8(self, value, char_mode=False):
486+
print(f"bit-by-bit: {char_mode=}, {value=:x}")
487487
# Sends 8b ``value`` in ``char_mode``.
488488
# :param value: bytes
489489
# :param char_mode: character/data mode selector. False (default) for
@@ -520,7 +520,7 @@ def _pulse_enable(self):
520520
# pylint: enable-msg=too-many-instance-attributes
521521

522522

523-
# pylint: disable-msg=too-many-instance-attributes
523+
# pylint: disable=too-many-instance-attributes
524524
class Character_LCD_Mono(Character_LCD):
525525
"""Interfaces with monochromatic character LCDs.
526526
@@ -539,7 +539,7 @@ class Character_LCD_Mono(Character_LCD):
539539
540540
"""
541541

542-
# pylint: disable-msg=too-many-arguments
542+
# pylint: disable=too-many-positional-arguments
543543
def __init__(
544544
self,
545545
rs,
@@ -553,7 +553,6 @@ def __init__(
553553
backlight_pin=None,
554554
backlight_inverted=False,
555555
):
556-
557556
# Backlight pin and inversion
558557
self.backlight_pin = backlight_pin
559558
self.backlight_inverted = backlight_inverted
@@ -591,15 +590,12 @@ def backlight(self):
591590
time.sleep(5)
592591
593592
"""
594-
return self._enable
593+
return self._backlight_on
595594

596595
@backlight.setter
597596
def backlight(self, enable):
598-
self._enable = enable
599-
if enable:
600-
self.backlight_pin.value = not self.backlight_inverted
601-
else:
602-
self.backlight_pin.value = self.backlight_inverted
597+
self._backlight_on = enable
598+
self.backlight_pin.value = enable ^ self.backlight_inverted
603599

604600

605601
class Character_LCD_RGB(Character_LCD):
@@ -621,7 +617,7 @@ class Character_LCD_RGB(Character_LCD):
621617
622618
"""
623619

624-
# pylint: disable-msg=too-many-arguments
620+
# pylint: disable=too-many-positional-arguments,invalid-name
625621
def __init__(
626622
self,
627623
rs,
@@ -637,7 +633,6 @@ def __init__(
637633
blue,
638634
read_write=None,
639635
):
640-
641636
# Define read_write (rw) pin
642637
self.read_write = read_write
643638

adafruit_character_lcd/character_lcd_i2c.py

Lines changed: 46 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
2929
"""
3030

31+
import time
32+
3133
from adafruit_mcp230xx.mcp23008 import MCP23008
3234
from adafruit_character_lcd.character_lcd import Character_LCD_Mono
3335

@@ -36,7 +38,7 @@
3638

3739

3840
class Character_LCD_I2C(Character_LCD_Mono):
39-
# pylint: disable=too-few-public-methods, too-many-arguments
41+
# pylint: disable=too-few-public-methods
4042
"""Character LCD connected to I2C/SPI backpack using its I2C connection.
4143
This is a subclass of `Character_LCD_Mono` and implements all of the
4244
same functions and functionality.
@@ -52,25 +54,59 @@ class Character_LCD_I2C(Character_LCD_Mono):
5254
lcd = Character_LCD_I2C(i2c, 16, 2)
5355
"""
5456

57+
# pylint: disable=too-many-positional-arguments
5558
def __init__(self, i2c, columns, lines, address=None, backlight_inverted=False):
5659
"""Initialize character LCD connected to backpack using I2C connection
5760
on the specified I2C bus with the specified number of columns and
5861
lines on the display. Optionally specify if backlight is inverted.
5962
"""
6063

6164
if address:
62-
mcp = MCP23008(i2c, address=address)
65+
self.mcp = MCP23008(i2c, address=address)
6366
else:
64-
mcp = MCP23008(i2c)
67+
self.mcp = MCP23008(i2c)
6568
super().__init__(
66-
mcp.get_pin(1),
67-
mcp.get_pin(2),
68-
mcp.get_pin(3),
69-
mcp.get_pin(4),
70-
mcp.get_pin(5),
71-
mcp.get_pin(6),
69+
self.mcp.get_pin(1), # reset
70+
self.mcp.get_pin(2), # enable
71+
self.mcp.get_pin(3), # data line 4
72+
self.mcp.get_pin(4), # data line 5
73+
self.mcp.get_pin(5), # data line 6
74+
self.mcp.get_pin(6), # data line 7
7275
columns,
7376
lines,
74-
backlight_pin=mcp.get_pin(7),
77+
backlight_pin=self.mcp.get_pin(7),
7578
backlight_inverted=backlight_inverted,
7679
)
80+
81+
def _write8(self, value, char_mode=False):
82+
# Sends 8b ``value`` in ``char_mode``.
83+
# :param value: bytes
84+
# :param char_mode: character/data mode selector. False (default) for
85+
# data only, True for character bits.
86+
# one ms delay to prevent writing too quickly.
87+
time.sleep(0.001)
88+
89+
# bits are, MSB (7) to LSB (0)
90+
# backlight: bit 7
91+
# data line 7: bit 6
92+
# data line 6: bit 5
93+
# data line 5: bit 4
94+
# data line 4: bit 3
95+
# enable: bit 2
96+
# reset: bit 1
97+
# (unused): bit 0
98+
99+
reset_bit = int(char_mode) << 1
100+
backlight_bit = int(self.backlight ^ self.backlight_inverted) << 7
101+
102+
# Write char_mode and upper 4 bits of data, shifted to the correct position.
103+
self.mcp.gpio = reset_bit | backlight_bit | ((value & 0xF0) >> 1)
104+
105+
# do command
106+
self._pulse_enable()
107+
108+
# Write char_mode and lower 4 bits of data, shifted to the correct position.
109+
self.mcp.gpio = reset_bit | backlight_bit | ((value & 0x0F) << 3)
110+
111+
# do command
112+
self._pulse_enable()

0 commit comments

Comments
 (0)