From 855e31eccc55405a35c08ee52acc062754120519 Mon Sep 17 00:00:00 2001 From: ladyada Date: Thu, 27 Dec 2018 20:35:12 -0500 Subject: [PATCH 1/9] oops forgot a dependency! --- requirements.txt | 1 + setup.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) 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', From 4582f8338f21fda4eecdc7067da41ec481b6bb90 Mon Sep 17 00:00:00 2001 From: ladyada Date: Thu, 27 Dec 2018 20:36:56 -0500 Subject: [PATCH 2/9] use the default address --- examples/ssd1306_framebuftest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/ssd1306_framebuftest.py b/examples/ssd1306_framebuftest.py index a78f8c5..8f95921 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`") From 714a53509f0aaf757476bc6f8be6c9854d6e9f67 Mon Sep 17 00:00:00 2001 From: ladyada Date: Thu, 27 Dec 2018 20:45:14 -0500 Subject: [PATCH 3/9] better error catching if no font, display hello world properly --- examples/ssd1306_framebuftest.py | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/examples/ssd1306_framebuftest.py b/examples/ssd1306_framebuftest.py index 8f95921..623a9cb 100644 --- a/examples/ssd1306_framebuftest.py +++ b/examples/ssd1306_framebuftest.py @@ -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") From 95fe1cebfc6d76f93794cc48c71dd0d2046e4b6e Mon Sep 17 00:00:00 2001 From: ladyada Date: Thu, 27 Dec 2018 21:18:10 -0500 Subject: [PATCH 4/9] restructure to subclass framebuf properly - less messy than what we were doing --- adafruit_ssd1306.py | 23 +++++------------------ 1 file changed, 5 insertions(+), 18 deletions(-) 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): From b2a4c9e5d7242f7dd6f0c997d47e2a104977f5a5 Mon Sep 17 00:00:00 2001 From: ladyada Date: Thu, 27 Dec 2018 22:07:03 -0500 Subject: [PATCH 5/9] all the linux/raspi examples --- examples/bonnet_buttons.py | 114 ++++++++++++++++++++++++++++++++++ examples/happycat_oled_32.ppm | 0 examples/happycat_oled_64.ppm | Bin 0 -> 24629 bytes examples/pillow_animate.py | 109 ++++++++++++++++++++++++++++++++ examples/pillow_images.py | 60 ++++++++++++++++++ examples/pillow_shapes.py | 92 +++++++++++++++++++++++++++ examples/stats.py | 102 ++++++++++++++++++++++++++++++ 7 files changed, 477 insertions(+) create mode 100644 examples/bonnet_buttons.py create mode 100644 examples/happycat_oled_32.ppm create mode 100644 examples/happycat_oled_64.ppm create mode 100644 examples/pillow_animate.py create mode 100644 examples/pillow_images.py create mode 100644 examples/pillow_shapes.py create mode 100644 examples/stats.py diff --git a/examples/bonnet_buttons.py b/examples/bonnet_buttons.py new file mode 100644 index 0000000..ff6d0c9 --- /dev/null +++ b/examples/bonnet_buttons.py @@ -0,0 +1,114 @@ +# 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 time +import board +import busio +from digitalio import DigitalInOut, Direction, Pull +import adafruit_ssd1306 +from PIL import Image, ImageDraw, ImageFont + +# 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.pull = Pull.UP +button_B = DigitalInOut(board.D6) +button_B.pull = Pull.UP +button_L = DigitalInOut(board.D27) +button_L.pull = Pull.UP +button_R = DigitalInOut(board.D23) +button_R.pull = Pull.UP +button_U = DigitalInOut(board.D17) +button_U.pull = Pull.UP +button_D = DigitalInOut(board.D22) +button_D.pull = Pull.UP +button_C = DigitalInOut(board.D4) +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 0000000000000000000000000000000000000000..922daacaaea199bf329176816d68bba597b0e24a GIT binary patch literal 24629 zcmeH{&5j&J5QI7JQ>?@t$riQ{H-rFjFjyAi4ScYKKr*~Pgf~3jhBK>cdb@YLGwjx( z{AFb1PxV^!`sLM^*WbVS;k(~{ee>=0Pd~qUef|2ESJywj`{SRt@2`J<`~L5DfBkv= z?5k&2&z^sC{qpOp=PzDdeX;NS8%LcKm3v?Nr|KhLpnUKW9w~lG@B0G&+Swz&zw~ZM z^Aqp<0{XoE!oKNtBR~BR@jXrj`Pus)qARD`;}Q2=`pD=4_z{1nlRVuY)~$yh8BxHI zUwo2<9$8a=()|9NrC{Svfbz&b*h!wNkC~sH&|jXE^>U~AB+LD;o94$XU%S5>vjBFL z72mz^VHI{8uF7AWVE>}81{pwt542Ko}|*Y zflG$UKLy3iMPe6Wb)kN6S`X z9|{HK$Y2GhLd0Uetk5s=TaMmo;0vU<#QrApZ2xZdXDytmUU(_W2d94-P+$zFu=TVs8}3&mPGV~!V1e74#GngWgBE4Sm5KHhv*Y= z+c>J!OI)T{S-M@4RjE)VfSHma*&?Eswzj1iL#DQIwkq4IVPI(#;Xhl@Lwx)YF)un~J}OS-Lofr>0zH*|GD}H9;S#Fc9i(6A@e_RO z34~@8VEEo)6&(O-4JE`TC~SqBLfbOLb3vf}{e&Up8`G9%JQ%E?6AJQlzp@swl`!=z zN53r46MVGx0YCY{k(jCCAq7kf_UJChBP0Ta)89R*q;oy1gO5wZrS_1&wWU(b>%(kf zR_ze1lkJ64mORoqwh;oUcTPnm4s`?c*#K_h!lj1kNoVJ~E}+hCZb(+E3}Nd_Vb`Tt zEZZ*W%(b7}O=v|q3eG!0mYY*?D=9v7RybtDHE`&9+Z;vZg}Y*d^}Hz*Nath-1GZ&o z9^Q!QXV9G>JJ7atNYB!qrDSEuM1hYA0dv0(-jBaIgn~3@h%U%eJWg4hunhJ9+4D~9 zJ~=Cu)U$1RlGC$>RqG?O!1o-;9yJ#OBLsyrbbpjS4h8toZtG#38Z0$TkLRS4eAg{h zTaMR|I02VnNHgqgda^3BV!|bG+Z*HUSISvVZM(e~BM1#%DaE2}8|o?#9o{*ei2zxq z)5L(&2K)0yx0Aa=>Acj$4KM31Z{ekWg|mE+r7)kI9qjK_ZisWqkaG*ufhJNe@#Nd{ zEvf5W8Jba+UX1~N>Em#6yR*u>2azc@U*gRZcvN{fI^YlDLW@?=0ZMF6+e%)tmCl6n zU(oSq;p2Go@)okiY+EUzwt#FdH_NL&)#(ETIIqtviG2PJ2f=~mV{(f@4h_-!7 zS7grG&S}VO>M)Sb36nCEa)lRhw7mCE@aE`*RulsH#`KGQsHI9e45Vo8sq{FDB7i9r zoZ@)UeRaNB{Pu&;dAQ;oO*=1wP(T%qt9&ERX6{qyT#y!dciwDHex!5r-ku&kD4vkG4u+Nr_J7 zZPA`?7}g>t(5HYxE5On$Y%*XjqEk8dtT@*;=l-mkVwTw8tT=7M6rN$W_c_`y4RiLy zv%0k~hc9ELe4or_O6ClUjjTOn6JVQ}p5Su2;dJdhEdAZ;d~TK(_zWNAg=KIyZ;Poc znen6nG5hpE*gAA`w!)7n@{q!hb`Gx)}ff literal 0 HcmV?d00001 diff --git a/examples/pillow_animate.py b/examples/pillow_animate.py new file mode 100644 index 0000000..aec8ae1 --- /dev/null +++ b/examples/pillow_animate.py @@ -0,0 +1,109 @@ +# 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 +import adafruit_ssd1306 + +from PIL import Image, ImageDraw, ImageFont + +# 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..90ae4ae --- /dev/null +++ b/examples/pillow_images.py @@ -0,0 +1,60 @@ +# 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 time + +import time + +from board import SCL, SDA +import busio +import adafruit_ssd1306 + +from PIL import Image, ImageDraw, ImageFont + +import subprocess + +# 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..38f0c00 --- /dev/null +++ b/examples/pillow_shapes.py @@ -0,0 +1,92 @@ +# 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 time + +from board import SCL, SDA +import busio +import adafruit_ssd1306 + +from PIL import Image, ImageDraw, ImageFont + + +# 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/stats.py b/examples/stats.py new file mode 100644 index 0000000..c883837 --- /dev/null +++ b/examples/stats.py @@ -0,0 +1,102 @@ +# 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 + +from board import SCL, SDA +import busio +import adafruit_ssd1306 + +from PIL import Image, ImageDraw, ImageFont + +import subprocess + +# 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: " + str(IP), font=font, fill=255) + draw.text((x, top+8), str(CPU), font=font, fill=255) + draw.text((x, top+16), str(MemUsage), font=font, fill=255) + draw.text((x, top+25), str(Disk), font=font, fill=255) + + # Display image. + disp.image(image) + disp.show() + time.sleep(.1) From 1c2142868eb4c9adeb67a24b0fe97c737ff91234 Mon Sep 17 00:00:00 2001 From: ladyada Date: Thu, 27 Dec 2018 22:24:40 -0500 Subject: [PATCH 6/9] belinted --- examples/bonnet_buttons.py | 30 +++++++++++++++++++++--------- examples/pillow_animate.py | 16 +++++++++------- examples/pillow_images.py | 7 +------ examples/pillow_shapes.py | 15 +++++++-------- examples/stats.py | 30 ++++++++++++++++-------------- 5 files changed, 54 insertions(+), 44 deletions(-) diff --git a/examples/bonnet_buttons.py b/examples/bonnet_buttons.py index ff6d0c9..f6e2669 100644 --- a/examples/bonnet_buttons.py +++ b/examples/bonnet_buttons.py @@ -19,13 +19,12 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. +from PIL import Image, ImageDraw -import time import board import busio from digitalio import DigitalInOut, Direction, Pull import adafruit_ssd1306 -from PIL import Image, ImageDraw, ImageFont # Create the I2C interface. i2c = busio.I2C(board.SCL, board.SDA) @@ -36,18 +35,31 @@ # 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 @@ -65,7 +77,7 @@ draw = ImageDraw.Draw(image) # Draw a black filled box to clear the image. -draw.rectangle((0,0,width,height), outline=0, fill=0) +draw.rectangle((0, 0, width, height), outline=0, fill=0) while True: @@ -90,19 +102,19 @@ 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 + 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 + 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 + 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 + 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 + 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 + 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') diff --git a/examples/pillow_animate.py b/examples/pillow_animate.py index aec8ae1..dbe2303 100644 --- a/examples/pillow_animate.py +++ b/examples/pillow_animate.py @@ -18,21 +18,21 @@ # 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 PIL import Image, ImageDraw, ImageFont from board import SCL, SDA import busio import adafruit_ssd1306 -from PIL import Image, ImageDraw, ImageFont - # 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! +# 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: @@ -53,7 +53,8 @@ # 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! +# 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) @@ -61,7 +62,8 @@ 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. @@ -75,7 +77,7 @@ pos = startpos while True: # Clear image buffer by drawing a black filled box. - draw.rectangle((0,0,width,height), outline=0, fill=0) + 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): diff --git a/examples/pillow_images.py b/examples/pillow_images.py index 90ae4ae..e3fcf8c 100644 --- a/examples/pillow_images.py +++ b/examples/pillow_images.py @@ -18,18 +18,13 @@ # 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 time -import time +from PIL import Image from board import SCL, SDA import busio import adafruit_ssd1306 -from PIL import Image, ImageDraw, ImageFont - -import subprocess - # Create the I2C interface. i2c = busio.I2C(SCL, SDA) diff --git a/examples/pillow_shapes.py b/examples/pillow_shapes.py index 38f0c00..4034265 100644 --- a/examples/pillow_shapes.py +++ b/examples/pillow_shapes.py @@ -18,15 +18,13 @@ # 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 time + +from PIL import Image, ImageDraw, ImageFont from board import SCL, SDA import busio import adafruit_ssd1306 -from PIL import Image, ImageDraw, ImageFont - - # Create the I2C interface. i2c = busio.I2C(SCL, SDA) @@ -52,7 +50,7 @@ draw = ImageDraw.Draw(image) # Draw a black filled box to clear the image. -draw.rectangle((0,0,width,height), outline=0, fill=0) +draw.rectangle((0, 0, width, height), outline=0, fill=0) # Draw some shapes. # First define some constants to allow easy resizing of shapes. @@ -63,7 +61,7 @@ # 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) +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) @@ -79,12 +77,13 @@ # 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! +# 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), 'Hello', font=font, fill=255) draw.text((x, top+20), 'World!', font=font, fill=255) # Display image. diff --git a/examples/stats.py b/examples/stats.py index c883837..f5cb1d6 100644 --- a/examples/stats.py +++ b/examples/stats.py @@ -25,14 +25,14 @@ # not support PIL/pillow (python imaging library)! import time +import subprocess +from PIL import Image, ImageDraw, ImageFont from board import SCL, SDA import busio import adafruit_ssd1306 -from PIL import Image, ImageDraw, ImageFont -import subprocess # Create the I2C interface. i2c = busio.I2C(SCL, SDA) @@ -56,7 +56,7 @@ draw = ImageDraw.Draw(image) # Draw a black filled box to clear the image. -draw.rectangle((0,0,width,height), outline=0, fill=0) +draw.rectangle((0, 0, width, height), outline=0, fill=0) # Draw some shapes. # First define some constants to allow easy resizing of shapes. @@ -70,31 +70,33 @@ # 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! +# 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) + 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 + # 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") + 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") + 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") + 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") + Disk = subprocess.check_output(cmd, shell=True).decode("utf-8") # Write four lines of text. - draw.text((x, top+0), "IP: " + str(IP), font=font, fill=255) - draw.text((x, top+8), str(CPU), font=font, fill=255) - draw.text((x, top+16), str(MemUsage), font=font, fill=255) - draw.text((x, top+25), str(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) From 64299740e28ae6b7d29f6e9fb77dab06c8261abf Mon Sep 17 00:00:00 2001 From: ladyada Date: Thu, 27 Dec 2018 22:29:36 -0500 Subject: [PATCH 7/9] fix import order complaints --- examples/bonnet_buttons.py | 3 +-- examples/pillow_animate.py | 3 +-- examples/pillow_images.py | 3 +-- examples/stats.py | 3 +-- 4 files changed, 4 insertions(+), 8 deletions(-) diff --git a/examples/bonnet_buttons.py b/examples/bonnet_buttons.py index f6e2669..f5a07c7 100644 --- a/examples/bonnet_buttons.py +++ b/examples/bonnet_buttons.py @@ -19,11 +19,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -from PIL import Image, ImageDraw - import board import busio from digitalio import DigitalInOut, Direction, Pull +from PIL import Image, ImageDraw import adafruit_ssd1306 # Create the I2C interface. diff --git a/examples/pillow_animate.py b/examples/pillow_animate.py index dbe2303..fd2f039 100644 --- a/examples/pillow_animate.py +++ b/examples/pillow_animate.py @@ -21,10 +21,9 @@ import math import time -from PIL import Image, ImageDraw, ImageFont - from board import SCL, SDA import busio +from PIL import Image, ImageDraw, ImageFont import adafruit_ssd1306 # Create the I2C interface. diff --git a/examples/pillow_images.py b/examples/pillow_images.py index e3fcf8c..f72cb80 100644 --- a/examples/pillow_images.py +++ b/examples/pillow_images.py @@ -19,10 +19,9 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -from PIL import Image - from board import SCL, SDA import busio +from PIL import Image import adafruit_ssd1306 # Create the I2C interface. diff --git a/examples/stats.py b/examples/stats.py index f5cb1d6..703747e 100644 --- a/examples/stats.py +++ b/examples/stats.py @@ -26,14 +26,13 @@ import time import subprocess -from PIL import Image, ImageDraw, ImageFont 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) From a356cce6fb61b3326eb8cf508654064dc0bcd5c6 Mon Sep 17 00:00:00 2001 From: ladyada Date: Thu, 27 Dec 2018 22:32:18 -0500 Subject: [PATCH 8/9] (forgot one) --- examples/pillow_shapes.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/examples/pillow_shapes.py b/examples/pillow_shapes.py index 4034265..b3e5713 100644 --- a/examples/pillow_shapes.py +++ b/examples/pillow_shapes.py @@ -19,10 +19,9 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -from PIL import Image, ImageDraw, ImageFont - from board import SCL, SDA import busio +from PIL import Image, ImageDraw, ImageFont import adafruit_ssd1306 # Create the I2C interface. From eef4d99ec6112210062114465f0401875a8c2bc0 Mon Sep 17 00:00:00 2001 From: ladyada Date: Fri, 28 Dec 2018 10:06:50 -0500 Subject: [PATCH 9/9] add framebuf dep --- README.rst | 1 + 1 file changed, 1 insertion(+) 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