diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fff3aa9..1dad804 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -40,7 +40,7 @@ jobs: source actions-ci/install.sh - name: Pip install pylint, black, & Sphinx run: | - pip install --force-reinstall pylint==1.9.2 black==19.10b0 Sphinx sphinx-rtd-theme + pip install --force-reinstall pylint black==19.10b0 Sphinx sphinx-rtd-theme - name: Library version run: git describe --dirty --always --tags - name: PyLint diff --git a/adafruit_ssd1306.py b/adafruit_ssd1306.py index ad46638..8a56b06 100644 --- a/adafruit_ssd1306.py +++ b/adafruit_ssd1306.py @@ -32,6 +32,7 @@ from micropython import const from adafruit_bus_device import i2c_device, spi_device + try: import framebuf except ImportError: @@ -40,31 +41,32 @@ __version__ = "0.0.0-auto.0" __repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_SSD1306.git" -#pylint: disable-msg=bad-whitespace +# pylint: disable-msg=bad-whitespace # register definitions -SET_CONTRAST = const(0x81) -SET_ENTIRE_ON = const(0xa4) -SET_NORM_INV = const(0xa6) -SET_DISP = const(0xae) -SET_MEM_ADDR = const(0x20) -SET_COL_ADDR = const(0x21) -SET_PAGE_ADDR = const(0x22) +SET_CONTRAST = const(0x81) +SET_ENTIRE_ON = const(0xA4) +SET_NORM_INV = const(0xA6) +SET_DISP = const(0xAE) +SET_MEM_ADDR = const(0x20) +SET_COL_ADDR = const(0x21) +SET_PAGE_ADDR = const(0x22) SET_DISP_START_LINE = const(0x40) -SET_SEG_REMAP = const(0xa0) -SET_MUX_RATIO = const(0xa8) -SET_COM_OUT_DIR = const(0xc0) -SET_DISP_OFFSET = const(0xd3) -SET_COM_PIN_CFG = const(0xda) -SET_DISP_CLK_DIV = const(0xd5) -SET_PRECHARGE = const(0xd9) -SET_VCOM_DESEL = const(0xdb) -SET_CHARGE_PUMP = const(0x8d) -#pylint: enable-msg=bad-whitespace +SET_SEG_REMAP = const(0xA0) +SET_MUX_RATIO = const(0xA8) +SET_COM_OUT_DIR = const(0xC0) +SET_DISP_OFFSET = const(0xD3) +SET_COM_PIN_CFG = const(0xDA) +SET_DISP_CLK_DIV = const(0xD5) +SET_PRECHARGE = const(0xD9) +SET_VCOM_DESEL = const(0xDB) +SET_CHARGE_PUMP = const(0x8D) +# pylint: enable-msg=bad-whitespace class _SSD1306(framebuf.FrameBuffer): """Base class for SSD1306 display driver""" - #pylint: disable-msg=too-many-arguments + + # pylint: disable-msg=too-many-arguments def __init__(self, buffer, width, height, *, external_vcc, reset): super().__init__(buffer, width, height) self.width = width @@ -90,27 +92,37 @@ def power(self): def init_display(self): """Base class to initialize display""" for cmd in ( - SET_DISP | 0x00, # off - # address setting - SET_MEM_ADDR, 0x00, # horizontal - # resolution and layout - SET_DISP_START_LINE | 0x00, - SET_SEG_REMAP | 0x01, # column addr 127 mapped to SEG0 - SET_MUX_RATIO, self.height - 1, - SET_COM_OUT_DIR | 0x08, # scan from COM[N] to COM0 - SET_DISP_OFFSET, 0x00, - SET_COM_PIN_CFG, 0x02 if self.height == 32 or self.height == 16 else 0x12, - # timing and driving scheme - SET_DISP_CLK_DIV, 0x80, - SET_PRECHARGE, 0x22 if self.external_vcc else 0xf1, - SET_VCOM_DESEL, 0x30, # 0.83*Vcc - # display - SET_CONTRAST, 0xff, # maximum - SET_ENTIRE_ON, # output follows RAM contents - SET_NORM_INV, # not inverted - # charge pump - SET_CHARGE_PUMP, 0x10 if self.external_vcc else 0x14, - SET_DISP | 0x01): # on + SET_DISP | 0x00, # off + # address setting + SET_MEM_ADDR, + 0x00, # horizontal + # resolution and layout + SET_DISP_START_LINE | 0x00, + SET_SEG_REMAP | 0x01, # column addr 127 mapped to SEG0 + SET_MUX_RATIO, + self.height - 1, + SET_COM_OUT_DIR | 0x08, # scan from COM[N] to COM0 + SET_DISP_OFFSET, + 0x00, + SET_COM_PIN_CFG, + 0x02 if self.height == 32 or self.height == 16 else 0x12, + # timing and driving scheme + SET_DISP_CLK_DIV, + 0x80, + SET_PRECHARGE, + 0x22 if self.external_vcc else 0xF1, + SET_VCOM_DESEL, + 0x30, # 0.83*Vcc + # display + SET_CONTRAST, + 0xFF, # maximum + SET_ENTIRE_ON, # output follows RAM contents + SET_NORM_INV, # not inverted + # charge pump + SET_CHARGE_PUMP, + 0x10 if self.external_vcc else 0x14, + SET_DISP | 0x01, + ): # on self.write_cmd(cmd) if self.width == 72: self.write_cmd(0xAD) @@ -172,6 +184,7 @@ def show(self): self.write_cmd(self.pages - 1) self.write_framebuf() + class SSD1306_I2C(_SSD1306): """ I2C class for SSD1306 @@ -184,7 +197,9 @@ class SSD1306_I2C(_SSD1306): :param reset: if needed, DigitalInOut designating reset pin """ - def __init__(self, width, height, i2c, *, addr=0x3c, external_vcc=False, reset=None): + def __init__( + self, width, height, i2c, *, addr=0x3C, external_vcc=False, reset=None + ): self.i2c_device = i2c_device.I2CDevice(i2c, addr) self.addr = addr self.temp = bytearray(2) @@ -195,12 +210,17 @@ def __init__(self, width, height, i2c, *, addr=0x3c, external_vcc=False, reset=N # buffer). self.buffer = bytearray(((height // 8) * width) + 1) self.buffer[0] = 0x40 # Set first byte of data buffer to Co=0, D/C=1 - super().__init__(memoryview(self.buffer)[1:], width, height, - external_vcc=external_vcc, reset=reset) + super().__init__( + memoryview(self.buffer)[1:], + width, + height, + external_vcc=external_vcc, + reset=reset, + ) def write_cmd(self, cmd): """Send a command to the SPI device""" - self.temp[0] = 0x80 # Co=1, D/C#=0 + self.temp[0] = 0x80 # Co=1, D/C#=0 self.temp[1] = cmd with self.i2c_device: self.i2c_device.write(self.temp) @@ -211,7 +231,8 @@ def write_framebuf(self): with self.i2c_device: self.i2c_device.write(self.buffer) -#pylint: disable-msg=too-many-arguments + +# pylint: disable-msg=too-many-arguments class SSD1306_SPI(_SSD1306): """ SPI class for SSD1306 @@ -223,18 +244,37 @@ class SSD1306_SPI(_SSD1306): :param reset: the reset pin to use, :param cs: the chip-select pin to use (sometimes labeled "SS"). """ + # pylint: disable=no-member # Disable should be reconsidered when refactor can be tested. - def __init__(self, width, height, spi, dc, reset, cs, *, - external_vcc=False, baudrate=8000000, polarity=0, phase=0): + def __init__( + self, + width, + height, + spi, + dc, + reset, + cs, + *, + external_vcc=False, + baudrate=8000000, + polarity=0, + phase=0 + ): self.rate = 10 * 1024 * 1024 dc.switch_to_output(value=0) - self.spi_device = spi_device.SPIDevice(spi, cs, baudrate=baudrate, - polarity=polarity, phase=phase) + self.spi_device = spi_device.SPIDevice( + spi, cs, baudrate=baudrate, polarity=polarity, phase=phase + ) self.dc_pin = dc self.buffer = bytearray((height // 8) * width) - super().__init__(memoryview(self.buffer), width, height, - external_vcc=external_vcc, reset=reset) + super().__init__( + memoryview(self.buffer), + width, + height, + external_vcc=external_vcc, + reset=reset, + ) def write_cmd(self, cmd): """Send a command to the SPI device""" diff --git a/docs/conf.py b/docs/conf.py index cfb21c4..e9b8962 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -2,7 +2,8 @@ import os import sys -sys.path.insert(0, os.path.abspath('..')) + +sys.path.insert(0, os.path.abspath("..")) # -- General configuration ------------------------------------------------ @@ -10,10 +11,10 @@ # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ - 'sphinx.ext.autodoc', - 'sphinx.ext.intersphinx', - 'sphinx.ext.napoleon', - 'sphinx.ext.todo', + "sphinx.ext.autodoc", + "sphinx.ext.intersphinx", + "sphinx.ext.napoleon", + "sphinx.ext.todo", ] # Uncomment the below if you use native CircuitPython modules such as @@ -21,29 +22,36 @@ # autodoc module docs will fail to generate with a warning. autodoc_mock_imports = ["framebuf"] -intersphinx_mapping = {'python': ('https://docs.python.org/3.4', None),'BusDevice': ('https://circuitpython.readthedocs.io/projects/busdevice/en/latest/', None),'CircuitPython': ('https://circuitpython.readthedocs.io/en/latest/', None)} +intersphinx_mapping = { + "python": ("https://docs.python.org/3.4", None), + "BusDevice": ( + "https://circuitpython.readthedocs.io/projects/busdevice/en/latest/", + None, + ), + "CircuitPython": ("https://circuitpython.readthedocs.io/en/latest/", None), +} # Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] +templates_path = ["_templates"] -source_suffix = '.rst' +source_suffix = ".rst" # The master toctree document. -master_doc = 'index' +master_doc = "index" # General information about the project. -project = u'Adafruit SSD1306 Library' -copyright = u'2017 Michael McWethy' -author = u'Michael McWethy' +project = u"Adafruit SSD1306 Library" +copyright = u"2017 Michael McWethy" +author = u"Michael McWethy" # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. -version = u'1.0' +version = u"1.0" # The full version, including alpha/beta/rc tags. -release = u'1.0' +release = u"1.0" # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. @@ -55,7 +63,7 @@ # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This patterns also effect to html_static_path and html_extra_path -exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store', '.env', 'CODE_OF_CONDUCT.md'] +exclude_patterns = ["_build", "Thumbs.db", ".DS_Store", ".env", "CODE_OF_CONDUCT.md"] # The reST default role (used for this markup: `text`) to use for all # documents. @@ -67,7 +75,7 @@ add_function_parentheses = True # The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' +pygments_style = "sphinx" # If true, `todo` and `todoList` produce output, else they produce nothing. todo_include_todos = False @@ -82,53 +90,56 @@ # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # -on_rtd = os.environ.get('READTHEDOCS', None) == 'True' +on_rtd = os.environ.get("READTHEDOCS", None) == "True" if not on_rtd: # only import and set the theme if we're building docs locally try: import sphinx_rtd_theme - html_theme = 'sphinx_rtd_theme' - html_theme_path = [sphinx_rtd_theme.get_html_theme_path(), '.'] + + html_theme = "sphinx_rtd_theme" + html_theme_path = [sphinx_rtd_theme.get_html_theme_path(), "."] except: - html_theme = 'default' - html_theme_path = ['.'] + html_theme = "default" + html_theme_path = ["."] else: - html_theme_path = ['.'] + html_theme_path = ["."] # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] +html_static_path = ["_static"] # Output file base name for HTML help builder. -htmlhelp_basename = 'AdafruitSsd1306Librarydoc' +htmlhelp_basename = "AdafruitSsd1306Librarydoc" # -- Options for LaTeX output --------------------------------------------- latex_elements = { - # The paper size ('letterpaper' or 'a4paper'). - # - # 'papersize': 'letterpaper', - - # The font size ('10pt', '11pt' or '12pt'). - # - # 'pointsize': '10pt', - - # Additional stuff for the LaTeX preamble. - # - # 'preamble': '', - - # Latex figure (float) alignment - # - # 'figure_align': 'htbp', + # The paper size ('letterpaper' or 'a4paper'). + # + # 'papersize': 'letterpaper', + # The font size ('10pt', '11pt' or '12pt'). + # + # 'pointsize': '10pt', + # Additional stuff for the LaTeX preamble. + # + # 'preamble': '', + # Latex figure (float) alignment + # + # 'figure_align': 'htbp', } # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ - (master_doc, 'AdafruitSSD1306Library.tex', u'AdafruitSSD1306 Library Documentation', - author, 'manual'), + ( + master_doc, + "AdafruitSSD1306Library.tex", + u"AdafruitSSD1306 Library Documentation", + author, + "manual", + ), ] # -- Options for manual page output --------------------------------------- @@ -136,8 +147,13 @@ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ - (master_doc, 'AdafruitSSD1306library', u'Adafruit SSD1306 Library Documentation', - [author], 1) + ( + master_doc, + "AdafruitSSD1306library", + u"Adafruit SSD1306 Library Documentation", + [author], + 1, + ) ] # -- Options for Texinfo output ------------------------------------------- @@ -146,7 +162,13 @@ # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ - (master_doc, 'AdafruitSSD1306Library', u'Adafruit SSD1306 Library Documentation', - author, 'AdafruitSSD1306Library', 'One line description of project.', - 'Miscellaneous'), + ( + master_doc, + "AdafruitSSD1306Library", + u"Adafruit SSD1306 Library Documentation", + author, + "AdafruitSSD1306Library", + "One line description of project.", + "Miscellaneous", + ), ] diff --git a/examples/ssd1306_bonnet_buttons.py b/examples/ssd1306_bonnet_buttons.py index 539afd1..8d98935 100644 --- a/examples/ssd1306_bonnet_buttons.py +++ b/examples/ssd1306_bonnet_buttons.py @@ -35,7 +35,6 @@ disp = adafruit_ssd1306.SSD1306_I2C(128, 64, i2c) - # Input pins: button_A = DigitalInOut(board.D5) button_A.direction = Direction.INPUT @@ -74,7 +73,7 @@ # Make sure to create image with mode '1' for 1-bit color. width = disp.width height = disp.height -image = Image.new('1', (width, height)) +image = Image.new("1", (width, height)) # Get drawing object to draw on image. draw = ImageDraw.Draw(image) @@ -84,43 +83,45 @@ while True: - if button_U.value: # button is released - draw.polygon([(20, 20), (30, 2), (40, 20)], outline=255, fill=0) #Up - else: # button is pressed: - draw.polygon([(20, 20), (30, 2), (40, 20)], outline=255, fill=1) #Up filled - - if button_L.value: # button is released - draw.polygon([(0, 30), (18, 21), (18, 41)], outline=255, fill=0) #left - else: # button is pressed: - draw.polygon([(0, 30), (18, 21), (18, 41)], outline=255, fill=1) #left filled - - if button_R.value: # button is released - draw.polygon([(60, 30), (42, 21), (42, 41)], outline=255, fill=0) #right - else: # button is pressed: - draw.polygon([(60, 30), (42, 21), (42, 41)], outline=255, fill=1) #right filled - - if button_D.value: # button is released - draw.polygon([(30, 60), (40, 42), (20, 42)], outline=255, fill=0) #down - else: # button is pressed: - draw.polygon([(30, 60), (40, 42), (20, 42)], outline=255, fill=1) #down filled - - if button_C.value: # button is released - draw.rectangle((20, 22, 40, 40), outline=255, fill=0) #center - else: # button is pressed: - draw.rectangle((20, 22, 40, 40), outline=255, fill=1) #center filled - - if button_A.value: # button is released - draw.ellipse((70, 40, 90, 60), outline=255, fill=0) #A button - else: # button is pressed: - draw.ellipse((70, 40, 90, 60), outline=255, fill=1) #A button filled - - if button_B.value: # button is released - draw.ellipse((100, 20, 120, 40), outline=255, fill=0) #B button - else: # button is pressed: - draw.ellipse((100, 20, 120, 40), outline=255, fill=1) #B button filled + if button_U.value: # button is released + draw.polygon([(20, 20), (30, 2), (40, 20)], outline=255, fill=0) # Up + else: # button is pressed: + draw.polygon([(20, 20), (30, 2), (40, 20)], outline=255, fill=1) # Up filled + + if button_L.value: # button is released + draw.polygon([(0, 30), (18, 21), (18, 41)], outline=255, fill=0) # left + else: # button is pressed: + draw.polygon([(0, 30), (18, 21), (18, 41)], outline=255, fill=1) # left filled + + if button_R.value: # button is released + draw.polygon([(60, 30), (42, 21), (42, 41)], outline=255, fill=0) # right + else: # button is pressed: + draw.polygon( + [(60, 30), (42, 21), (42, 41)], outline=255, fill=1 + ) # right filled + + if button_D.value: # button is released + draw.polygon([(30, 60), (40, 42), (20, 42)], outline=255, fill=0) # down + else: # button is pressed: + draw.polygon([(30, 60), (40, 42), (20, 42)], outline=255, fill=1) # down filled + + if button_C.value: # button is released + draw.rectangle((20, 22, 40, 40), outline=255, fill=0) # center + else: # button is pressed: + draw.rectangle((20, 22, 40, 40), outline=255, fill=1) # center filled + + if button_A.value: # button is released + draw.ellipse((70, 40, 90, 60), outline=255, fill=0) # A button + else: # button is pressed: + draw.ellipse((70, 40, 90, 60), outline=255, fill=1) # A button filled + + if button_B.value: # button is released + draw.ellipse((100, 20, 120, 40), outline=255, fill=0) # B button + else: # button is pressed: + draw.ellipse((100, 20, 120, 40), outline=255, fill=1) # B button filled if not button_A.value and not button_B.value and not button_C.value: - catImage = Image.open('happycat_oled_64.ppm').convert('1') + catImage = Image.open("happycat_oled_64.ppm").convert("1") disp.image(catImage) else: # Display image. diff --git a/examples/ssd1306_bouncing_ball.py b/examples/ssd1306_bouncing_ball.py index cd97ed8..786335e 100644 --- a/examples/ssd1306_bouncing_ball.py +++ b/examples/ssd1306_bouncing_ball.py @@ -38,6 +38,7 @@ def draw_circle(xpos0, ypos0, rad, col=1): dx += 2 err += dx - (rad << 1) + # initial center of the circle center_x = 63 center_y = 15 diff --git a/examples/ssd1306_framebuftest.py b/examples/ssd1306_framebuftest.py index 623a9cb..e1a74e4 100644 --- a/examples/ssd1306_framebuftest.py +++ b/examples/ssd1306_framebuftest.py @@ -23,10 +23,12 @@ # to the right size for your display! # The I2C address for these displays is 0x3d or 0x3c, change to match # A reset line may be required if there is no auto-reset circuitry -display = adafruit_ssd1306.SSD1306_I2C(128, 32, i2c, addr=0x3c, reset=reset_pin) +display = adafruit_ssd1306.SSD1306_I2C(128, 32, i2c, addr=0x3C, reset=reset_pin) -print("Framebuf capability test - these are slow and minimal but don't require" - "a special graphics management library, only `adafruit_framebuf`") +print( + "Framebuf capability test - these are slow and minimal but don't require" + "a special graphics management library, only `adafruit_framebuf`" +) print("Pixel test") # Clear the display. Always call show after changing pixels to make the display @@ -37,22 +39,25 @@ # Set a pixel in the origin 0,0 position. display.pixel(0, 0, 1) # Set a pixel in the middle position. -display.pixel(display.width//2, display.height//2, 1) +display.pixel(display.width // 2, display.height // 2, 1) # Set a pixel in the opposite corner position. -display.pixel(display.width-1, display.height-1, 1) +display.pixel(display.width - 1, display.height - 1, 1) display.show() time.sleep(0.1) print("Lines test") # we'll draw from corner to corner, lets define all the pair coordinates here -corners = ((0, 0), (0, display.height-1), (display.width-1, 0), - (display.width-1, display.height-1)) +corners = ( + (0, 0), + (0, display.height - 1), + (display.width - 1, 0), + (display.width - 1, display.height - 1), +) display.fill(0) for corner_from in corners: for corner_to in corners: - display.line(corner_from[0], corner_from[1], - corner_to[0], corner_to[1], 1) + display.line(corner_from[0], corner_from[1], corner_to[0], corner_to[1], 1) display.show() time.sleep(0.1) @@ -61,26 +66,28 @@ w_delta = display.width / 10 h_delta = display.height / 10 for i in range(11): - display.rect(0, 0, int(w_delta*i), int(h_delta*i), 1) + display.rect(0, 0, int(w_delta * i), int(h_delta * i), 1) display.show() time.sleep(0.1) print("Text test") display.fill(0) try: - display.text('hello world', 0, 0, 1) + display.text("hello world", 0, 0, 1) display.show() time.sleep(1) display.fill(0) char_width = 6 char_height = 8 - chars_per_line = display.width//6 + chars_per_line = display.width // 6 for i in range(255): x = char_width * (i % chars_per_line) y = char_height * (i // chars_per_line) display.text(chr(i), x, y, 1) display.show() except FileNotFoundError: - print("To test the framebuf font setup, you'll need the font5x8.bin file from " + - "https://github.com/adafruit/Adafruit_CircuitPython_framebuf/tree/master/examples" + - " in the same directory as this script") + print( + "To test the framebuf font setup, you'll need the font5x8.bin file from " + + "https://github.com/adafruit/Adafruit_CircuitPython_framebuf/tree/master/examples" + + " in the same directory as this script" + ) diff --git a/examples/ssd1306_pillow_animate.py b/examples/ssd1306_pillow_animate.py index 70aa923..accf40b 100644 --- a/examples/ssd1306_pillow_animate.py +++ b/examples/ssd1306_pillow_animate.py @@ -39,7 +39,7 @@ disp = adafruit_ssd1306.SSD1306_I2C(128, 32, i2c) # Note you can change the I2C address, or add a reset pin: -#disp = adafruit_ssd1306.SSD1306_I2C(128, 32, i2c, addr=0x3c, reset=reset_pin) +# disp = adafruit_ssd1306.SSD1306_I2C(128, 32, i2c, addr=0x3c, reset=reset_pin) # Get display width and height. width = disp.width @@ -51,7 +51,7 @@ # Create image buffer. # Make sure to create image with mode '1' for 1-bit color. -image = Image.new('1', (width, height)) +image = Image.new("1", (width, height)) # Load default font. font = ImageFont.load_default() @@ -65,18 +65,20 @@ draw = ImageDraw.Draw(image) # Define text and get total width. -text = 'SSD1306 ORGANIC LED DISPLAY. THIS IS AN OLD SCHOOL DEMO SCROLLER!!'+\ - 'GREETZ TO: LADYADA & THE ADAFRUIT CREW, TRIXTER, FUTURE CREW, AND FARBRAUSCH' +text = ( + "SSD1306 ORGANIC LED DISPLAY. THIS IS AN OLD SCHOOL DEMO SCROLLER!!" + + "GREETZ TO: LADYADA & THE ADAFRUIT CREW, TRIXTER, FUTURE CREW, AND FARBRAUSCH" +) maxwidth, unused = draw.textsize(text, font=font) # Set animation and sine wave parameters. -amplitude = height/4 -offset = height/2 - 4 +amplitude = height / 4 +offset = height / 2 - 4 velocity = -2 startpos = width # Animate text moving in sine wave. -print('Press Ctrl-C to quit.') +print("Press Ctrl-C to quit.") pos = startpos while True: # Clear image buffer by drawing a black filled box. @@ -93,7 +95,7 @@ x += char_width continue # Calculate offset from sine wave. - y = offset+math.floor(amplitude*math.sin(x/float(width)*2.0*math.pi)) + y = offset + math.floor(amplitude * math.sin(x / float(width) * 2.0 * math.pi)) # Draw text. draw.text((x, y), c, font=font, fill=255) # Increment x position based on chacacter width. diff --git a/examples/ssd1306_pillow_clock.py b/examples/ssd1306_pillow_clock.py index af0def2..069b07a 100644 --- a/examples/ssd1306_pillow_clock.py +++ b/examples/ssd1306_pillow_clock.py @@ -16,21 +16,21 @@ RESET_PIN = digitalio.DigitalInOut(board.D4) i2c = board.I2C() -oled = adafruit_ssd1306.SSD1306_I2C(128, 64, i2c, addr=0x3d, reset=RESET_PIN) +oled = adafruit_ssd1306.SSD1306_I2C(128, 64, i2c, addr=0x3D, reset=RESET_PIN) # Clear display. oled.fill(0) oled.show() # Create blank image for drawing. -image = Image.new('1', (oled.width, oled.height)) +image = Image.new("1", (oled.width, oled.height)) draw = ImageDraw.Draw(image) # Load a font in 2 different sizes. -font = ImageFont.truetype('/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf', 16) -font2 = ImageFont.truetype('/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf', 24) +font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 16) +font2 = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 24) -offset = 0 # flips between 0 and 32 for double buffering +offset = 0 # flips between 0 and 32 for double buffering while True: # write the current time to the display after each scroll @@ -46,7 +46,7 @@ time.sleep(1) - for i in range(0, oled.height//2): + for i in range(0, oled.height // 2): offset = (offset + 1) % oled.height oled.write_cmd(adafruit_ssd1306.SET_DISP_START_LINE | offset) oled.show() diff --git a/examples/ssd1306_pillow_demo.py b/examples/ssd1306_pillow_demo.py index 302fc59..0dcca5a 100644 --- a/examples/ssd1306_pillow_demo.py +++ b/examples/ssd1306_pillow_demo.py @@ -18,18 +18,18 @@ # Change these # to the right size for your display! WIDTH = 128 -HEIGHT = 32 # Change to 64 if needed +HEIGHT = 32 # Change to 64 if needed BORDER = 5 # Use for I2C. i2c = board.I2C() -oled = adafruit_ssd1306.SSD1306_I2C(WIDTH, HEIGHT, i2c, addr=0x3c, reset=oled_reset) +oled = adafruit_ssd1306.SSD1306_I2C(WIDTH, HEIGHT, i2c, addr=0x3C, reset=oled_reset) # Use for SPI -#spi = board.SPI() -#oled_cs = digitalio.DigitalInOut(board.D5) -#oled_dc = digitalio.DigitalInOut(board.D6) -#oled = adafruit_ssd1306.SSD1306_SPI(WIDTH, HEIGHT, spi, oled_dc, oled_reset, oled_cs) +# spi = board.SPI() +# oled_cs = digitalio.DigitalInOut(board.D5) +# oled_dc = digitalio.DigitalInOut(board.D6) +# oled = adafruit_ssd1306.SSD1306_SPI(WIDTH, HEIGHT, spi, oled_dc, oled_reset, oled_cs) # Clear display. oled.fill(0) @@ -37,7 +37,7 @@ # Create blank image for drawing. # Make sure to create image with mode '1' for 1-bit color. -image = Image.new('1', (oled.width, oled.height)) +image = Image.new("1", (oled.width, oled.height)) # Get drawing object to draw on image. draw = ImageDraw.Draw(image) @@ -46,8 +46,11 @@ draw.rectangle((0, 0, oled.width, oled.height), outline=255, fill=255) # Draw a smaller inner rectangle -draw.rectangle((BORDER, BORDER, oled.width - BORDER - 1, oled.height - BORDER - 1), - outline=0, fill=0) +draw.rectangle( + (BORDER, BORDER, oled.width - BORDER - 1, oled.height - BORDER - 1), + outline=0, + fill=0, +) # Load default font. font = ImageFont.load_default() @@ -55,8 +58,12 @@ # Draw Some Text text = "Hello World!" (font_width, font_height) = font.getsize(text) -draw.text((oled.width//2 - font_width//2, oled.height//2 - font_height//2), - text, font=font, fill=255) +draw.text( + (oled.width // 2 - font_width // 2, oled.height // 2 - font_height // 2), + text, + font=font, + fill=255, +) # Display image oled.image(image) diff --git a/examples/ssd1306_pillow_image_display.py b/examples/ssd1306_pillow_image_display.py index a613f95..83da4d7 100644 --- a/examples/ssd1306_pillow_image_display.py +++ b/examples/ssd1306_pillow_image_display.py @@ -16,14 +16,18 @@ RESET_PIN = digitalio.DigitalInOut(board.D4) i2c = board.I2C() -oled = adafruit_ssd1306.SSD1306_I2C(128, 64, i2c, addr=0x3d, reset=RESET_PIN) +oled = adafruit_ssd1306.SSD1306_I2C(128, 64, i2c, addr=0x3D, reset=RESET_PIN) # Clear display. oled.fill(0) oled.show() # Open, resize, and convert image to Black and White -image = Image.open(sys.argv[1]).resize((oled.width, oled.height), Image.BICUBIC).convert('1') +image = ( + Image.open(sys.argv[1]) + .resize((oled.width, oled.height), Image.BICUBIC) + .convert("1") +) # Display the converted image oled.image(image) diff --git a/examples/ssd1306_pillow_images.py b/examples/ssd1306_pillow_images.py index 4251593..1deff65 100644 --- a/examples/ssd1306_pillow_images.py +++ b/examples/ssd1306_pillow_images.py @@ -37,7 +37,7 @@ disp = adafruit_ssd1306.SSD1306_I2C(128, 64, i2c) # Note you can change the I2C address, or add a reset pin: -#disp = adafruit_ssd1306.SSD1306_I2C(128, 32, i2c, addr=0x3c, reset=reset_pin) +# disp = adafruit_ssd1306.SSD1306_I2C(128, 32, i2c, addr=0x3c, reset=reset_pin) # Clear display. disp.fill(0) @@ -46,12 +46,12 @@ # Load image based on OLED display height. Note that image is converted to 1 bit color. if disp.height == 64: - image = Image.open('happycat_oled_64.ppm').convert('1') + image = Image.open("happycat_oled_64.ppm").convert("1") else: - image = Image.open('happycat_oled_32.ppm').convert('1') + image = Image.open("happycat_oled_32.ppm").convert("1") # Alternatively load a different format image, resize it, and convert to 1 bit color. -#image = Image.open('happycat.png').resize((disp.width, disp.height), Image.ANTIALIAS).convert('1') +# image = Image.open('happycat.png').resize((disp.width, disp.height), Image.ANTIALIAS).convert('1') # Display image. disp.image(image) diff --git a/examples/ssd1306_pillow_ip.py b/examples/ssd1306_pillow_ip.py index be6ce85..61f7d01 100644 --- a/examples/ssd1306_pillow_ip.py +++ b/examples/ssd1306_pillow_ip.py @@ -17,44 +17,47 @@ # This function allows us to grab any of our IP addresses def get_ip_address(ifname): s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - return socket.inet_ntoa(fcntl.ioctl( - s.fileno(), - 0x8915, # SIOCGIFADDR - struct.pack('256s', str.encode(ifname[:15])) - )[20:24]) + return socket.inet_ntoa( + fcntl.ioctl( + s.fileno(), + 0x8915, # SIOCGIFADDR + struct.pack("256s", str.encode(ifname[:15])), + )[20:24] + ) + # Setting some variables for our reset pin etc. RESET_PIN = digitalio.DigitalInOut(board.D4) -TEXT = '' +TEXT = "" # Very important... This lets py-gaugette 'know' what pins to use in order to reset the display i2c = board.I2C() -oled = adafruit_ssd1306.SSD1306_I2C(128, 64, i2c, addr=0x3d, reset=RESET_PIN) +oled = adafruit_ssd1306.SSD1306_I2C(128, 64, i2c, addr=0x3D, reset=RESET_PIN) # This sets TEXT equal to whatever your IP address is, or isn't try: - TEXT = get_ip_address('wlan0') # WiFi address of WiFi adapter. NOT ETHERNET + TEXT = get_ip_address("wlan0") # WiFi address of WiFi adapter. NOT ETHERNET except IOError: try: - TEXT = get_ip_address('eth0') # WiFi address of Ethernet cable. NOT ADAPTER + TEXT = get_ip_address("eth0") # WiFi address of Ethernet cable. NOT ADAPTER except IOError: - TEXT = ('NO INTERNET!') + TEXT = "NO INTERNET!" # Clear display. oled.fill(0) oled.show() # Create blank image for drawing. -image = Image.new('1', (oled.width, oled.height)) +image = Image.new("1", (oled.width, oled.height)) draw = ImageDraw.Draw(image) # Load a font in 2 different sizes. -font = ImageFont.truetype('/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf', 28) -font2 = ImageFont.truetype('/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf', 14) +font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 28) +font2 = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 14) # Draw the text -intro = 'Hello!' -ip = 'Your IP Address is:' +intro = "Hello!" +ip = "Your IP Address is:" draw.text((0, 46), TEXT, font=font2, fill=255) draw.text((0, 0), intro, font=font, fill=255) draw.text((0, 30), ip, font=font2, fill=255) diff --git a/examples/ssd1306_pillow_shapes.py b/examples/ssd1306_pillow_shapes.py index 7ab2f17..21986c7 100644 --- a/examples/ssd1306_pillow_shapes.py +++ b/examples/ssd1306_pillow_shapes.py @@ -37,7 +37,7 @@ disp = adafruit_ssd1306.SSD1306_I2C(128, 32, i2c) # Note you can change the I2C address, or add a reset pin: -#disp = adafruit_ssd1306.SSD1306_I2C(128, 32, i2c, addr=0x3c, reset=reset_pin) +# disp = adafruit_ssd1306.SSD1306_I2C(128, 32, i2c, addr=0x3c, reset=reset_pin) # Clear display. disp.fill(0) @@ -47,7 +47,7 @@ # Make sure to create image with mode '1' for 1-bit color. width = disp.width height = disp.height -image = Image.new('1', (width, height)) +image = Image.new("1", (width, height)) # Get drawing object to draw on image. draw = ImageDraw.Draw(image) @@ -60,22 +60,26 @@ padding = 2 shape_width = 20 top = padding -bottom = height-padding +bottom = height - padding # Move left to right keeping track of the current x position for drawing shapes. x = padding # Draw an ellipse. -draw.ellipse((x, top, x+shape_width, bottom), outline=255, fill=0) -x += shape_width+padding +draw.ellipse((x, top, x + shape_width, bottom), outline=255, fill=0) +x += shape_width + padding # Draw a rectangle. -draw.rectangle((x, top, x+shape_width, bottom), outline=255, fill=0) -x += shape_width+padding +draw.rectangle((x, top, x + shape_width, bottom), outline=255, fill=0) +x += shape_width + padding # Draw a triangle. -draw.polygon([(x, bottom), (x+shape_width/2, top), (x+shape_width, bottom)], outline=255, fill=0) -x += shape_width+padding +draw.polygon( + [(x, bottom), (x + shape_width / 2, top), (x + shape_width, bottom)], + outline=255, + fill=0, +) +x += shape_width + padding # Draw an X. -draw.line((x, bottom, x+shape_width, top), fill=255) -draw.line((x, top, x+shape_width, bottom), fill=255) -x += shape_width+padding +draw.line((x, bottom, x + shape_width, top), fill=255) +draw.line((x, top, x + shape_width, bottom), fill=255) +x += shape_width + padding # Load default font. font = ImageFont.load_default() @@ -83,11 +87,11 @@ # Alternatively load a TTF font. Make sure the .ttf font file is in the # same directory as the python script! # Some other nice fonts to try: http://www.dafont.com/bitmap.php -#font = ImageFont.truetype('Minecraftia.ttf', 8) +# font = ImageFont.truetype('Minecraftia.ttf', 8) # Write two lines of text. -draw.text((x, top), 'Hello', font=font, fill=255) -draw.text((x, top+20), 'World!', font=font, fill=255) +draw.text((x, top), "Hello", font=font, fill=255) +draw.text((x, top + 20), "World!", font=font, fill=255) # Display image. disp.image(image) diff --git a/examples/ssd1306_pillow_text.py b/examples/ssd1306_pillow_text.py index 7e455a4..3730fb5 100644 --- a/examples/ssd1306_pillow_text.py +++ b/examples/ssd1306_pillow_text.py @@ -16,24 +16,24 @@ # Very important... This lets py-gaugette 'know' what pins to use in order to reset the display i2c = board.I2C() -oled = adafruit_ssd1306.SSD1306_I2C(128, 64, i2c, addr=0x3d, reset=RESET_PIN) +oled = adafruit_ssd1306.SSD1306_I2C(128, 64, i2c, addr=0x3D, reset=RESET_PIN) # Clear display. oled.fill(0) oled.show() # Create blank image for drawing. -image = Image.new('1', (oled.width, oled.height)) +image = Image.new("1", (oled.width, oled.height)) draw = ImageDraw.Draw(image) # Load a font in 2 different sizes. -font = ImageFont.truetype('/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf', 28) -font2 = ImageFont.truetype('/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf', 14) +font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 28) +font2 = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 14) # Draw the text -draw.text((0, 0), 'Hello!', font=font, fill=255) -draw.text((0, 30), 'Hello!', font=font2, fill=255) -draw.text((34, 46), 'Hello!', font=font2, fill=255) +draw.text((0, 0), "Hello!", font=font, fill=255) +draw.text((0, 30), "Hello!", font=font2, fill=255) +draw.text((34, 46), "Hello!", font=font2, fill=255) # Display image oled.image(image) diff --git a/examples/ssd1306_simpletest.py b/examples/ssd1306_simpletest.py index 832ef4b..84cd220 100644 --- a/examples/ssd1306_simpletest.py +++ b/examples/ssd1306_simpletest.py @@ -19,7 +19,7 @@ # to the right size for your display! display = adafruit_ssd1306.SSD1306_I2C(128, 32, i2c) # Alternatively you can change the I2C address of the device with an addr parameter: -#display = adafruit_ssd1306.SSD1306_I2C(128, 32, i2c, addr=0x31) +# display = adafruit_ssd1306.SSD1306_I2C(128, 32, i2c, addr=0x31) # Clear the display. Always call show after changing pixels to make the display # update visible! diff --git a/examples/ssd1306_stats.py b/examples/ssd1306_stats.py index 703747e..ab51f77 100644 --- a/examples/ssd1306_stats.py +++ b/examples/ssd1306_stats.py @@ -49,7 +49,7 @@ # Make sure to create image with mode '1' for 1-bit color. width = disp.width height = disp.height -image = Image.new('1', (width, height)) +image = Image.new("1", (width, height)) # Get drawing object to draw on image. draw = ImageDraw.Draw(image) @@ -61,7 +61,7 @@ # First define some constants to allow easy resizing of shapes. padding = -2 top = padding -bottom = height-padding +bottom = height - padding # Move left to right keeping track of the current x position for drawing shapes. x = 0 @@ -72,7 +72,7 @@ # Alternatively load a TTF font. Make sure the .ttf font file is in the # same directory as the python script! # Some other nice fonts to try: http://www.dafont.com/bitmap.php -#font = ImageFont.truetype('/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf', 9) +# font = ImageFont.truetype('/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf', 9) while True: @@ -81,23 +81,23 @@ # Shell scripts for system monitoring from here: # https://unix.stackexchange.com/questions/119126/command-to-display-memory-usage-disk-usage-and-cpu-load - cmd = "hostname -I | cut -d\' \' -f1" + cmd = "hostname -I | cut -d' ' -f1" IP = subprocess.check_output(cmd, shell=True).decode("utf-8") cmd = "top -bn1 | grep load | awk '{printf \"CPU Load: %.2f\", $(NF-2)}'" CPU = subprocess.check_output(cmd, shell=True).decode("utf-8") cmd = "free -m | awk 'NR==2{printf \"Mem: %s/%s MB %.2f%%\", $3,$2,$3*100/$2 }'" MemUsage = subprocess.check_output(cmd, shell=True).decode("utf-8") - cmd = "df -h | awk '$NF==\"/\"{printf \"Disk: %d/%d GB %s\", $3,$2,$5}'" + cmd = 'df -h | awk \'$NF=="/"{printf "Disk: %d/%d GB %s", $3,$2,$5}\'' Disk = subprocess.check_output(cmd, shell=True).decode("utf-8") # Write four lines of text. - draw.text((x, top+0), "IP: "+IP, font=font, fill=255) - draw.text((x, top+8), CPU, font=font, fill=255) - draw.text((x, top+16), MemUsage, font=font, fill=255) - draw.text((x, top+25), Disk, font=font, fill=255) + draw.text((x, top + 0), "IP: " + IP, font=font, fill=255) + draw.text((x, top + 8), CPU, font=font, fill=255) + draw.text((x, top + 16), MemUsage, font=font, fill=255) + draw.text((x, top + 25), Disk, font=font, fill=255) # Display image. disp.image(image) disp.show() - time.sleep(.1) + time.sleep(0.1) diff --git a/setup.py b/setup.py index 33f4290..4c5438f 100644 --- a/setup.py +++ b/setup.py @@ -7,6 +7,7 @@ # Always prefer setuptools over distutils from setuptools import setup, find_packages + # To use a consistent encoding from codecs import open from os import path @@ -14,47 +15,42 @@ here = path.abspath(path.dirname(__file__)) # Get the long description from the README file -with open(path.join(here, 'README.rst'), encoding='utf-8') as f: +with open(path.join(here, "README.rst"), encoding="utf-8") as f: long_description = f.read() setup( - name='adafruit-circuitpython-ssd1306', - + name="adafruit-circuitpython-ssd1306", use_scm_version=True, - setup_requires=['setuptools_scm'], - - description='CircuitPython library for SSD1306 OLED displays.', + setup_requires=["setuptools_scm"], + description="CircuitPython library for SSD1306 OLED displays.", long_description=long_description, - long_description_content_type='text/x-rst', - + long_description_content_type="text/x-rst", # The project's main homepage. - url='https://github.com/adafruit/Adafruit_CircuitPython_SSD1306', - + url="https://github.com/adafruit/Adafruit_CircuitPython_SSD1306", # Author details - author='Adafruit Industries', - author_email='circuitpython@adafruit.com', - - install_requires=['Adafruit-Blinka', 'adafruit-circuitpython-busdevice', 'adafruit-circuitpython-framebuf'], - + author="Adafruit Industries", + author_email="circuitpython@adafruit.com", + install_requires=[ + "Adafruit-Blinka", + "adafruit-circuitpython-busdevice", + "adafruit-circuitpython-framebuf", + ], # Choose your license - license='MIT', - + license="MIT", # See https://pypi.python.org/pypi?%3Aaction=list_classifiers classifiers=[ - 'Development Status :: 3 - Alpha', - 'Intended Audience :: Developers', - 'Topic :: Software Development :: Libraries', - 'Topic :: System :: Hardware', - 'License :: OSI Approved :: MIT License', - 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.4', - 'Programming Language :: Python :: 3.5', + "Development Status :: 3 - Alpha", + "Intended Audience :: Developers", + "Topic :: Software Development :: Libraries", + "Topic :: System :: Hardware", + "License :: OSI Approved :: MIT License", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.4", + "Programming Language :: Python :: 3.5", ], - # What does your project relate to? - keywords='adafruit ssd1306 oled displays hardware micropython circuitpython', - + keywords="adafruit ssd1306 oled displays hardware micropython circuitpython", # You can just specify the packages manually here if your project is # simple. Or you can use find_packages(). - py_modules=['adafruit_ssd1306'], + py_modules=["adafruit_ssd1306"], )