ILI9341 (8bit parallel bus) display on RP2040/CircuitPython
This video show WeAct RP2040 (16M Flash)
running CircuitPython 8.0.5, to display on 2.8 inch 320x240 ili9341 TFT with 8/16BIT parallel interface. It should be work on Raspberry Pi Pico also.
This display is set 16-bit parallel interface by default. Read here to set it in 8 bit interface.
Connection between RP2040 and
2.8" 320x240 ili9341 TFT in 8-bit parallel interface:
RP2040 GPIO
| |
V V
+------------+
| CLK T_CS |
| F_CS PEN |
| MOSI MISO |
| NC GND | GND
GND | GND VDD | 3V3
3V3 | VDD BL | 3V3
| SDCS DB15 | 17
16 | DB14 DB13 | 15
14 | DB12 DB11 | 13
12 | DB10 DB9 | 11
10 | DB8 DB7 |
| DB6 DB5 |
| DB4 DB3 |
| DB2 DB1 |
| DB0 RST | 20
8 | RD WR | 19
9 | RS CS | 18
+------------+
ILI9341 TFT (parallel i/f)
Exercise code
cpyPico_ParallelBus_ili9341.py
Simple setup display of adafruit_ili9341, with display_bus = displayio.ParallelBus().
import os, sys
import time
import board
import displayio
import adafruit_ili9341
displayio.release_displays()
"""
This Raspberry Pi Pico,
supports data0= only, not data_pins=, because it requires contiguous pins.
"""
TFT_DATA0 = board.GP10 #The first data pin. The rest are implied
#D0~D7 = GP10~17
TFT_RS = board.GP9 #command
TFT_CS = board.GP18 #chip Select
TFT_WR = board.GP19 #write
TFT_RD = board.GP8 #read
TFT_RST = board.GP20 #reset
TFT_WIDTH = 320
TFT_HEIGHT = 240
display_bus = displayio.ParallelBus(data0=TFT_DATA0,
command=TFT_RS,
chip_select=TFT_CS,
write=TFT_WR,
read=TFT_RD,
reset=TFT_RST)
display = adafruit_ili9341.ILI9341(display_bus,
width=TFT_WIDTH,
height=TFT_HEIGHT)
display.rotation=270
print("========================================")
print(sys.implementation[0], os.uname()[3],
"\nrun on", os.uname()[4])
print("========================================")
print(adafruit_ili9341.__name__, adafruit_ili9341.__version__)
print(display_bus)
print()
print("display.rotation:", display.rotation)
print("display.width: ", display.width)
print("display.height: ", display.height)
print()
print("Press Enter to return to REPL")
input()
print("~ bye ~")
time.sleep(1)
print()
cpyPico_ParallelBus_ili9341_graysq.py
A visual illusion exercise, both square have the same gray level.
import os, sys
import time
import board
import displayio
import adafruit_ili9341
from adafruit_display_shapes.rect import Rect
displayio.release_displays()
"""
This Raspberry Pi Pico,
supports data0= only, not data_pins=, because it requires contiguous pins.
"""
TFT_DATA0 = board.GP10 #The first data pin. The rest are implied
#D0~D7 = GP10~17
TFT_RS = board.GP9 #command
TFT_CS = board.GP18 #chip Select
TFT_WR = board.GP19 #write
TFT_RD = board.GP8 #read
TFT_RST = board.GP20 #reset
TFT_WIDTH = 320
TFT_HEIGHT = 240
display_bus = displayio.ParallelBus(data0=TFT_DATA0,
command=TFT_RS,
chip_select=TFT_CS,
write=TFT_WR,
read=TFT_RD,
reset=TFT_RST,
frequency=60000000)
# very strange, in my test,
# frequency of 60000000 is more stable than 30000000 or 40000000
display = adafruit_ili9341.ILI9341(display_bus,
width=TFT_WIDTH,
height=TFT_HEIGHT)
display.rotation=0
print("========================================")
print(sys.implementation[0], os.uname()[3],
"\nrun on", os.uname()[4])
print("========================================")
print(adafruit_ili9341.__name__, adafruit_ili9341.__version__)
print(display_bus)
print()
print("display.rotation:", display.rotation)
print("display.width: ", display.width)
print("display.height: ", display.height)
print()
group = displayio.Group()
no_of_color = 256
bg_bitmap = displayio.Bitmap(display.width, display.height, no_of_color)
bg_palette = displayio.Palette(no_of_color)
bg = displayio.TileGrid(bg_bitmap, pixel_shader=bg_palette)
for i in range(no_of_color):
bg_palette[i] = i*0x10000 + i*0x100 +i
for y in range(display.height):
for x in range(display.width):
bg_bitmap[x, y] = y
group.append(bg)
sq = Rect(20, 20, 20, 20, fill=0xA0A0A0)
group.append(sq)
sq2 = Rect(280, 200, 20, 20, fill=0xA0A0A0)
group.append(sq2)
"""
show() is deprecated and will be removed in CircuitPython 9.0.0. Use .root_group = group instead.
https://docs.circuitpython.org/en/latest/shared-bindings/displayio/index.html#displayio.Display.show
"""
#display.show(group)
display.root_group = group
time.sleep(5)
x_dir=1
y_dir=1
x_step=3
y_step=2
while True:
time.sleep(0.05)
sq.x = sq.x + x_dir*x_step
sq.y = sq.y + y_dir*y_step
if x_dir>0:
if sq.x>=display.width-1-sq.width:
x_dir = -1
else:
if sq.x<=0:
x_dir = 1
if y_dir>0:
if sq.y>=display.height-1-sq.height:
y_dir = -1
else:
if sq.y<=0:
y_dir = 1
while True:
pass
cpyPico_ParallelBus_ili9341_graybar.py
Another visual illusion exercise, the frame is set a single gray level.
import os, sys
import time
import board
import displayio
import adafruit_ili9341
from adafruit_display_shapes.rect import Rect
displayio.release_displays()
"""
This Raspberry Pi Pico,
supports data0= only, not data_pins=, because it requires contiguous pins.
"""
TFT_DATA0 = board.GP10 #The first data pin. The rest are implied
#D0~D7 = GP10~17
TFT_RS = board.GP9 #command
TFT_CS = board.GP18 #chip Select
TFT_WR = board.GP19 #write
TFT_RD = board.GP8 #read
TFT_RST = board.GP20 #reset
TFT_WIDTH = 320
TFT_HEIGHT = 240
display_bus = displayio.ParallelBus(data0=TFT_DATA0,
command=TFT_RS,
chip_select=TFT_CS,
write=TFT_WR,
read=TFT_RD,
reset=TFT_RST,
frequency=60000000)
display = adafruit_ili9341.ILI9341(display_bus,
width=TFT_WIDTH,
height=TFT_HEIGHT)
display.rotation=0
print("========================================")
print(sys.implementation[0], os.uname()[3],
"\nrun on", os.uname()[4])
print("========================================")
print(adafruit_ili9341.__name__, adafruit_ili9341.__version__)
print(display_bus)
print()
print("display.rotation:", display.rotation)
print("display.width: ", display.width)
print("display.height: ", display.height)
print()
group = displayio.Group()
no_of_color = 256
bg_bitmap = displayio.Bitmap(display.width, display.height, no_of_color)
bg_palette = displayio.Palette(no_of_color)
bg = displayio.TileGrid(bg_bitmap, pixel_shader=bg_palette)
for i in range(no_of_color):
bg_palette[i] = i*0x10000 + i*0x100 +i
for y in range(display.height):
for x in range(display.width):
bg_bitmap[x, y] = y
group.append(bg)
#All four rect set same gray level
rect = Rect(20, 10, 10, 220, fill=0xA0A0A0)
group.append(rect)
rect2 = Rect(20, 10, 280, 10, fill=0xA0A0A0)
group.append(rect2)
rect3 = Rect(20, 220, 280, 10, fill=0xA0A0A0)
group.append(rect3)
rect3 = Rect(300, 10, 10, 220, fill=0xA0A0A0)
group.append(rect3)
"""
show() is deprecated and will be removed in CircuitPython 9.0.0. Use .root_group = group instead.
https://docs.circuitpython.org/en/latest/shared-bindings/displayio/index.html#displayio.Display.show
"""
#display.show(group)
display.root_group = group
while True:
time.sleep(5)
for i in range(no_of_color):
inv_i = 255-i
bg_palette[i] = inv_i*0x10000 + inv_i*0x100 +inv_i
time.sleep(5)
for i in range(no_of_color):
bg_palette[i] = i*0x10000 + i*0x100 +i
cpyPico_ParallelBus_ili9341_hello.py
import os, sys
import time
import board
import displayio
import adafruit_ili9341
import terminalio
from adafruit_display_shapes.rect import Rect
from adafruit_display_text import label
displayio.release_displays()
"""
This Raspberry Pi Pico,
supports data0= only, not data_pins=, because it requires contiguous pins.
"""
TFT_DATA0 = board.GP10 #The first data pin. The rest are implied
#D0~D7 = GP10~17
TFT_RS = board.GP9 #command
TFT_CS = board.GP18 #chip Select
TFT_WR = board.GP19 #write
TFT_RD = board.GP8 #read
TFT_RST = board.GP20 #reset
TFT_WIDTH = 320
TFT_HEIGHT = 240
display_bus = displayio.ParallelBus(data0=TFT_DATA0,
command=TFT_RS,
chip_select=TFT_CS,
write=TFT_WR,
read=TFT_RD,
reset=TFT_RST,
frequency=60000000)
# very strange, in my test,
# frequency of 60000000 is more stable than 30000000 or 40000000
display = adafruit_ili9341.ILI9341(display_bus,
width=TFT_WIDTH,
height=TFT_HEIGHT)
display.rotation=270
print("========================================")
print(sys.implementation[0], os.uname()[3],
"\nrun on", os.uname()[4])
print("========================================")
print(adafruit_ili9341.__name__, adafruit_ili9341.__version__)
print(display_bus)
print()
print("display.rotation:", display.rotation)
print("display.width: ", display.width)
print("display.height: ", display.height)
print()
# Make the display context
splash = displayio.Group()
"""
show() is deprecated and will be removed in CircuitPython 9.0.0. Use .root_group = group instead.
https://docs.circuitpython.org/en/latest/shared-bindings/displayio/index.html#displayio.Display.show
"""
#display.show(splash)
display.root_group = splash
bg_bitmap = displayio.Bitmap(display.width, display.height, 1)
bg_palette = displayio.Palette(1)
bg_palette[0] = 0xFFFFFF # White
background = displayio.TileGrid(bg_bitmap, pixel_shader=bg_palette, x=0, y=0)
splash.append(background)
inner_bitmap = displayio.Bitmap(display.width-2, display.height-2, 1)
inner_palette = displayio.Palette(1)
inner_palette[0] = 0x000000 # Black
inner = displayio.TileGrid(inner_bitmap, pixel_shader=inner_palette, x=1, y=1)
splash.append(inner)
# draw a label say hello
text_hello = "coxxect.blogspot.com"
label_hello = label.Label(terminalio.FONT, text=text_hello, scale=2, color=0xFF0000, x=2, y=10)
splash.append(label_hello)
# label for CircuitPython info
sys_info = sys.implementation[0] + " " + os.uname()[2] + "\nrun on " + os.uname()[4]
# labels for driver
label_sysinfo = label.Label(terminalio.FONT,
text=sys_info,
scale=1,
color=0x00FF00,
x=5, y=40)
splash.append(label_sysinfo)
# labels for driver
label_drv_name = label.Label(terminalio.FONT,
text=adafruit_ili9341.__name__,
scale=1,
color=0x0000FF,
x=5, y=90)
splash.append(label_drv_name)
label_drv_ver = label.Label(terminalio.FONT,
text=adafruit_ili9341.__version__,
scale=2,
color=0x0000FF,
x=5, y=110)
splash.append(label_drv_ver)
# scroll()/reverse_scroll()
# ref:
# https://learn.adafruit.com/rgb-led-matrices-matrix-panels-with-circuitpython/example-simple-two-line-text-scroller
def scroll(line):
line.x = line.x - 1
line_width = line.bounding_box[2]
if line.x < -line_width:
line.x = display.width
def reverse_scroll(line):
line.x = line.x + 1
line_width = line.bounding_box[2]
if line.x >= display.width:
line.x = -line_width
time.sleep(1)
while True:
scroll(label_sysinfo)
scroll(label_drv_name)
reverse_scroll(label_drv_ver)
display.refresh(minimum_frames_per_second=0)
ref:
~ CircuitPython Display Support Using displayio Display and Display Bus
~ paralleldisplay
next:
~ RP2040/CircuitPython 8.1.0 Beta 1, play animated GIF on 8 bit parallel bus ILI9341.
~ Play animated GIF stored in SD Card
Comments
Post a Comment