Merge pull request #1 from pimoroni/160x80

Support for 160x80 0.96" LCD Breakout
This commit is contained in:
Philip Howard
2019-01-18 12:18:57 +00:00
committed by GitHub
6 changed files with 143 additions and 52 deletions

View File

@@ -1,9 +1,9 @@
Python ST7735
=======================
Python ST7735 160x80
====================
Python library to control an ST7735 TFT LCD display. Allows simple drawing on the display without installing a kernel module.
Designed specifically to work with a ST7735 based 128x160 pixel TFT SPI display.
Designed specifically to work with a ST7735 based 160x80 pixel TFT SPI display. (Specifically the 0.96" SPI LCD from Pimoroni).
For all platforms (Raspberry Pi and Beaglebone Black) make sure you have the following dependencies:
@@ -33,8 +33,10 @@ sudo python setup.py install
See example of usage in the examples folder.
Pimoroni invests time and resources forking and slightly modifying this open source code, please support Pimoroni and open-source software by purchasing products from us, too!
Adafruit invests time and resources providing this open source code, please support Adafruit and open-source hardware by purchasing products from Adafruit!
Modified from 'Adafruit Python ILI9341' written by Tony DiCola for Adafruit Industries.
Modified from 'Modified from 'Adafruit Python ILI9341' written by Tony DiCola for Adafruit Industries.' written by Clement Skau.
MIT license, all text above must be included in any redistribution

View File

@@ -30,12 +30,12 @@ import Adafruit_GPIO.SPI as SPI
# SPI_CLOCK_HZ = 64000000 # 64 MHz
SPI_CLOCK_HZ = 4000000 # 4 MHz
SPI_CLOCK_HZ = 16000000 # 4 MHz
# Constants for interacting with display registers.
ST7735_TFTWIDTH = 128
ST7735_TFTHEIGHT = 160
ST7735_TFTWIDTH = 160 # 128
ST7735_TFTHEIGHT = 80 #64 #160
ST7735_NOP = 0x00
ST7735_SWRESET = 0x01
@@ -116,7 +116,7 @@ def image_to_data(image):
"""Generator function to convert a PIL image to 16-bit 565 RGB bytes."""
# NumPy is much faster at doing this. NumPy code provided by:
# Keith (https://www.blogger.com/profile/02555547344016007163)
pb = np.array(image.convert('RGB')).astype('uint16')
pb = np.rot90(np.array(image.convert('RGB')), 1).astype('uint16')
color = ((pb[:,:,0] & 0xF8) << 8) | ((pb[:,:,1] & 0xFC) << 3) | (pb[:,:,2] >> 3)
return np.dstack(((color >> 8) & 0xFF, color & 0xFF)).flatten().tolist()
@@ -235,7 +235,7 @@ class ST7735(object):
self.command(ST7735_VMCTR1) # Power control
self.data(0x0E)
self.command(ST7735_INVOFF) # Don't invert display
self.command(ST7735_INVON) # Don't invert display
self.command(ST7735_MADCTL) # Memory access control (directions)
self.data(0xC8) # row addr/col addr, bottom to top refresh
@@ -247,15 +247,15 @@ class ST7735(object):
self.command(ST7735_CASET) # Column addr set
self.data(0x00) # XSTART = 0
self.data(0x00)
self.data(132 - ST7735_TFTHEIGHT)
self.data(0x00) # XEND = 127
self.data(0x7F)
self.data(ST7735_TFTHEIGHT - 1)
self.command(ST7735_RASET) # Row addr set
self.data(0x00) # XSTART = 0
self.data(0x00)
self.data(161 - ST7735_TFTWIDTH)
self.data(0x00) # XEND = 159
self.data(0x9F)
self.data(ST7735_TFTWIDTH - 1)
#
@@ -319,16 +319,25 @@ class ST7735(object):
x1 = self.width-1
if y1 is None:
y1 = self.height-1
#y0 += 132 - 80
#y1 += 132 - 80
y0 += 26
y1 += 26
x0 += 1
x1 += 1
self.command(ST7735_CASET) # Column addr set
self.data(x0 >> 8)
self.data(x0) # XSTART
self.data(x1 >> 8)
self.data(x1) # XEND
self.command(ST7735_RASET) # Row addr set
self.data(y0 >> 8)
self.data(y0) # YSTART
self.data(y0) # XSTART
self.data(y1 >> 8)
self.data(y1) # YEND
self.data(y1) # XEND
self.command(ST7735_RASET) # Row addr set
self.data(x0 >> 8)
self.data(x0) # YSTART
self.data(x1 >> 8)
self.data(x1) # YEND
self.command(ST7735_RAMWR) # write to RAM
def display(self, image=None):

67
examples/gif.py Normal file
View File

@@ -0,0 +1,67 @@
# Copyright (c) 2014 Adafruit Industries
# Author: Phil Howard, 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 PIL import Image
import ST7735 as TFT
import Adafruit_GPIO.SPI as SPI
import time
import sys
image_file = sys.argv[1]
WIDTH = TFT.ST7735_TFTWIDTH
HEIGHT = TFT.ST7735_TFTHEIGHT
SPEED_HZ = 4000000
# Raspberry Pi configuration.
DC = 5
RST = 25
SPI_PORT = 0
SPI_DEVICE = 0
# Create TFT LCD display class.
disp = TFT.ST7735(
DC,
rst=RST,
spi=SPI.SpiDev(
SPI_PORT,
SPI_DEVICE,
max_speed_hz=SPEED_HZ))
# Initialize display.
disp.begin()
# Load an image.
print('Loading gif: {}...'.format(image_file))
image = Image.open(image_file)
print('Drawing gif')
frame = 0
while True:
try:
image.seek(frame)
disp.display(image.resize((WIDTH, HEIGHT)))
frame += 1
time.sleep(0.05)
except EOFError:
frame = 0

View File

@@ -21,18 +21,24 @@
from PIL import Image
import ST7735 as TFT
import Adafruit_GPIO as GPIO
import Adafruit_GPIO.SPI as SPI
import time
import sys
WIDTH = 128
HEIGHT = 160
if len(sys.argv) < 2:
print("Usage: {} <image_file>".format(sys.argv[0]))
sys.exit(1)
image_file = sys.argv[1]
WIDTH = TFT.ST7735_TFTWIDTH
HEIGHT = TFT.ST7735_TFTHEIGHT
SPEED_HZ = 4000000
# Raspberry Pi configuration.
DC = 24
RST = 25
DC = 5
SPI_PORT = 0
SPI_DEVICE = 0
@@ -45,7 +51,6 @@ SPI_DEVICE = 0
# Create TFT LCD display class.
disp = TFT.ST7735(
DC,
rst=RST,
spi=SPI.SpiDev(
SPI_PORT,
SPI_DEVICE,
@@ -55,12 +60,14 @@ disp = TFT.ST7735(
disp.begin()
# Load an image.
print('Loading image...')
image = Image.open('cat.jpg')
print('Loading image: {}...'.format(image_file))
image = Image.open(image_file)
# Resize the image and rotate it so matches the display.
image = image.rotate(90).resize((WIDTH, HEIGHT))
# image = image.rotate(90).resize((WIDTH, HEIGHT))
image = image.resize((WIDTH, HEIGHT))
# Draw the image on the display hardware.
print('Drawing image')
disp.display(image)

View File

@@ -24,14 +24,23 @@ import ST7735 as TFT
import Adafruit_GPIO as GPIO
import Adafruit_GPIO.SPI as SPI
import sys
WIDTH = 128
HEIGHT = 160
SPEED_HZ = 4000000
if len(sys.argv) < 2:
print("Usage: {} <image_file>".format(sys.argv[0]))
sys.exit(1)
image_file = sys.argv[1]
WIDTH = 160
HEIGHT = 80
SPEED_HZ = 16000000
# Raspberry Pi configuration.
DC = 24
DC = 5
RST = 25
SPI_PORT = 0
SPI_DEVICE = 0
@@ -56,10 +65,10 @@ disp.begin()
# Load an image.
print('Loading image...')
image = Image.open('cat.jpg')
image = Image.open(image_file)
# Resize the image and rotate it so matches the display.
image = image.rotate(90).resize((WIDTH, HEIGHT))
image = image.rotate(0).resize((WIDTH, HEIGHT))
print('Press Ctrl-C to exit')
while(True):
@@ -69,5 +78,5 @@ while(True):
disp.display(image)
end_time = time.time()
print('Time to draw image: ' + str(end_time - start_time))
disp.clear((0, 0, 0))
disp.display()
# disp.clear((0, 0, 0))
# disp.display()

View File

@@ -23,18 +23,16 @@ from PIL import ImageDraw
from PIL import ImageFont
import ST7735 as TFT
import Adafruit_GPIO as GPIO
import Adafruit_GPIO.SPI as SPI
WIDTH = 128
HEIGHT = 160
WIDTH = 160
HEIGHT = 80
SPEED_HZ = 4000000
# Raspberry Pi configuration.
DC = 24
RST = 25
DC = 5
SPI_PORT = 0
SPI_DEVICE = 0
@@ -47,7 +45,6 @@ SPI_DEVICE = 0
# Create TFT LCD display class.
disp = TFT.ST7735(
DC,
rst=RST,
spi=SPI.SpiDev(
SPI_PORT,
SPI_DEVICE,
@@ -66,19 +63,19 @@ disp.clear((255, 0, 0))
# Get a PIL Draw object to start drawing on the display buffer.
draw = disp.draw()
# Draw a purple rectangle with yellow outline.
draw.rectangle((10, 10, WIDTH-10, HEIGHT-10), outline=(255,255,0), fill=(255,0,255))
# Draw some shapes.
# Draw a blue ellipse with a green outline.
draw.ellipse((10, 10, 110, 80), outline=(0,255,0), fill=(0,0,255))
# Draw a purple rectangle with yellow outline.
draw.rectangle((10, 90, 110, 160), outline=(255,255,0), fill=(255,0,255))
draw.ellipse((10, 10, WIDTH-10, HEIGHT-10), outline=(0,255,0), fill=(0,0,255))
# Draw a white X.
draw.line((10, 170, 110, 230), fill=(255,255,255))
draw.line((10, 230, 110, 170), fill=(255,255,255))
draw.line((10, 10, WIDTH-10, HEIGHT-10), fill=(255,255,255))
draw.line((10, HEIGHT-10, WIDTH-10, 10), fill=(255,255,255))
# Draw a cyan triangle with a black outline.
draw.polygon([(10, 275), (110, 240), (110, 310)], outline=(0,0,0), fill=(0,255,255))
draw.polygon([(WIDTH/2, 10), (WIDTH-10, HEIGHT-10), (10, HEIGHT-10)], outline=(0,0,0), fill=(0,255,255))
# Load default font.
font = ImageFont.load_default()
@@ -105,8 +102,8 @@ def draw_rotated_text(image, text, position, angle, font, fill=(255,255,255)):
image.paste(rotated, position, rotated)
# Write two lines of white text on the buffer, rotated 90 degrees counter clockwise.
draw_rotated_text(disp.buffer, 'Hello World!', (150, 120), 90, font, fill=(255,255,255))
draw_rotated_text(disp.buffer, 'This is a line of text.', (170, 90), 90, font, fill=(255,255,255))
draw_rotated_text(disp.buffer, 'Hello World!', (0, 0), 90, font, fill=(255,255,255))
draw_rotated_text(disp.buffer, 'This is a line of text.', (10, HEIGHT-10), 0, font, fill=(255,255,255))
# Write buffer to display hardware, must be called to make things visible on the
# display!