-
Notifications
You must be signed in to change notification settings - Fork 344
display
This class includes full support for ILI9341, ILI9488, ST7789V and ST7735 based TFT modules in 4-wire SPI mode.
Some TFT examples are available.
ESP32 pin | Display module | Notes |
---|---|---|
Any output pin | MOSI | SPI input on Display module |
Any pin | MISO | SPI output from Display module, optional |
Any output pin | SCK | SPI clock input on Display module |
Any output pin | CS | SPI CS input on Display module |
Any output pin | DC | DC (data/command) input on Display module |
Any output pin | TCS | Touch pannel CS input (if touch panel is used |
Any output pin | RST | optional, reset input of the display module, if not used pullup the reset input to Vcc |
Any output pin | BL | optional, backlight input of the display module, if not used connect to +3.3V (or +5V) |
GND | GND | Power supply ground |
3.3V or +5V | Vcc | Power supply positive |
Make shure the display module has 3.3V compatible interface, if not you must use level shifter!
Before using the display, the display module must be imported and the instance of the TFT class has to be created:
import display
tft = display.TFT()
Color values are given as 24 bit integer numbers, 8-bit per color.
For example: 0xFF0000 represents the RED color. Only upper 6 bits of the color component value is used.
The following color constants are defined and can be used as color arguments:
BLACK
, NAVY
, DARKGREEN
, DARKCYAN
, MAROON
, PURPLE
OLIVE
, LIGHTGREY
, DARKGREY
, BLUE
, GREEN
, CYAN
, RED
MAGENTA
, YELLOW
, WHITE
, ORANGE
, GREENYELLOW
, PINK
All drawings coordinates are relative to the display window.
Initialy, the display window is set to full screen, and there are methods to set the window to the part of the full screen.
9 bit-mapped fornts and one vector 7-segment font are included. Unlimited number of fonts from file can also be used.
The following font constants are defined and can be used as font arguments:
FONT_Default
, FONT_DefaultSmall
, FONT_DejaVu18
, FONT_Dejavu24
FONT_Ubuntu
, FONT_Comic
, FONT_Minya
, FONT_Tooney
, FONT_Small
FONT_7seg
Touch panels based on XPT2066 and STMPE610 controllers are supported at the moment.
Initialize the SPI interface and set the warious operational modes.
All arguments, except for type are KW arguments and must be entered as arg=value
.
Pins have to be given as pin numbers, not the machine.Pin objects
opt_args
are optional, see the table bellow.
Argument | Description |
---|---|
type |
required, sets the display controler type, use one of the constants: ST7789 , ILI9341 , ILI9488 , ST7735 , ST7735B , ST7735R , M5STACK , GENERIC If GENERIC type is set, the display will not be initializedPython initialization function must be provided and used to initialize the display. |
mosi | required, SPI MOSI pin number |
miso | required, SPI MISO pin number |
clk | required, SPI CLK pin number |
cs | required, SPI CS pin number |
spihost |
optional, default=HSPI_HOST , select ESP32 spi host, use constants: HSPI_HOST or VSPI_HOST
|
width | optional, default=240, display phisical width in pixels (display's smaller dimension). |
height | optional, default=320, display phisical height in pixels (display's larger dimension). |
speed | optional, default=10000000, SPI speed for display comunication in Hz. Maximal usable speed depends on display type and the wiring length |
tcs | optional, Touch panel CS pin number if used |
rst_pin | optional, default=not used, pin to drive the RESET input on Display module, if not set the software reset will be used |
backl_pin | optional, default=not used, pin to drive the backlight input on Display module, do not use if the display module does not have some kind of backlight driver, the display's backlight usualy needs more current than gpio can provide. |
backl_on | optional, default=0, polarity of backl_pin for backlight ON, 0 or 1 |
hastouch |
optional, default=TOUCH_NONE , set to TOUCH_XPT or TOUCH_STMPE if touch panel is used |
invrot |
optional, default=auto, configure special display rotation options If not set default value for display type is used. If you get some kind of mirrored display or you can's set correct orientation mode, try to use different values for invrot : 0, 1, 2 or 3 |
bgr |
optional, default=False, set to True if the display panel has BGR matrix. If you get inverted RED and BLUE colors, try to change this argument |
color_bits |
optional, default=COLOR_BITS24 ; Set color mode to 24 or 16 bits.Use constants COLOR_BITS16 or COLOR_BITS24 Some display controllers, like ILI9488, does not support 16-bit colors. |
rot | optional, default=PORTRAIT ; Set the initial display orientation |
splash | optional, default=True; If set to False do not display "MicroPython" string in RGB colors atfter initialization |
De initialize the used spi device(s), free all used resources.
Draw the pixel at position (x,y).
If color is not given, current foreground color is used.
Get the pixel color value at position (x,y).
Read the content of the rectangular screen area into buffer.
If the buffer object buff
is not given, the new string object with the screen data wil be returned.
3 bytes per pixel are returned (R, G, B).
Draw the line from point (x,y) to point (x1,y1)
If color is not given, current foreground color is used.
Draw the line from point (x,y) with length lenght starting st distance start from center.
If color is not given, current foreground color is used.
The angle is given in degrees (0~359).
Draw the triangel between points (x,y), (x1,y1) and (x2,y2).
If color is not given, current foreground color is used.
If fillcolor is given, filled triangle will be drawn.
Draw the circle with center at (x,y) and radius r.
If color is not given, current foreground color is used.
If fillcolor is given, filled circle will be drawn.
Draw the circle with center at (x,y) and radius r.
If color is not given, current foreground color is used.
*opt argument defines the ellipse segment to be drawn, default id 15, all ellipse segments.
Multiple segments can drawn, combine (logical or) the values.
- 1 - upper left segment
- 2 - upper right segment
- 4 - lower left segment
- 8 - lower right segment
If fillcolor is given, filled elipse will be drawn.
Draw the arc with center at (x,y) and radius r, starting at angle start and ending at angle end
The thicknes of the arc outline is set by the thick argument
If fillcolor is given, filled arc will be drawn.
Draw the polygon with center at (x,y) and radius r, with number of sides sides
The thicknes of the polygon outline is set by the thick argument
If fillcolor is given, filled polygon will be drawn.
If rotate is given, the polygon is rotated by the given angle (0~359)
Draw the rectangle from the upper left point at (x,y) and width width and height height
If fillcolor is given, filled rectangle will be drawn.
Draw the rectangle with rounded corners from the upper left point at (x,y) and width width and height height
Corner radius is given by r argument.
If fillcolor is given, filled rectangle will be drawn.
Clear the screen with default background color or specific color if given.
Clear the current display window with default background color or specific color if given.
Set the display orientation.
Use one of predifined constants:
tft.PORTRAIT, tft.LANDSCAPE, tft.PORTRAIT_FLIP, tft.LANDSCAPE_FLIP
Set the active font and its characteristics.
Argument | Description |
---|---|
font | required, use font name constant or font file name |
rotate | optional, set font rotation angle (0~360) |
transparent | only draw font's foreground pixels |
fixedwidth | draw proportional font with fixed character width, max character width from the font is used |
dist | only for 7-seg font, the distance between bars |
width | only for 7-seg font, the width of the bar |
outline | only for 7-seg font, draw the outline |
color | font color, if not given the current foreground color is used |
Set characteristics of the 7-segment font
Argument | Description |
---|---|
dist | the distance between bars |
width | the width of the bar |
outline | outline color |
color | fill color |
Return width and height of the active font
Display the string text
at possition (x
,y
).
If color
is not given, current foreground color is used.
-
x
: horizontal position of the upper left point in pixels, special values can be given:-
CENTER
, centers the text -
RIGHT
, right justifies the text -
LASTX
, continues from last X position; offset can be used:LASTX+n
-
-
y
: vertical position of the upper left point in pixels, special values can be given:-
CENTER
, centers the text -
BOTTOM
, bottom justifies the text -
LASTY
, continues from last Y position; offset can be used:LASTY+n
-
-
text
: string to be displayed. Two special characters are allowed in strings:-
\r
CR (0x0D), clears the display to EOL -
\n
LF (ox0A), continues to the new line, x=0
-
Return the width of the string text using the active font fontSize
Clear the the screen area used by string text at possition (x,y) using the bacckground color color.
If color is not given, current background color is used.
Display the image from the file file on position (x,y)
-
JPG images are supported.
Baseline only. Progressive and Lossless JPEG format are not supported.
Image size: Up to 65520 x 65520 pixels
Color space: YCbCr three components only. Gray scale image is not supported.
Sampling factor: 4:4:4, 4:2:2 or 4:2:0. -
BMP images are supported.
Only uncompressed RGB 24-bit with no color space information BMP images can be displayed. - Constants tft.CENTER, tft.BOTTOM, tft.RIGHT can be used for x&y
- x and y values can be negative
scale (jpg): image scale factor: 0 to 3; if scale>0, image is scaled by factor 1/(2^scale) (1/2, 1/4 or 1/8)
scale (bmp): image scale factor: 0 to 7; if scale>0, image is scaled by factor 1/(scale+1)
type: optional, set the image type, constants tft.JPG or tft.BMP can be used. If not set, file extension and/or file content will be used to determine the image type.
WARNING: Displaying images from SDCard connected in SPI mode will be very slow. In such a case, it is recommended to copy the image files to the internal file system.
Set active display window to screen rectangle (x,y) - (x1,y1)
Reset active display window to full screen size.
Save active display window dimensions.
Restore active display window dimensions previously saved wint savewin().
Return the display size, (width, height)
Return the active display window size, (width, height)
Converts the components of a color, as specified by the HSB model, to an equivalent set of values for the default RGB model.
Returns 24-bit integer value suitable to be used as color argiment
Arguments
- hue: float: any number, the floor of this number is subtracted from it to create a fraction between 0 and 1. This fractional number is then multiplied by 360 to produce the hue angle in the HSB color model.
- saturation: float; 0 ~ 1.0
- brightness: float; 0 ~ 1.0
Compile the source font file (must have .c extension) to the binary font file (same name, .fon extension) which can be used as external font.
If debug=True the information about compiled font will be printed.
You can create the c source file from any tft font using the included ttf2c_vc2003.exe program. See README for instructions.
Get the touch status and coordinates.
The tuple (touched, x, y) wil be returned.
thouch is True if the touch panel is touched, False if not.
x, y - touch point coordinates, valid only if touched=True
If the optional argument raw is True, the raw touch controller coordinates are returned. Otherwise, the calibrated screen coordinates are returned.
Get the default background color
Get the default foreground color
Set the default background color
Set the default foreground color
Set display SPI speed
Returns tuple with the actual SPI speed set for writting and reading (write_speed, read_speed)
Activate display CS
Deactivate display CS
Write cmd
byte to the display controller
Write cmd
byte followed by data
(bytearray) to the display controller
Write cmd
byte to the display controller and read len
bytes of the command response
bytearray of read bytes is returned
Touch calibration can be done using the frozen module tpcalib.
You must initialize the displayfirst.
Usage:
tpc(tft.TOUCH_STMPE|tft.TOUCH_XPT [, save])
import tpcalib
tpc = tpcalib.Calibrate(tft)
dosave = True
tp_type = tft.TOUCH_STMPE
tpc.tpcalib(tt_type, dosave)
If optional argument id True, calibration constants will be updated and saved in NVS memory as tpcalibX & tpcalibY.
After reboot you can get them from NVS:
import machine
tft.setCalib(machine.nvs_getint("tpcalibX"), machine.nvs_getint("tpcalibY"))
"""
Demo program demonstrating the capabities of the MicroPython display module
Author: LoBo (https://github/loboris)
Date: 08/10/2017
"""
import machine, display, time, math
tft = display.TFT()
# ESP32-WROVER-KIT v3:
#tft.init(tft.ST7789, rst_pin=18, backl_pin=5, miso=25, mosi=23, clk=19, cs=22, dc=21)
# Adafruit:
tft.init(tft.ILI9341, width=240, height=320, miso=19, mosi=18, clk=5, cs=15, dc=33, bgr=True, hastouch=tft.TOUCH_STMPE, tcs=32)
# M5Stack:
#tft.init(tft.M5STACK, width=240, height=320, rst_pin=33, backl_pin=32, miso=19, mosi=23, clk=18, cs=14, dc=27, bgr=True, backl_on=1, invrot=3)
# Others...
#tft.init(tft.ILI9341, width=240, height=320, miso=19,mosi=23,clk=18,cs=5,dc=26,tcs=27,hastouch=True, bgr=True)
#tft.init(tft.ST7735R, speed=10000000, spihost=tft.HSPI, mosi=13, miso=12, clk=14, cs=15, dc=27, rst_pin=26, hastouch=False, bgr=False, width=128, height=160)
def testt():
while True:
lastx = 0
lasty = 0
t,x,y = tft.gettouch()
if t:
dx = abs(x-lastx)
dy = abs(y-lasty)
if (dx > 2) and (dy > 2):
tft.circle(x,y,4,tft.RED)
time.sleep_ms(50)
maxx = 240
maxy = 320
miny = 12
touch = False
# fonts used in this demo
fontnames = (
tft.FONT_Default,
tft.FONT_7seg,
tft.FONT_Ubuntu,
tft.FONT_Comic,
tft.FONT_Tooney,
tft.FONT_Minya
)
# Check if the display is touched
#-------------
def touched():
if not touch:
return False
else:
tch,_,_ = tft.gettouch()
if tch <= 0:
return False
else:
return True
# print display header
#----------------------
def header(tx, setclip):
# adjust screen dimensions (depends on used display and orientation)
global maxx, maxy, miny
maxx, maxy = tft.screensize()
tft.clear()
if maxx < 240:
tft.font(tft.FONT_Small, rotate=0)
else:
tft.font(tft.FONT_Default, rotate=0)
_,miny = tft.fontSize()
miny += 5
tft.rect(0, 0, maxx-1, miny-1, tft.OLIVE, tft.DARKGREY)
tft.text(tft.CENTER, 2, tx, tft.CYAN, transparent=True)
if setclip:
tft.setwin(0, miny, maxx, maxy)
# Display some fonts
#-------------------
def dispFont(sec=5):
header("DISPLAY FONTS", False)
if maxx < 240:
tx = "MicroPython"
else:
tx = "Hi from MicroPython"
starty = miny + 4
n = time.time() + sec
while time.time() < n:
y = starty
x = 0
i = 0
while y < maxy:
if i == 0:
x = 0
elif i == 1:
x = tft.CENTER
elif i == 2:
x = tft.RIGHT
i = i + 1
if i > 2:
i = 0
for font in fontnames:
if font == tft.FONT_7seg:
tft.font(font)
tft.text(x,y,"-12.45/",machine.random(0xFFFFFF))
else:
tft.font(font)
tft.text(x,y,tx, machine.random(0xFFFFFF))
_,fsz = tft.fontSize()
y = y + 2 + fsz
if y > (maxy-fsz):
y = maxy
if touched():
break
# Display random fonts
#------------------------------
def fontDemo(sec=5, rot=False):
tx = "FONTS"
if rot:
tx = "ROTATED " + tx
header(tx, True)
tx = "ESP32-MicrpPython"
n = time.time() + sec
while time.time() < n:
frot = 0
if rot:
frot = math.floor(machine.random(359)/5)*5
for font in fontnames:
if (not rot) or (font != tft.FONT_7seg):
x = machine.random(maxx-8)
if font != tft.FONT_7seg:
tft.font(font, rotate=frot)
_,fsz = tft.fontSize()
y = machine.random(miny, maxy-fsz)
tft.text(x,y,tx, machine.random(0xFFFFFF))
else:
l = machine.random(6,12)
w = machine.random(1,l // 3)
tft.font(font, rotate=frot, dist=l, width=w)
_,fsz = tft.fontSize()
y = machine.random(miny, maxy-fsz)
tft.text(x,y,"-12.45/", machine.random(0xFFFFFF))
if touched():
break
tft.resetwin()
# Display random lines
#-------------------
def lineDemo(sec=5):
header("LINE DEMO", True)
n = time.time() + sec
while time.time() < n:
x1 = machine.random(maxx-4)
y1 = machine.random(miny, maxy-4)
x2 = machine.random(maxx-1)
y2 = machine.random(miny, maxy-1)
color = machine.random(0xFFFFFF)
tft.line(x1,y1,x2,y2,color)
if touched():
break
tft.resetwin()
# Display random circles
#----------------------------------
def circleDemo(sec=5,dofill=False):
tx = "CIRCLE"
if dofill:
tx = "FILLED " + tx
header(tx, True)
n = time.time() + sec
while time.time() < n:
color = machine.random(0xFFFFFF)
fill = machine.random(0xFFFFFF)
x = machine.random(4, maxx-2)
y = machine.random(miny+2, maxy-2)
if x < y:
r = machine.random(2, x)
else:
r = machine.random(2, y)
if dofill:
tft.circle(x,y,r,color,fill)
else:
tft.circle(x,y,r,color)
if touched():
break
tft.resetwin()
#------------------
def circleSimple():
tx = "CIRCLE"
header(tx, True)
x = 110
y = 160
r = 110
z = 0
while z < 12:
color = machine.random(0xFFFFFF)
fill = machine.random(0xFFFFFF)
tft.circle(x,y,r,color,fill)
r -= 10
x += 10
z += 1
# Display random ellipses
#-----------------------------------
def ellipseDemo(sec=5,dofill=False):
tx = "ELLIPSE"
if dofill:
tx = "FILLED " + tx
header(tx, True)
n = time.time() + sec
while time.time() < n:
x = machine.random(4, maxx-2)
y = machine.random(miny+2, maxy-2)
if x < y:
rx = machine.random(2, x)
else:
rx = machine.random(2, y)
if x < y:
ry = machine.random(2, x)
else:
ry = machine.random(2, y)
color = machine.random(0xFFFFFF)
if dofill:
fill = machine.random(0xFFFFFF)
tft.ellipse(x,y,rx,ry,15, color,fill)
else:
tft.ellipse(x,y,rx,ry,15,color)
if touched():
break
tft.resetwin()
# Display random rectangles
#---------------------------------
def rectDemo(sec=5, dofill=False):
tx = "RECTANGLE"
if dofill:
tx = "FILLED " + tx
header(tx, True)
n = time.time() + sec
while time.time() < n:
x = machine.random(4, maxx-2)
y = machine.random(miny, maxy-2)
w = machine.random(2, maxx-x)
h = machine.random(2, maxy-y)
color = machine.random(0xFFFFFF)
if dofill:
fill = machine.random(0xFFFFFF)
tft.rect(x,y,w,h,color,fill)
else:
tft.rect(x,y,w,h,color)
if touched():
break
tft.resetwin()
# Display random rounded rectangles
#--------------------------------------
def roundrectDemo(sec=5, dofill=False):
tx = "ROUND RECT"
if dofill:
tx = "FILLED " + tx
header(tx, True)
n = time.time() + sec
while time.time() < n:
x = machine.random(2, maxx-18)
y = machine.random(miny, maxy-18)
w = machine.random(12, maxx-x)
h = machine.random(12, maxy-y)
if w > h:
r = machine.random(2, h // 2)
else:
r = machine.random(2, w // 2)
color = machine.random(0xFFFFFF)
if dofill:
fill = machine.random(0xFFFFFF)
tft.roundrect(x,y,w,h,r,color,fill)
else:
tft.roundrect(x,y,w,h,r,color)
if touched():
break
tft.resetwin()
import machine, display, time
from micropython import const
tft_rst = machine.Pin(33, machine.Pin.OUT, 1)
tft_bckl = machine.Pin(32, machine.Pin.OUT, 0)
# Define ILI9341 command constants
_RDDSDR = const(0x0f) # Read Display Self-Diagnostic Result
_SLPOUT = const(0x11) # Sleep Out
_GAMSET = const(0x26) # Gamma Set
_DISPOFF = const(0x28) # Display Off
_DISPON = const(0x29) # Display On
_CASET = const(0x2a) # Column Address Set
_PASET = const(0x2b) # Page Address Set
_RAMWR = const(0x2c) # Memory Write
_RAMRD = const(0x2e) # Memory Read
_MADCTL = const(0x36) # Memory Access Control
_VSCRSADD = const(0x37) # Vertical Scrolling Start Address
_PIXSET = const(0x3a) # Pixel Format Set
_PWCTRLA = const(0xcb) # Power Control A
_PWCRTLB = const(0xcf) # Power Control B
_DTCTRLA = const(0xe8) # Driver Timing Control A
_DTCTRLB = const(0xea) # Driver Timing Control B
_PWRONCTRL = const(0xed) # Power on Sequence Control
_PRCTRL = const(0xf7) # Pump Ratio Control
_PWCTRL1 = const(0xc0) # Power Control 1
_PWCTRL2 = const(0xc1) # Power Control 2
_VMCTRL1 = const(0xc5) # VCOM Control 1
_VMCTRL2 = const(0xc7) # VCOM Control 2
_FRMCTR1 = const(0xb1) # Frame Rate Control 1
_DISCTRL = const(0xb6) # Display Function Control
_ENA3G = const(0xf2) # Enable 3G
_PGAMCTRL = const(0xe0) # Positive Gamma Control
_NGAMCTRL = const(0xe1) # Negative Gamma Control
#------------------
def tft_init(disp):
# Reset
tft_rst.value(0)
time.sleep_ms(120)
tft_rst.value(1)
# Send initialization commands
for command, data in (
(_RDDSDR, b"\x03\x80\x02"),
(_PWCRTLB, b"\x00\xc1\x30"),
(_PWRONCTRL, b"\x64\x03\x12\x81"),
(_DTCTRLA, b"\x85\x00\x78"),
(_PWCTRLA, b"\x39\x2c\x00\x34\x02"),
(_PRCTRL, b"\x20"),
(_DTCTRLB, b"\x00\x00"),
(_PWCTRL1, b"\x23"),
(_PWCTRL2, b"\x10"),
(_VMCTRL1, b"\x3e\x28"),
(_VMCTRL2, b"\x86"),
(_MADCTL, b"\x48"),
#(_MADCTL, b"\x08"),
(_PIXSET, b"\x55"),
(_FRMCTR1, b"\x00\x18"),
(_DISCTRL, b"\x08\x82\x27"),
(_ENA3G, b"\x00"),
(_GAMSET, b"\x01"),
(_PGAMCTRL, b"\x0f\x31\x2b\x0c\x0e\x08\x4e\xf1\x37\x07\x10\x03\x0e\x09\x00"),
(_NGAMCTRL, b"\x00\x0e\x14\x03\x11\x07\x31\xc1\x48\x08\x0f\x0c\x31\x36\x0f")):
disp.tft_writecmddata(command, data)
disp.tft_writecmd(_SLPOUT)
time.sleep_ms(120)
disp.tft_writecmd(_DISPON)
tft_bckl.value(1)
tft = display.TFT()
# Init display with GENERIC type, the display will not be initialized
# This, for example, works for M5Stack display
tft.init(tft.GENERIC, width=240, height=320, miso=19, mosi=23, clk=18, cs=14, dc=27, bgr=True, color_bits=16, invrot=3)
# Initialize the display
tft_init(tft)
# We can naw use all display commands
ESP32-WROVER-KIT v3, ST7789V controller, 240x320
2.4" 240x320 ILI9341 conroller with Touch panel from eBay
3.5" 320x480 ILI9488 controller with Touch panel from BuyDisplay
1.8" 128x160 ST7735 conroller from eBay