Example Programs

320x240 Example Programs

These examples run on a ESP32 board with a 320x240 display. They are were tested using a SparkFun ESP32 Thing and a Waveshare 2 inch LCD ST7789 Module. You may need to modify the pin use for your device.

320x240 lines.py

 1"""
 2lines.py
 3
 4    Draws lines and rectangles in random colors at random locations on the
 5    display.
 6
 7"""
 8import random
 9from machine import Pin, SPI
10import st7789py as st7789
11
12
13def main():
14    # configure display
15
16    spi = SPI(1, baudrate=31250000, sck=Pin(18), mosi=Pin(19))
17
18    tft = st7789.ST7789(
19        spi,
20        320,
21        240,
22        reset=Pin(4, Pin.OUT),
23        cs=Pin(13, Pin.OUT),
24        dc=Pin(12, Pin.OUT),
25        backlight=Pin(15, Pin.OUT),
26        rotation=0)
27
28    tft.fill(st7789.BLUE)
29
30    while True:
31        tft.line(
32            random.randint(0, tft.width),
33            random.randint(0, tft.height),
34            random.randint(0, tft.width),
35            random.randint(0, tft.height),
36            st7789.color565(
37                random.getrandbits(8),
38                random.getrandbits(8),
39                random.getrandbits(8)
40                )
41            )
42
43        width = random.randint(0, tft.width // 2)
44        height = random.randint(0, tft.height // 2)
45        col = random.randint(0, tft.width - width)
46        row = random.randint(0, tft.height - height)
47        tft.fill_rect(
48            col,
49            row,
50            width,
51            height,
52            st7789.color565(
53                random.getrandbits(8),
54                random.getrandbits(8),
55                random.getrandbits(8)
56            )
57        )
58
59
60main()

320x240 hello.py

 1"""
 2hello.py
 3
 4    Writes "Hello!" in random colors at random locations on the display.
 5
 6"""
 7import random
 8from machine import Pin, SPI
 9import st7789py as st7789
10
11# Choose a font
12
13# from romfonts import vga1_8x8 as font
14# from romfonts import vga2_8x8 as font
15# from romfonts import vga1_8x16 as font
16# from romfonts import vga2_8x16 as font
17# from romfonts import vga1_16x16 as font
18# from romfonts import vga1_bold_16x16 as font
19# from romfonts import vga2_16x16 as font
20# from romfonts import vga2_bold_16x16 as font
21# from romfonts import vga1_16x32 as font
22# from romfonts import vga1_bold_16x32 as font
23# from romfonts import vga2_16x32 as font
24from romfonts import vga2_bold_16x32 as font
25
26
27def main():
28    spi = SPI(1, baudrate=31250000, sck=Pin(18), mosi=Pin(19))
29
30    tft = st7789.ST7789(
31        spi,
32        320,
33        240,
34        reset=Pin(4, Pin.OUT),
35        cs=Pin(13, Pin.OUT),
36        dc=Pin(12, Pin.OUT),
37        backlight=Pin(15, Pin.OUT),
38        rotation=0)
39
40    while True:
41        for rotation in range(4):
42            tft.rotation(rotation)
43            tft.fill(0)
44            col_max = tft.width - font.WIDTH*6
45            row_max = tft.height - font.HEIGHT
46
47            for _ in range(100):
48                tft.text(
49                    font,
50                    "Hello!",
51                    random.randint(0, col_max),
52                    random.randint(0, row_max),
53                    st7789.color565(
54                        random.getrandbits(8),
55                        random.getrandbits(8),
56                        random.getrandbits(8)),
57                    st7789.color565(
58                        random.getrandbits(8),
59                        random.getrandbits(8),
60                        random.getrandbits(8))
61                )
62
63
64main()

320x240 feathers.py

  1"""
  2feathers.py
  3
  4    Smoothly scroll mirrored rainbow colored random curves across the display.
  5
  6"""
  7
  8import random
  9import math
 10import utime
 11from machine import Pin, SPI
 12import st7789py as st7789
 13
 14
 15def between(left, right, along):
 16    """returns a point along the curve from left to right"""
 17    dist = (1 - math.cos(along * math.pi)) / 2
 18    return left * (1 - dist) + right * dist
 19
 20
 21def color_wheel(position):
 22    """returns a 565 color from the given position of the color wheel"""
 23    position = (255 - position) % 255
 24
 25    if position < 85:
 26        return st7789.color565(255 - position * 3, 0, position * 3)
 27
 28    if position < 170:
 29        position -= 85
 30        return st7789.color565(0, position * 3, 255 - position * 3)
 31
 32    position -= 170
 33    return st7789.color565(position * 3, 255 - position * 3, 0)
 34
 35
 36def main():
 37    '''
 38    The big show!
 39    '''
 40    #enable display and clear screen
 41
 42    spi = SPI(1, baudrate=31250000, sck=Pin(18), mosi=Pin(19))
 43
 44    tft = st7789.ST7789(
 45        spi,
 46        320,
 47        240,
 48        reset=Pin(4, Pin.OUT),
 49        cs=Pin(13, Pin.OUT),
 50        dc=Pin(12, Pin.OUT),
 51        backlight=Pin(15, Pin.OUT),
 52        rotation=1)
 53
 54    tft.fill(st7789.BLACK)      # clear screen
 55
 56    height = tft.height         # height of display in pixels
 57    width = tft.width           # width if display in pixels
 58
 59    tfa = 0                     # top free area when scrolling
 60    bfa = 0         	        # bottom free area when scrolling
 61
 62    scroll = 0                  # scroll position
 63    wheel = 0                   # color wheel position
 64
 65    tft.vscrdef(tfa, width, bfa)    # set scroll area
 66    tft.vscsad(scroll + tfa)        # set scroll position
 67    tft.fill(st7789.BLACK)          # clear screen
 68
 69    half = (height >> 1) - 1    # half the height of the dislay
 70    interval = 0                # steps between new points
 71    increment = 0               # increment per step
 72    counter = 1                 # step counter, overflow to start
 73    current_y = 0               # current_y value (right point)
 74    last_y = 0                  # last_y value (left point)
 75
 76    # segment offsets
 77    x_offsets = [x * (width // 8) -1 for x in range(2,9)]
 78
 79    while True:
 80        # when the counter exceeds the interval, save current_y to last_y,
 81        # choose a new random value for current_y between 0 and 1/2 the
 82        # height of the display, choose a new random interval then reset
 83        # the counter to 0
 84
 85        if counter > interval:
 86            last_y = current_y
 87            current_y = random.randint(0, half)
 88            counter = 0
 89            interval = random.randint(10, 100)
 90            increment = 1/interval      # increment per step
 91
 92        # clear the first column of the display and scroll it
 93        tft.vline(scroll, 0, height, st7789.BLACK)
 94        tft.vscsad(scroll + tfa)
 95
 96        # get the next point between last_y and current_y
 97        tween = int(between(last_y, current_y, counter * increment))
 98
 99        # draw mirrored pixels across the display at the offsets using the color_wheel effect
100        for i, x_offset in enumerate(x_offsets):
101            tft.pixel((scroll + x_offset) % width, half + tween, color_wheel(wheel+(i<<2)))
102            tft.pixel((scroll + x_offset) % width, half - tween, color_wheel(wheel+(i<<2)))
103
104        # increment scroll, counter, and wheel
105        scroll = (scroll + 1) % width
106        wheel = (wheel + 1) % 256
107        counter += 1
108
109
110main()

320x240 fonts.py

 1"""
 2fonts.py
 3
 4    Pages through all characters of four fonts on the display.
 5
 6"""
 7import utime
 8from machine import Pin, SPI
 9import st7789py as st7789
10
11# Choose fonts
12
13# from romfonts import vga1_8x8 as font
14from romfonts import vga2_8x8 as font1
15# from romfonts import vga1_8x16 as font
16from romfonts import vga2_8x16 as font2
17# from romfonts import vga1_16x16 as font
18# from romfonts import vga1_bold_16x16 as font
19# from romfonts import vga2_16x16 as font
20from romfonts import vga2_bold_16x16 as font3
21# from romfonts import vga1_16x32 as font
22# from romfonts import vga1_bold_16x32 as font
23# from romfonts import vga2_16x32 as font
24from romfonts import vga2_bold_16x32 as font4
25
26
27def main():
28    spi = SPI(1, baudrate=31250000, sck=Pin(18), mosi=Pin(19))
29
30    tft = st7789.ST7789(
31        spi,
32        320,
33        240,
34        reset=Pin(4, Pin.OUT),
35        cs=Pin(13, Pin.OUT),
36        dc=Pin(12, Pin.OUT),
37        backlight=Pin(15, Pin.OUT),
38        rotation=0)
39
40    tft.vscrdef(40, 240, 40)
41
42    while True:
43        for font in (font1, font2, font3, font4):
44            tft.fill(st7789.BLUE)
45            line = 0
46            col = 0
47
48            for char in range(font.FIRST, font.LAST):
49                tft.text(font, chr(char), col, line, st7789.WHITE, st7789.BLUE)
50                col += font.WIDTH
51                if col > tft.width - font.WIDTH:
52                    col = 0
53                    line += font.HEIGHT
54
55                    if line > tft.height-font.HEIGHT:
56                        utime.sleep(3)
57                        tft.fill(st7789.BLUE)
58                        line = 0
59                        col = 0
60
61            utime.sleep(3)
62
63
64main()

320x240 scroll.py

 1"""
 2fonts.py
 3
 4    Smoothly scrolls all font characters up the screen on the display.
 5    Only works with fonts with heights that are even multiples of
 6    the screen height, (i.e. 8 or 16 pixels high)
 7
 8"""
 9import utime
10import random
11from machine import Pin, SPI
12import st7789py as st7789
13
14# choose a font
15
16# from romfonts import vga1_8x8 as font
17# from romfonts import vga2_8x8 as font
18# from romfonts import vga1_8x16 as font
19# from romfonts import vga2_8x16 as font
20# from romfonts import vga1_16x16 as font
21# from romfonts import vga1_bold_16x16 as font
22# from romfonts import vga2_16x16 as font
23from romfonts import vga2_bold_16x16 as font
24
25
26def main():
27    spi = SPI(1, baudrate=31250000, sck=Pin(18), mosi=Pin(19))
28
29    tft = st7789.ST7789(
30        spi,
31        320,
32        240,
33        reset=Pin(4, Pin.OUT),
34        cs=Pin(13, Pin.OUT),
35        dc=Pin(12, Pin.OUT),
36        backlight=Pin(15, Pin.OUT),
37        rotation=0)
38
39    last_line = tft.height - font.HEIGHT
40    tfa = 0
41    tfb = 0
42    tft.vscrdef(tfa, 240, tfb)
43
44    tft.fill(st7789.BLUE)
45    scroll = 0
46    character = 0
47    while True:
48        tft.fill_rect(0, scroll, tft.width, 1, st7789.BLUE)
49
50        if scroll % font.HEIGHT == 0:
51            tft.text(
52                font,
53                '\\x{:02x}= {:s} '.format(character, chr(character)),
54                0,
55                (scroll + last_line) % tft.height,
56                st7789.WHITE,
57                st7789.BLUE)
58
59            character = character + 1 if character < 256 else 0
60
61        tft.vscsad(scroll + tfa)
62        scroll += 1
63
64        if scroll == tft.height:
65            scroll = 0
66
67        utime.sleep(0.01)
68
69
70main()

320x240 toasters.py

Flying toasters sprite demo using bitmaps created from spritesheet using the sprites2bitmap.py utility. See the maketoast shell script for the command line used to create the toast_bitmaps.py from the toasters.bmp image.

  1'''
  2toasters.py - Flying Toasters(ish) an ESP-32 and ST7789 240x320 display.
  3
  4    Uses spritesheet from CircuitPython_Flying_Toasters pendant project
  5    https://learn.adafruit.com/circuitpython-sprite-animation-pendant-mario-clouds-flying-toasters
  6
  7    Convert spritesheet bmp to tft.bitmap() method compatible python module using:
  8        python3 ./sprites2bitmap.py toasters.bmp 64 64 4 > toast_bitmaps.py
  9
 10'''
 11
 12import gc
 13import time
 14import random
 15from machine import Pin, SPI
 16import st7789
 17import toast_bitmaps
 18
 19TOASTER_FRAMES = [0, 1, 2, 3]
 20TOAST_FRAMES = [4]
 21
 22def collide(a_col, a_row, a_width, a_height, b_col, b_row, b_width, b_height):
 23    '''return true if two rectangles overlap'''
 24    return (a_col + a_width >= b_col and a_col <= b_col + b_width
 25            and a_row + a_height >= b_row and a_row <= b_row + b_height)
 26
 27def random_start(tft, sprites, bitmaps, num):
 28    '''
 29    Return a random location along the top or right of the screen, if that location would overlaps
 30    with another sprite return (0,0). This allows the other sprites to keep moving giving the next
 31    random_start a better chance to avoid a collision.
 32
 33    '''
 34    # 50/50 chance to try along the top/right half or along the right/top half of the screen
 35    if random.getrandbits(1):
 36        row = 1
 37        col = random.randint(bitmaps.WIDTH//2, tft.width()-bitmaps.WIDTH)
 38    else:
 39        col = tft.width() - bitmaps.WIDTH
 40        row = random.randint(1, tft.height() // 2)
 41
 42    if any(collide(
 43        col, row, bitmaps.WIDTH, bitmaps.HEIGHT,
 44        sprite.col, sprite.row, sprite.width, sprite.height)
 45        for sprite in sprites if num != sprite.num):
 46
 47        col = 0
 48        row = 0
 49
 50    return (col, row)
 51
 52def main():
 53
 54    class Toast():
 55        '''
 56        Toast class to keep track of toaster and toast sprites
 57        '''
 58        def __init__(self, sprites, bitmaps, frames):
 59            '''create new sprite in random location that does not overlap other sprites'''
 60            self.num = len(sprites)
 61            self.bitmaps = bitmaps
 62            self.frames = frames
 63            self.steps = len(frames)
 64            self.col, self.row  = random_start(tft, sprites, bitmaps, self.num)
 65            self.width = bitmaps.WIDTH
 66            self.height = bitmaps.HEIGHT
 67            self.last_col = self.col
 68            self.last_row = self.row
 69            self.step = random.randint(0, self.steps)
 70            self.dir_col = -random.randint(2, 5)
 71            self.dir_row = 2
 72            self.prev_dir_col = self.dir_col
 73            self.prev_dir_row = self.dir_row
 74            self.iceberg = 0
 75
 76        def clear(self):
 77            '''clear above and behind sprite'''
 78            tft.fill_rect(
 79                self.col, self.row-1, self.width, self.dir_row+1,
 80                st7789.BLACK)
 81
 82            tft.fill_rect(
 83                self.col+self.width+self.dir_col, self.row,
 84                -self.dir_col, self.height, st7789.BLACK)
 85
 86        def erase(self):
 87            '''erase last postion of sprite'''
 88            tft.fill_rect(
 89                self.last_col, self.last_row, self.width, self.height, st7789.BLACK)
 90
 91        def move(self, sprites):
 92            '''step frame and move sprite'''
 93
 94            if self.steps:
 95                self.step = (self.step + 1) % self.steps
 96
 97            self.last_col = self.col
 98            self.last_row = self.row
 99            new_col = self.col + self.dir_col
100            new_row = self.row + self.dir_row
101
102            # if new location collides with another sprite, change direction for 32 frames
103
104            for sprite in sprites:
105                if (
106                    self.num != sprite.num
107                    and collide(
108                        new_col, new_row, self.width, self.height,
109                        sprite.col, sprite.row, sprite.width, sprite.height,
110                    )
111                    and (self.col > sprite.col)):
112
113                    self.iceberg = 32
114                    self.dir_col = -1
115                    self.dir_row = 3
116                    new_col = self.col + self.dir_col
117                    new_row = self.row + self.dir_row
118
119            self.col = new_col
120            self.row = new_row
121
122            # if new location touches edge of screen, erase then set new start location
123            if self.col <= 0 or self.row > tft.height() - self.height:
124                self.erase()
125                self.dir_col = -random.randint(2, 5)
126                self.dir_row = 2
127                self.col, self.row  = random_start(tft, sprites, self.bitmaps, self.num)
128
129            # Track post collision direction change
130            if self.iceberg:
131                self.iceberg -= 1
132                if self.iceberg == 1:
133                    self.dir_col = self.prev_dir_col
134                    self.dir_row = self.prev_dir_row
135
136        def draw(self):
137            '''if the location is not 0,0 draw current frame of sprite at it's location'''
138            if self.col and self.row:
139                tft.bitmap(self.bitmaps, self.col, self.row, self.frames[self.step])
140
141    # configure spi interface
142    spi = SPI(1, baudrate=31250000, sck=Pin(18), mosi=Pin(19))
143
144    # configure display
145    tft = st7789.ST7789(
146        spi,
147        240,
148        320,
149        reset=Pin(4, Pin.OUT),
150        cs=Pin(13, Pin.OUT),
151        dc=Pin(12, Pin.OUT),
152        backlight=Pin(15, Pin.OUT),
153        rotation=1,
154        buffer_size=64*62*2)
155
156    # init and clear screen
157    tft.init()
158    tft.fill(st7789.BLACK)
159
160    # create toast spites and set animation frames
161    sprites = []
162    sprites.append(Toast(sprites, toast_bitmaps, TOAST_FRAMES))
163    sprites.append(Toast(sprites, toast_bitmaps, TOASTER_FRAMES))
164    sprites.append(Toast(sprites, toast_bitmaps, TOASTER_FRAMES))
165
166    # move and draw sprites
167
168    while True:
169        for sprite in sprites:
170            sprite.clear()
171            sprite.move(sprites)
172            sprite.draw()
173
174        gc.collect()
175        time.sleep(0.01)
176
177main()

135x240 TTGO T-Display Example Programs

These examples run on the LilyGo TTGO-T-Display available from the usual locations. See https://github.com/Xinyuan-LilyGO/TTGO-T-Display for more information.

lines.py

 1"""
 2lines.py
 3
 4    Draws lines and rectangles in random colors at random locations on the
 5    display.
 6
 7"""
 8import random
 9from machine import Pin, SoftSPI
10import st7789py as st7789
11
12
13def main():
14    spi = SoftSPI(
15        baudrate=20000000,
16        polarity=1,
17        phase=0,
18        sck=Pin(18),
19        mosi=Pin(19),
20        miso=Pin(13))
21
22    tft = st7789.ST7789(
23        spi,
24        135,
25        240,
26        reset=Pin(23, Pin.OUT),
27        cs=Pin(5, Pin.OUT),
28        dc=Pin(16, Pin.OUT),
29        backlight=Pin(4, Pin.OUT),
30        rotation=0)
31
32    tft.fill(st7789.BLACK)
33
34    while True:
35        tft.line(
36            random.randint(0, tft.width),
37            random.randint(0, tft.height),
38            random.randint(0, tft.width),
39            random.randint(0, tft.height),
40            st7789.color565(
41                random.getrandbits(8),
42                random.getrandbits(8),
43                random.getrandbits(8)
44                )
45            )
46
47        width = random.randint(0, tft.width // 2)
48        height = random.randint(0, tft.height // 2)
49        col = random.randint(0, tft.width - width)
50        row = random.randint(0, tft.height - height)
51        tft.fill_rect(
52            col,
53            row,
54            width,
55            height,
56            st7789.color565(
57                random.getrandbits(8),
58                random.getrandbits(8),
59                random.getrandbits(8)
60            )
61        )
62
63
64main()

hello.py

 1"""
 2hello.py
 3
 4    Writes "Hello!" in random colors at random locations on a
 5    LILYGO® TTGO T-Display.
 6
 7    https://www.youtube.com/watch?v=atBa0BYPAAc
 8
 9"""
10import random
11from machine import Pin, SoftSPI
12import st7789py as st7789
13
14# Choose a font
15
16# from romfonts import vga1_8x8 as font
17# from romfonts import vga2_8x8 as font
18# from romfonts import vga1_8x16 as font
19# from romfonts import vga2_8x16 as font
20# from romfonts import vga1_16x16 as font
21# from romfonts import vga1_bold_16x16 as font
22# from romfonts import vga2_16x16 as font
23# from romfonts import vga2_bold_16x16 as font
24# from romfonts import vga1_16x32 as font
25# from romfonts import vga1_bold_16x32 as font
26# from romfonts import vga2_16x32 as font
27from romfonts import vga2_bold_16x32 as font
28
29
30def main():
31    spi = SoftSPI(
32        baudrate=20000000,
33        polarity=1,
34        phase=0,
35        sck=Pin(18),
36        mosi=Pin(19),
37        miso=Pin(13))
38
39    tft = st7789.ST7789(
40        spi,
41        135,
42        240,
43        reset=Pin(23, Pin.OUT),
44        cs=Pin(5, Pin.OUT),
45        dc=Pin(16, Pin.OUT),
46        backlight=Pin(4, Pin.OUT),
47        rotation=0)
48
49    while True:
50        for rotation in range(4):
51            tft.rotation(rotation)
52            tft.fill(0)
53            col_max = tft.width - font.WIDTH*6
54            row_max = tft.height - font.HEIGHT
55
56            for _ in range(100):
57                tft.text(
58                    font,
59                    "Hello!",
60                    random.randint(0, col_max),
61                    random.randint(0, row_max),
62                    st7789.color565(
63                        random.getrandbits(8),
64                        random.getrandbits(8),
65                        random.getrandbits(8)),
66                    st7789.color565(
67                        random.getrandbits(8),
68                        random.getrandbits(8),
69                        random.getrandbits(8))
70                )
71
72
73main()

feathers.py

  1"""
  2feathers.py
  3
  4    Smoothly scroll mirrored rainbow colored random curves across the display.
  5
  6"""
  7
  8import random
  9import math
 10import utime
 11from machine import Pin, SoftSPI
 12import st7789py as st7789
 13
 14
 15def between(left, right, along):
 16    """returns a point along the curve from left to right"""
 17    dist = (1 - math.cos(along * math.pi)) / 2
 18    return left * (1 - dist) + right * dist
 19
 20
 21def color_wheel(position):
 22    """returns a 565 color from the given position of the color wheel"""
 23    position = (255 - position) % 255
 24
 25    if position < 85:
 26        return st7789.color565(255 - position * 3, 0, position * 3)
 27
 28    if position < 170:
 29        position -= 85
 30        return st7789.color565(0, position * 3, 255 - position * 3)
 31
 32    position -= 170
 33    return st7789.color565(position * 3, 255 - position * 3, 0)
 34
 35
 36def main():
 37    '''
 38    The big show!
 39    '''
 40    #enable display and clear screen
 41
 42    spi = SoftSPI(
 43        baudrate=20000000,
 44        polarity=1,
 45        phase=0,
 46        sck=Pin(18),
 47        mosi=Pin(19),
 48        miso=Pin(13))
 49
 50    tft = st7789.ST7789(
 51        spi,
 52        135,
 53        240,
 54        reset=Pin(23, Pin.OUT),
 55        cs=Pin(5, Pin.OUT),
 56        dc=Pin(16, Pin.OUT),
 57        backlight=Pin(4, Pin.OUT),
 58        rotation=1)
 59
 60    tft.fill(st7789.BLACK)      # clear screen
 61
 62    height = tft.height         # height of display in pixels
 63    width = tft.width           # width if display in pixels
 64
 65    tfa = 40                    # top free area when scrolling
 66    bfa = 40        	        # bottom free area when scrolling
 67
 68    scroll = 0                  # scroll position
 69    wheel = 0                   # color wheel position
 70
 71    tft.vscrdef(tfa, width, bfa)    # set scroll area
 72    tft.vscsad(scroll + tfa)        # set scroll position
 73    tft.fill(st7789.BLACK)          # clear screen
 74
 75    half = (height >> 1) - 1    # half the height of the dislay
 76    interval = 0                # steps between new points
 77    increment = 0               # increment per step
 78    counter = 1                 # step counter, overflow to start
 79    current_y = 0               # current_y value (right point)
 80    last_y = 0                  # last_y value (left point)
 81
 82    # segment offsets
 83    x_offsets = [x * (width // 8) -1 for x in range(2,9)]
 84
 85    while True:
 86        # when the counter exceeds the interval, save current_y to last_y,
 87        # choose a new random value for current_y between 0 and 1/2 the
 88        # height of the display, choose a new random interval then reset
 89        # the counter to 0
 90
 91        if counter > interval:
 92            last_y = current_y
 93            current_y = random.randint(0, half)
 94            counter = 0
 95            interval = random.randint(10, 100)
 96            increment = 1/interval      # increment per step
 97
 98        # clear the first column of the display and scroll it
 99        tft.vline(scroll, 0, height, st7789.BLACK)
100        tft.vscsad(scroll + tfa)
101
102        # get the next point between last_y and current_y
103        tween = int(between(last_y, current_y, counter * increment))
104
105        # draw mirrored pixels across the display at the offsets using the color_wheel effect
106        for i, x_offset in enumerate(x_offsets):
107            tft.pixel((scroll + x_offset) % width, half + tween, color_wheel(wheel+(i<<2)))
108            tft.pixel((scroll + x_offset) % width, half - tween, color_wheel(wheel+(i<<2)))
109
110        # increment scroll, counter, and wheel
111        scroll = (scroll + 1) % width
112        wheel = (wheel + 1) % 256
113        counter += 1
114
115
116main()

fonts.py

 1"""
 2fonts.py
 3
 4    Pages through all characters of four fonts on the LILYGO® TTGO T-Display.
 5
 6    https://www.youtube.com/watch?v=2cnAhEucPD4
 7
 8"""
 9import utime
10from machine import Pin, SoftSPI
11import st7789py as st7789
12
13# Choose fonts
14
15# from romfonts import vga1_8x8 as font
16from romfonts import vga2_8x8 as font1
17# from romfonts import vga1_8x16 as font
18from romfonts import vga2_8x16 as font2
19# from romfonts import vga1_16x16 as font
20# from romfonts import vga1_bold_16x16 as font
21# from romfonts import vga2_16x16 as font
22from romfonts import vga2_bold_16x16 as font3
23# from romfonts import vga1_16x32 as font
24# from romfonts import vga1_bold_16x32 as font
25# from romfonts import vga2_16x32 as font
26from romfonts import vga2_bold_16x32 as font4
27
28
29def main():
30    spi = SoftSPI(
31        baudrate=20000000,
32        polarity=1,
33        phase=0,
34        sck=Pin(18),
35        mosi=Pin(19),
36        miso=Pin(13))
37
38    tft = st7789.ST7789(
39        spi,
40        135,
41        240,
42        reset=Pin(23, Pin.OUT),
43        cs=Pin(5, Pin.OUT),
44        dc=Pin(16, Pin.OUT),
45        backlight=Pin(4, Pin.OUT),
46        rotation=0)
47
48    tft.vscrdef(40, 240, 40)
49
50    while True:
51        for font in (font1, font2, font3, font4):
52            tft.fill(st7789.BLUE)
53            line = 0
54            col = 0
55
56            for char in range(font.FIRST, font.LAST):
57                tft.text(font, chr(char), col, line, st7789.WHITE, st7789.BLUE)
58                col += font.WIDTH
59                if col > tft.width - font.WIDTH:
60                    col = 0
61                    line += font.HEIGHT
62
63                    if line > tft.height-font.HEIGHT:
64                        utime.sleep(3)
65                        tft.fill(st7789.BLUE)
66                        line = 0
67                        col = 0
68
69            utime.sleep(3)
70
71
72main()

scroll.py

 1"""
 2scroll.py
 3
 4    Smoothly scrolls all font characters up the screen on the LILYGO® TTGO
 5    T-Display. Only works with fonts with heights that are even multiples of
 6    the screen height, (i.e. 8 or 16 pixels high)
 7
 8"""
 9import utime
10import random
11from machine import Pin, SoftSPI
12import st7789py as st7789
13
14# choose a font
15
16# from romfonts import vga1_8x8 as font
17# from romfonts import vga2_8x8 as font
18# from romfonts import vga1_8x16 as font
19# from romfonts import vga2_8x16 as font
20# from romfonts import vga1_16x16 as font
21# from romfonts import vga1_bold_16x16 as font
22# from romfonts import vga2_16x16 as font
23from romfonts import vga2_bold_16x16 as font
24
25
26def main():
27    spi = SoftSPI(
28        baudrate=20000000,
29        polarity=1,
30        phase=0,
31        sck=Pin(18),
32        mosi=Pin(19),
33        miso=Pin(13))
34
35    tft = st7789.ST7789(
36        spi,
37        135,
38        240,
39        reset=Pin(23, Pin.OUT),
40        cs=Pin(5, Pin.OUT),
41        dc=Pin(16, Pin.OUT),
42        backlight=Pin(4, Pin.OUT),
43        rotation=0)
44
45    last_line = tft.height - font.HEIGHT
46    tfa = 40
47    tfb = 40
48    tft.vscrdef(tfa, 240, tfb)
49
50    tft.fill(st7789.BLUE)
51    scroll = 0
52    character = 0
53    while True:
54        tft.fill_rect(0, scroll, tft.width, 1, st7789.BLUE)
55
56        if scroll % font.HEIGHT == 0:
57            tft.text(
58                font,
59                '\\x{:02x}= {:s} '.format(character, chr(character)),
60                0,
61                (scroll + last_line) % tft.height,
62                st7789.WHITE,
63                st7789.BLUE)
64
65            character = character + 1 if character < 256 else 0
66
67        tft.vscsad(scroll + tfa)
68        scroll += 1
69
70        if scroll == tft.height:
71            scroll = 0
72
73        utime.sleep(0.01)
74
75
76main()

toasters.py

Flying toasters sprite demo using bitmaps created from spritesheet using the imgtobitmap.py utility. See the maketoast script in the utils directory for details. See the 320x240 toasters example for a more advanced example that uses the sprites2bitmap utility and indexed bitmaps.

 1"""
 2toasters.py
 3
 4    An example using bitmap to draw sprites on the display.
 5
 6    Spritesheet from CircuitPython_Flying_Toasters
 7    https://learn.adafruit.com/circuitpython-sprite-animation-pendant-mario-clouds-flying-toasters
 8
 9"""
10
11import random
12from machine import Pin, SoftSPI
13import st7789py as st7789
14import t1, t2, t3, t4, t5
15
16TOASTERS = [t1, t2, t3, t4]
17TOAST = [t5]
18
19
20class toast():
21    '''
22    toast class to keep track of a sprites locaton and step
23    '''
24    def __init__(self, sprites, x, y):
25        self.sprites = sprites
26        self.steps = len(sprites)
27        self.x = x
28        self.y = y
29        self.step = random.randint(0, self.steps-1)
30        self.speed = random.randint(2, 5)
31
32    def move(self):
33        if self.x <= 0:
34            self.speed = random.randint(2, 5)
35            self.x = 135 - 64
36
37        self.step += 1
38        self.step %= self.steps
39        self.x -= self.speed
40
41
42def main():
43    """
44    Initialize the display and draw flying toasters and toast
45    """
46    spi = SoftSPI(
47        baudrate=20000000,
48        polarity=1,
49        phase=0,
50        sck=Pin(18),
51        mosi=Pin(19),
52        miso=Pin(13))
53
54    tft = st7789.ST7789(
55        spi,
56        135,
57        240,
58        reset=Pin(23, Pin.OUT),
59        cs=Pin(5, Pin.OUT),
60        dc=Pin(16, Pin.OUT),
61        backlight=Pin(4, Pin.OUT),
62        rotation=0)
63
64    tft.fill(st7789.BLACK)
65    # create toast spites in random positions
66    sprites = [
67        toast(TOASTERS, 135-64, 0),
68        toast(TOAST, 135-64*2, 80),
69        toast(TOASTERS, 135-64*4, 160)
70    ]
71
72    # move and draw sprites
73    while True:
74        for man in sprites:
75            bitmap = man.sprites[man.step]
76            tft.fill_rect(
77                man.x+bitmap.WIDTH-man.speed,
78                man.y,
79                man.speed,
80                bitmap.HEIGHT,
81                st7789.BLACK)
82
83            man.move()
84
85            if man.x > 0:
86                tft.bitmap(bitmap, man.x, man.y)
87            else:
88                tft.fill_rect(
89                    0,
90                    man.y,
91                    bitmap.WIDTH,
92                    bitmap.HEIGHT,
93                    st7789.BLACK)
94
95
96main()

chango.py

Test for font2bitmap converter for the driver. See the font2bitmap program in the utils directory.

 1"""
 2chango.py
 3
 4    Test for font2bitmap converter for the driver.
 5    See the font2bitmap program in the utils directory.
 6"""
 7
 8from machine import Pin, SoftSPI
 9import st7789py as st7789
10import gc
11from truetype import chango_16 as font_16
12from truetype import chango_32 as font_32
13from truetype import chango_64 as font_64
14
15gc.collect()
16
17
18def main():
19    # enable display and clear screen
20    spi = SoftSPI(
21        baudrate=20000000,
22        polarity=1,
23        phase=0,
24        sck=Pin(18),
25        mosi=Pin(19),
26        miso=Pin(13))
27
28    tft = st7789.ST7789(
29        spi,
30        135,
31        240,
32        reset=Pin(23, Pin.OUT),
33        cs=Pin(5, Pin.OUT),
34        dc=Pin(16, Pin.OUT),
35        backlight=Pin(4, Pin.OUT),
36        rotation=1)
37
38    tft.fill(st7789.BLACK)
39
40    row = 0
41    tft.write(font_16, "abcdefghijklmnopqrst", 0, row, st7789.RED)
42    row += font_16.HEIGHT
43
44    tft.write(font_32, "abcdefghij", 0, row, st7789.GREEN)
45    row += font_32.HEIGHT
46
47    tft.write(font_64, "abcd", 0, row, st7789.BLUE)
48    row += font_64.HEIGHT
49
50
51main()

noto_fonts.py

Test for font2bitmap converter for the driver. See the font2bitmap program in the utils directory.

 1"""
 2noto_fonts Writes the names of three Noto fonts centered on the display
 3    using the font. The fonts were converted from True Type fonts using
 4    the font2bitmap utility.
 5"""
 6
 7from machine import SoftSPI, Pin
 8import st7789py as st7789
 9
10from truetype import NotoSans_32 as noto_sans
11from truetype import NotoSerif_32 as noto_serif
12from truetype import NotoSansMono_32 as noto_mono
13
14
15def main():
16
17    def center(font, string, row, color=st7789.WHITE):
18        screen = tft.width                        # get screen width
19        width = tft.write_width(font, string)     # get the width of the string
20        if width and width < screen:              # if the string < display
21            col = tft.width // 2 - width // 2     # find the column to center
22        else:                                     # otherwise
23            col = 0                               # left justify
24
25        tft.write(font, string, col, row, color)  # and write the string
26
27    try:
28        spi = SoftSPI(
29            baudrate=20000000,
30            polarity=1,
31            phase=0,
32            sck=Pin(18),
33            mosi=Pin(19),
34            miso=Pin(13))
35
36        tft = st7789.ST7789(
37            spi,
38            135,
39            240,
40            reset=Pin(23, Pin.OUT),
41            cs=Pin(5, Pin.OUT),
42            dc=Pin(16, Pin.OUT),
43            backlight=Pin(4, Pin.OUT),
44            rotation=1)
45
46        # enable display and clear screen
47        tft.fill(st7789.BLACK)
48
49        row = 16
50
51        # center the name of the first font, using the font
52        center(noto_sans, "NotoSans", row, st7789.RED)
53        row += noto_sans.HEIGHT
54
55        # center the name of the second font, using the font
56        center(noto_serif, "NotoSerif", row, st7789.GREEN)
57        row += noto_serif.HEIGHT
58
59        # center the name of the third font, using the font
60        center(noto_mono, "NotoSansMono", row, st7789.BLUE)
61        row += noto_mono.HEIGHT
62
63    finally:
64        # shutdown spi
65        if 'spi' in locals():
66            spi.deinit()
67
68
69main()