diff --git a/README.rst b/README.rst index 503f550..166a374 100644 --- a/README.rst +++ b/README.rst @@ -26,6 +26,7 @@ This driver depends on: * `Adafruit CircuitPython `_ * `Bus Device `_ +* `Adafruit framebuf `_ Please ensure all dependencies are available on the CircuitPython filesystem. This is easily achieved by downloading diff --git a/adafruit_ssd1306.py b/adafruit_ssd1306.py index ed55026..949fef1 100644 --- a/adafruit_ssd1306.py +++ b/adafruit_ssd1306.py @@ -62,22 +62,11 @@ #pylint: enable-msg=bad-whitespace -class _SSD1306: +class _SSD1306(framebuf.FrameBuffer): """Base class for SSD1306 display driver""" #pylint: disable-msg=too-many-arguments - #pylint: disable-msg=too-many-instance-attributes - def __init__(self, framebuffer, width, height, *, external_vcc, reset): - self.framebuf = framebuffer - self.fill = self.framebuf.fill - self.pixel = self.framebuf.pixel - self.line = self.framebuf.line - self.text = self.framebuf.text - self.scroll = self.framebuf.scroll - self.blit = self.framebuf.blit - self.vline = self.framebuf.vline - self.hline = self.framebuf.hline - self.fill_rect = self.framebuf.fill_rect - self.rect = self.framebuf.rect + def __init__(self, buffer, width, height, *, external_vcc, reset): + super().__init__(buffer, width, height) self.width = width self.height = height self.external_vcc = external_vcc @@ -191,8 +180,7 @@ 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 - framebuffer = framebuf.FrameBuffer1(memoryview(self.buffer)[1:], width, height) - super().__init__(framebuffer, width, height, + super().__init__(memoryview(self.buffer)[1:], width, height, external_vcc=external_vcc, reset=reset) def write_cmd(self, cmd): @@ -230,8 +218,7 @@ def __init__(self, width, height, spi, dc, reset, cs, *, polarity=polarity, phase=phase) self.dc_pin = dc self.buffer = bytearray((height // 8) * width) - framebuffer = framebuf.FrameBuffer1(self.buffer, width, height) - super().__init__(framebuffer, width, height, + super().__init__(memoryview(self.buffer), width, height, external_vcc=external_vcc, reset=reset) def write_cmd(self, cmd): diff --git a/examples/bonnet_buttons.py b/examples/bonnet_buttons.py new file mode 100644 index 0000000..f5a07c7 --- /dev/null +++ b/examples/bonnet_buttons.py @@ -0,0 +1,125 @@ +# Copyright (c) 2017 Adafruit Industries +# Author: James DeVito +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +import board +import busio +from digitalio import DigitalInOut, Direction, Pull +from PIL import Image, ImageDraw +import adafruit_ssd1306 + +# Create the I2C interface. +i2c = busio.I2C(board.SCL, board.SDA) +# Create the SSD1306 OLED class. +disp = adafruit_ssd1306.SSD1306_I2C(128, 64, i2c) + + + +# Input pins: +button_A = DigitalInOut(board.D5) +button_A.direction = Direction.INPUT +button_A.pull = Pull.UP + +button_B = DigitalInOut(board.D6) +button_B.direction = Direction.INPUT +button_B.pull = Pull.UP + +button_L = DigitalInOut(board.D27) +button_L.direction = Direction.INPUT +button_L.pull = Pull.UP + +button_R = DigitalInOut(board.D23) +button_R.direction = Direction.INPUT +button_R.pull = Pull.UP + +button_U = DigitalInOut(board.D17) +button_U.direction = Direction.INPUT +button_U.pull = Pull.UP + +button_D = DigitalInOut(board.D22) +button_D.direction = Direction.INPUT +button_D.pull = Pull.UP + +button_C = DigitalInOut(board.D4) +button_C.direction = Direction.INPUT +button_C.pull = Pull.UP + + +# Clear display. +disp.fill(0) +disp.show() + +# Create blank image for drawing. +# Make sure to create image with mode '1' for 1-bit color. +width = disp.width +height = disp.height +image = Image.new('1', (width, height)) + +# Get drawing object to draw on image. +draw = ImageDraw.Draw(image) + +# Draw a black filled box to clear the image. +draw.rectangle((0, 0, width, height), outline=0, fill=0) + + +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 not button_A.value and not button_B.value and not button_C.value: + catImage = Image.open('happycat_oled_64.ppm').convert('1') + disp.image(catImage) + else: + # Display image. + disp.image(image) + + disp.show() diff --git a/examples/happycat_oled_32.ppm b/examples/happycat_oled_32.ppm new file mode 100644 index 0000000..e69de29 diff --git a/examples/happycat_oled_64.ppm b/examples/happycat_oled_64.ppm new file mode 100644 index 0000000..922daac Binary files /dev/null and b/examples/happycat_oled_64.ppm differ diff --git a/examples/pillow_animate.py b/examples/pillow_animate.py new file mode 100644 index 0000000..fd2f039 --- /dev/null +++ b/examples/pillow_animate.py @@ -0,0 +1,110 @@ +# Copyright (c) 2014 Adafruit Industries +# Author: Tony DiCola +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +import math +import time +from board import SCL, SDA +import busio +from PIL import Image, ImageDraw, ImageFont +import adafruit_ssd1306 + +# Create the I2C interface. +i2c = busio.I2C(SCL, SDA) + +# Create the SSD1306 OLED class. +# The first two parameters are the pixel width and pixel height. +# Change these to the right size for your display! +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) + +# Get display width and height. +width = disp.width +height = disp.height + +# Clear display. +disp.fill(0) +disp.show() + +# Create image buffer. +# Make sure to create image with mode '1' for 1-bit color. +image = Image.new('1', (width, height)) + +# Load default font. +font = ImageFont.load_default() + +# Alternatively load a TTF font. Make sure the .ttf font file is in the +# same directory as this python script! +# Some nice fonts to try: http://www.dafont.com/bitmap.php +# font = ImageFont.truetype('Minecraftia.ttf', 8) + +# Create drawing object. +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' +maxwidth, unused = draw.textsize(text, font=font) + +# Set animation and sine wave parameters. +amplitude = height/4 +offset = height/2 - 4 +velocity = -2 +startpos = width + +# Animate text moving in sine wave. +print('Press Ctrl-C to quit.') +pos = startpos +while True: + # Clear image buffer by drawing a black filled box. + draw.rectangle((0, 0, width, height), outline=0, fill=0) + # Enumerate characters and draw them offset vertically based on a sine wave. + x = pos + for i, c in enumerate(text): + # Stop drawing if off the right side of screen. + if x > width: + break + # Calculate width but skip drawing if off the left side of screen. + if x < -10: + char_width, char_height = draw.textsize(c, font=font) + x += char_width + continue + # Calculate offset from sine wave. + 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. + char_width, char_height = draw.textsize(c, font=font) + x += char_width + + # Draw the image buffer. + disp.image(image) + disp.show() + + # Move position for next frame. + pos += velocity + # Start over if text has scrolled completely off left side of screen. + if pos < -maxwidth: + pos = startpos + + # Pause briefly before drawing next frame. + time.sleep(0.05) diff --git a/examples/pillow_images.py b/examples/pillow_images.py new file mode 100644 index 0000000..f72cb80 --- /dev/null +++ b/examples/pillow_images.py @@ -0,0 +1,54 @@ +# Copyright (c) 2014 Adafruit Industries +# Author: Tony DiCola +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +from board import SCL, SDA +import busio +from PIL import Image +import adafruit_ssd1306 + +# Create the I2C interface. +i2c = busio.I2C(SCL, SDA) + +# Create the SSD1306 OLED class. +# The first two parameters are the pixel width and pixel height. Change these +# to the right size for your display! +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) + +# Clear display. +disp.fill(0) +disp.show() + + +# 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') +else: + 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') + +# Display image. +disp.image(image) +disp.show() diff --git a/examples/pillow_shapes.py b/examples/pillow_shapes.py new file mode 100644 index 0000000..b3e5713 --- /dev/null +++ b/examples/pillow_shapes.py @@ -0,0 +1,90 @@ +# Copyright (c) 2014 Adafruit Industries +# Author: Tony DiCola +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +from board import SCL, SDA +import busio +from PIL import Image, ImageDraw, ImageFont +import adafruit_ssd1306 + +# Create the I2C interface. +i2c = busio.I2C(SCL, SDA) + +# Create the SSD1306 OLED class. +# The first two parameters are the pixel width and pixel height. Change these +# to the right size for your display! +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) + +# Clear display. +disp.fill(0) +disp.show() + +# Create blank image for drawing. +# Make sure to create image with mode '1' for 1-bit color. +width = disp.width +height = disp.height +image = Image.new('1', (width, height)) + +# Get drawing object to draw on image. +draw = ImageDraw.Draw(image) + +# Draw a black filled box to clear the image. +draw.rectangle((0, 0, width, height), outline=0, fill=0) + +# Draw some shapes. +# First define some constants to allow easy resizing of shapes. +padding = 2 +shape_width = 20 +top = 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 a rectangle. +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 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 + +# Load default font. +font = ImageFont.load_default() + +# 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) + +# Write two lines of text. +draw.text((x, top), 'Hello', font=font, fill=255) +draw.text((x, top+20), 'World!', font=font, fill=255) + +# Display image. +disp.image(image) +disp.show() diff --git a/examples/ssd1306_framebuftest.py b/examples/ssd1306_framebuftest.py index a78f8c5..623a9cb 100644 --- a/examples/ssd1306_framebuftest.py +++ b/examples/ssd1306_framebuftest.py @@ -23,7 +23,7 @@ # 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=0x3d, 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`") @@ -67,12 +67,20 @@ print("Text test") display.fill(0) -display.text('hello world', 0, 0, 1) -char_width = 6 -char_height = 8 -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() +try: + 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 + 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") diff --git a/examples/stats.py b/examples/stats.py new file mode 100644 index 0000000..703747e --- /dev/null +++ b/examples/stats.py @@ -0,0 +1,103 @@ +# Copyright (c) 2017 Adafruit Industries +# Author: Tony DiCola & James DeVito +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + + +# This example is for use on (Linux) computers that are using CPython with +# Adafruit Blinka to support CircuitPython libraries. CircuitPython does +# not support PIL/pillow (python imaging library)! + +import time +import subprocess + +from board import SCL, SDA +import busio +from PIL import Image, ImageDraw, ImageFont +import adafruit_ssd1306 + + +# Create the I2C interface. +i2c = busio.I2C(SCL, SDA) + +# Create the SSD1306 OLED class. +# The first two parameters are the pixel width and pixel height. Change these +# to the right size for your display! +disp = adafruit_ssd1306.SSD1306_I2C(128, 32, i2c) + +# Clear display. +disp.fill(0) +disp.show() + +# Create blank image for drawing. +# Make sure to create image with mode '1' for 1-bit color. +width = disp.width +height = disp.height +image = Image.new('1', (width, height)) + +# Get drawing object to draw on image. +draw = ImageDraw.Draw(image) + +# Draw a black filled box to clear the image. +draw.rectangle((0, 0, width, height), outline=0, fill=0) + +# Draw some shapes. +# First define some constants to allow easy resizing of shapes. +padding = -2 +top = padding +bottom = height-padding +# Move left to right keeping track of the current x position for drawing shapes. +x = 0 + + +# Load default font. +font = ImageFont.load_default() + +# 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) + +while True: + + # Draw a black filled box to clear the image. + draw.rectangle((0, 0, width, height), outline=0, fill=0) + + # 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" + 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}'" + 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) + + # Display image. + disp.image(image) + disp.show() + time.sleep(.1) diff --git a/requirements.txt b/requirements.txt index 3031961..fb56461 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,3 @@ Adafruit-Blinka adafruit-circuitpython-busdevice +adafruit-circuitpython-framebuf diff --git a/setup.py b/setup.py index 5a5b7f6..33f4290 100644 --- a/setup.py +++ b/setup.py @@ -34,7 +34,7 @@ author='Adafruit Industries', author_email='circuitpython@adafruit.com', - install_requires=['Adafruit-Blinka', 'adafruit-circuitpython-busdevice'], + install_requires=['Adafruit-Blinka', 'adafruit-circuitpython-busdevice', 'adafruit-circuitpython-framebuf'], # Choose your license license='MIT',