Tuesday, May 10, 2022

CircuitPython display cursor on displayio, work on Raspberry Pi Pico/ST7789 SPI Display.

CircuitPython exercise run on Raspberry Pi Pico + 240x240 ST7789 SPI RGB Display, to display cursor on displayio.


Libraries needed:
- adafruit_cursorcontrol folder
- adafruit_display_text folder
- adafruit_st7789.mpy


Code:

cpyPico_st7789_240_cursor_mapping.py
cursor position are mapped to variable resistor position.

"""
Example of CircuitPython/RaspberryPi Pico
+ 240x240 ST7789 SPI RGB screen.
display cursor on displayio.

cursor position are mapped to variable resistor position

using adafruit_cursorcontrol.cursorcontrol
https://docs.circuitpython.org/projects/cursorcontrol/en/latest/api.html

Connection between Pico and
the IPS screen, with ST7789 SPI interface.
3V3  - BLK (backlight, always on)
GP11 - CS
GP12 - DC
GP13 - RES
GP15 - SDA
GP14 - SCL
3V3  - VCC
GND  - GND

AnalogIn GP26_A0 connect to variable resistor for Y
AnalogIn GP26_A1 connect to variable resistor for X
"""

import os
import sys
import board
import time
import terminalio
import displayio
import busio
from adafruit_display_text import label
import adafruit_st7789
import adafruit_cursorcontrol.cursorcontrol
from analogio import AnalogIn

print("=====================================")
info = sys.implementation[0] + ' ' + \
       os.uname()[3] + '\n' + \
       'run on ' + os.uname()[4]
print(info)
print("=====================================")
print(adafruit_st7789.__name__ + " version: " +
      adafruit_st7789.__version__)
print(adafruit_cursorcontrol.cursorcontrol.__name__
      + " version: "
      + adafruit_cursorcontrol.cursorcontrol.__version__)
print()

analog_A0 = AnalogIn(board.GP26_A0)
analog_A1 = AnalogIn(board.GP27_A1)

# Release any resources currently in use for the displays
displayio.release_displays()

tft_cs = board.GP11
tft_dc = board.GP12
tft_res = board.GP13
spi_mosi = board.GP15
spi_clk = board.GP14

display_width = 240
display_height = 240

"""
classbusio.SPI(clock: microcontroller.Pin,
                MOSI: Optional[microcontroller.Pin] = None,
                MISO: Optional[microcontroller.Pin] = None)
"""
spi = busio.SPI(spi_clk, MOSI=spi_mosi)

display_bus = displayio.FourWire(
    spi, command=tft_dc, chip_select=tft_cs, reset=tft_res
)

display = adafruit_st7789.ST7789(display_bus,
                    width=display_width, height=display_height,
                    rowstart=80,
                    rotation=180)

# Make the display context
splash = displayio.Group()
display.show(splash)

color_bitmap = displayio.Bitmap(display_width, display_height, 1)
color_palette = displayio.Palette(1)
color_palette[0] = 0xA0A0A0

bg_sprite = displayio.TileGrid(color_bitmap,
                               pixel_shader=color_palette, x=0, y=0)
splash.append(bg_sprite)

# Draw a smaller inner rectangle
inner_bitmap = displayio.Bitmap(80, 180, 1)
inner_palette = displayio.Palette(1)
inner_palette[0] = 0x0000FF
inner_sprite = displayio.TileGrid(inner_bitmap,
                                  pixel_shader=inner_palette, x=20, y=20)
splash.append(inner_sprite)

info1 = sys.implementation[0] + ' ' + os.uname()[2]
info2 = 'run on ' + os.uname()[4]

# Draw labels for CircuitPython info
text_group1 = displayio.Group(scale=2, x=5, y=40)
text1 = info1
text_area1 = label.Label(terminalio.FONT, text=text1, color=0x000000)
text_group1.append(text_area1)  # Subgroup for text scaling
#
text_group2 = displayio.Group(scale=1, x=5, y=70)
text2 = info2
text_area2 = label.Label(terminalio.FONT, text=text2, color=0xFFFFFF)
text_group2.append(text_area2)  # Subgroup for text scaling

# Draw labels for adafruit_st7789
text_group3 = displayio.Group(scale=2, x=5, y=120)
text3 = adafruit_st7789.__name__
text_area3 = label.Label(terminalio.FONT, text=text3, color=0x000000)
text_group3.append(text_area3)  # Subgroup for text scaling
#
text_group4 = displayio.Group(scale=2, x=5, y=150)
text4 = adafruit_st7789.__version__
text_area4 = label.Label(terminalio.FONT, text=text4, color=0xFF0000)
text_group4.append(text_area4)  # Subgroup for text scaling

# Draw labels for adafruit_cursorcontrol.cursorcontrol
text_group5 = displayio.Group(scale=1, x=5, y=180)
text5 = adafruit_cursorcontrol.cursorcontrol.__name__
text_area5 = label.Label(terminalio.FONT, text=text5, color=0x000000)
text_group5.append(text_area5)  # Subgroup for text scaling
# 
text_group6 = displayio.Group(scale=2, x=5, y=210)
text6 = adafruit_cursorcontrol.cursorcontrol.__version__
text_area6 = label.Label(terminalio.FONT, text=text6, color=0x000000)
text_group6.append(text_area6)  # Subgroup for text scaling

splash.append(text_group1)
splash.append(text_group2)
splash.append(text_group3)
splash.append(text_group4)
splash.append(text_group5)
splash.append(text_group6)

# initialize the mouse cursor object
# place over all others
mouse_cursor = adafruit_cursorcontrol.cursorcontrol.Cursor(
    display, display_group=splash)

cnv_ratio = 240/65536

while True:
    mouse_cursor.x = (int)(analog_A1.value * cnv_ratio)
    mouse_cursor.y = (int)((64436-analog_A0.value) * cnv_ratio)
    
    time.sleep(0.05)
    
print("~ bye ~")
cpyPico_st7789_240_cursor_delta.py
variable resistor position control the cursor movement.


"""
Example of CircuitPython/RaspberryPi Pico
+ 240x240 ST7789 SPI RGB screen.
display cursor on displayio.

variable resistor position control the cursor movement.

Connection between Pico and
the IPS screen, with ST7789 SPI interface.
3V3  - BLK (backlight, always on)
GP11 - CS
GP12 - DC
GP13 - RES
GP15 - SDA
GP14 - SCL
3V3  - VCC
GND  - GND

AnalogIn GP26_A0 connect to variable resistor for Y
AnalogIn GP26_A1 connect to variable resistor for X
"""

import os
import sys
import board
import time
import terminalio
import displayio
import busio
from adafruit_display_text import label
import adafruit_st7789
import adafruit_cursorcontrol.cursorcontrol
from analogio import AnalogIn

print("=====================================")
info = sys.implementation[0] + ' ' + \
       os.uname()[3] + '\n' + \
       'run on ' + os.uname()[4]
print(info)
print("=====================================")
print(adafruit_st7789.__name__ + " version: " +
      adafruit_st7789.__version__)
print(adafruit_cursorcontrol.cursorcontrol.__name__
      + " version: "
      + adafruit_cursorcontrol.cursorcontrol.__version__)
print()

analog_A0 = AnalogIn(board.GP26_A0)
analog_A1 = AnalogIn(board.GP27_A1)

# Release any resources currently in use for the displays
displayio.release_displays()

tft_cs = board.GP11
tft_dc = board.GP12
tft_res = board.GP13
spi_mosi = board.GP15
spi_clk = board.GP14

display_width = 240
display_height = 240

"""
classbusio.SPI(clock: microcontroller.Pin,
                MOSI: Optional[microcontroller.Pin] = None,
                MISO: Optional[microcontroller.Pin] = None)
"""
spi = busio.SPI(spi_clk, MOSI=spi_mosi)

display_bus = displayio.FourWire(
    spi, command=tft_dc, chip_select=tft_cs, reset=tft_res
)

display = adafruit_st7789.ST7789(display_bus,
                    width=display_width, height=display_height,
                    rowstart=80,
                    rotation=180)

# Make the display context
splash = displayio.Group()
display.show(splash)

color_bitmap = displayio.Bitmap(display_width, display_height, 1)
color_palette = displayio.Palette(1)
color_palette[0] = 0xA0A0A0

bg_sprite = displayio.TileGrid(color_bitmap,
                               pixel_shader=color_palette, x=0, y=0)
splash.append(bg_sprite)

# Draw a smaller inner rectangle
inner_bitmap = displayio.Bitmap(50, 180, 1)
inner_palette = displayio.Palette(1)
inner_palette[0] = 0x0000FF
inner_sprite = displayio.TileGrid(inner_bitmap,
                                  pixel_shader=inner_palette, x=50, y=20)
#splash.append(inner_sprite)

info1 = sys.implementation[0] + ' ' + os.uname()[2]
info2 = 'run on ' + os.uname()[4]

# Draw labels for CircuitPython info
text_group1 = displayio.Group(scale=2, x=5, y=40)
text1 = info1
text_area1 = label.Label(terminalio.FONT, text=text1, color=0x000000)
text_group1.append(text_area1)  # Subgroup for text scaling
#
text_group2 = displayio.Group(scale=1, x=5, y=70)
text2 = info2
text_area2 = label.Label(terminalio.FONT, text=text2, color=0xFFFFFF)
text_group2.append(text_area2)  # Subgroup for text scaling

# Draw labels for adafruit_st7789
text_group3 = displayio.Group(scale=2, x=5, y=120)
text3 = adafruit_st7789.__name__
text_area3 = label.Label(terminalio.FONT, text=text3, color=0x000000)
text_group3.append(text_area3)  # Subgroup for text scaling
# 
text_group4 = displayio.Group(scale=2, x=5, y=150)
text4 = adafruit_st7789.__version__
text_area4 = label.Label(terminalio.FONT, text=text4, color=0xFF0000)
text_group4.append(text_area4)  # Subgroup for text scaling

# Draw labels for adafruit_cursorcontrol.cursorcontrol
text_group5 = displayio.Group(scale=1, x=5, y=180)
text5 = adafruit_cursorcontrol.cursorcontrol.__name__
text_area5 = label.Label(terminalio.FONT, text=text5, color=0x000000)
text_group5.append(text_area5)  # Subgroup for text scaling
#
text_group6 = displayio.Group(scale=2, x=5, y=210)
text6 = adafruit_cursorcontrol.cursorcontrol.__version__
text_area6 = label.Label(terminalio.FONT, text=text6, color=0x000000)
text_group6.append(text_area6)  # Subgroup for text scaling

splash.append(text_group1)
splash.append(text_group2)

# initialize the mouse cursor object
# place under inner_sprite, text_group3/4/5/6, and over all other
mouse_cursor = adafruit_cursorcontrol.cursorcontrol.Cursor(
    display, display_group=splash)

splash.append(inner_sprite)
splash.append(text_group3)
splash.append(text_group4)
splash.append(text_group5)
splash.append(text_group6)
"""
# initialize the mouse cursor object
mouse_cursor = adafruit_cursorcontrol.cursorcontrol.Cursor(
    display, display_group=splash)
"""
while True:
    offset_x = 0
    offset_y = 0
    delta_x = analog_A1.value-32768
    delta_y = analog_A0.value-32768
    
    if(delta_x >= 0):
        if delta_x > 30000:
            offset_x = 4
        elif delta_x > 20000:
            offset_x = 2
        elif delta_x > 10000:
            offset_x = 1
    else:
        if delta_x < -30000:
            offset_x = -4
        elif delta_x < -20000:
            offset_x = -2
        elif delta_x < -10000:
            offset_x = -1

    if(delta_y >= 0):
        if delta_y > 30000:
            offset_y = -4
        elif delta_y > 20000:
            offset_y = -2
        elif delta_y > 10000:
            offset_y = -1
    else:
        if delta_y < -30000:
            offset_y = 4
        elif delta_y < -20000:
            offset_y = 2
        elif delta_y < -10000:
            offset_y = 1
    
    mouse_cursor.x = mouse_cursor.x + offset_x
    mouse_cursor.y = mouse_cursor.y + offset_y
    
    time.sleep(0.05)
    
print("~ bye ~")
cpyPico_st7789_240_cursor_delta_bitmap.py
implement custom cursor bitmap.


"""
Example of CircuitPython/RaspberryPi Pico
+ 240x240 ST7789 SPI RGB screen.
display cursor on displayio.

example to apply custom bitmap for cursor

Connection between Pico and
the IPS screen, with ST7789 SPI interface.
3V3  - BLK (backlight, always on)
GP11 - CS
GP12 - DC
GP13 - RES
GP15 - SDA
GP14 - SCL
3V3  - VCC
GND  - GND

AnalogIn GP26_A0 connect to variable resistor for Y
AnalogIn GP26_A1 connect to variable resistor for X
"""

import os
import sys
import board
import time
import terminalio
import displayio
import busio
from adafruit_display_text import label
import adafruit_st7789
import adafruit_cursorcontrol.cursorcontrol
from analogio import AnalogIn

print("=====================================")
info = sys.implementation[0] + ' ' + \
       os.uname()[3] + '\n' + \
       'run on ' + os.uname()[4]
print(info)
print("=====================================")
print(adafruit_st7789.__name__ + " version: " +
      adafruit_st7789.__version__)
print(adafruit_cursorcontrol.cursorcontrol.__name__
      + " version: "
      + adafruit_cursorcontrol.cursorcontrol.__version__)
print()

analog_A0 = AnalogIn(board.GP26_A0)
analog_A1 = AnalogIn(board.GP27_A1)

# Release any resources currently in use for the displays
displayio.release_displays()

tft_cs = board.GP11
tft_dc = board.GP12
tft_res = board.GP13
spi_mosi = board.GP15
spi_clk = board.GP14

display_width = 240
display_height = 240

"""
classbusio.SPI(clock: microcontroller.Pin,
                MOSI: Optional[microcontroller.Pin] = None,
                MISO: Optional[microcontroller.Pin] = None)
"""
spi = busio.SPI(spi_clk, MOSI=spi_mosi)

display_bus = displayio.FourWire(
    spi, command=tft_dc, chip_select=tft_cs, reset=tft_res
)

display = adafruit_st7789.ST7789(display_bus,
                    width=display_width, height=display_height,
                    rowstart=80,
                    rotation=180)

# Make the display context
splash = displayio.Group()
display.show(splash)

color_bitmap = displayio.Bitmap(display_width, display_height, 1)
color_palette = displayio.Palette(1)
color_palette[0] = 0xA0A0A0

bg_sprite = displayio.TileGrid(color_bitmap,
                               pixel_shader=color_palette, x=0, y=0)
splash.append(bg_sprite)

# Draw a smaller inner rectangle
inner_bitmap = displayio.Bitmap(50, 180, 1)
inner_palette = displayio.Palette(1)
inner_palette[0] = 0x0000FF
inner_sprite = displayio.TileGrid(inner_bitmap,
                                  pixel_shader=inner_palette, x=50, y=20)
#splash.append(inner_sprite)

info1 = sys.implementation[0] + ' ' + os.uname()[2]
info2 = 'run on ' + os.uname()[4]

# Draw labels for CircuitPython info
text_group1 = displayio.Group(scale=2, x=5, y=40)
text1 = info1
text_area1 = label.Label(terminalio.FONT, text=text1, color=0x000000)
text_group1.append(text_area1)  # Subgroup for text scaling
#
text_group2 = displayio.Group(scale=1, x=5, y=70)
text2 = info2
text_area2 = label.Label(terminalio.FONT, text=text2, color=0xFFFFFF)
text_group2.append(text_area2)  # Subgroup for text scaling

# Draw labels for adafruit_st7789
text_group3 = displayio.Group(scale=2, x=5, y=120)
text3 = adafruit_st7789.__name__
text_area3 = label.Label(terminalio.FONT, text=text3, color=0x000000)
text_group3.append(text_area3)  # Subgroup for text scaling
# 
text_group4 = displayio.Group(scale=2, x=5, y=150)
text4 = adafruit_st7789.__version__
text_area4 = label.Label(terminalio.FONT, text=text4, color=0xFF0000)
text_group4.append(text_area4)  # Subgroup for text scaling

# Draw labels for adafruit_cursorcontrol.cursorcontrol
text_group5 = displayio.Group(scale=1, x=5, y=180)
text5 = adafruit_cursorcontrol.cursorcontrol.__name__
text_area5 = label.Label(terminalio.FONT, text=text5, color=0x000000)
text_group5.append(text_area5)  # Subgroup for text scaling
#
text_group6 = displayio.Group(scale=2, x=5, y=210)
text6 = adafruit_cursorcontrol.cursorcontrol.__version__
text_area6 = label.Label(terminalio.FONT, text=text6, color=0x000000)
text_group6.append(text_area6)  # Subgroup for text scaling

splash.append(text_group1)
splash.append(text_group2)

# initialize the mouse cursor object
# create custom bitmap for cursor
bmp = displayio.Bitmap(20, 20, 3)
for i in range(0, 20):
    bmp[i, (20-1)-i] = 1
    bmp[(20-1)-i, (20-1)-i] = 1
for i in range(0, 20):
    bmp[0, i] = 1
    bmp[i, 0] = 1
    
# initialize the mouse cursor object
# place under inner_sprite, text_group3/4/5/6, and over all other
mouse_cursor = adafruit_cursorcontrol.cursorcontrol.Cursor(
    display, display_group=splash, bmp=bmp)
"""
#use default cursor
mouse_cursor = adafruit_cursorcontrol.cursorcontrol.Cursor(
    display, display_group=splash)
"""
cursor_bitmap = mouse_cursor.cursor_bitmap
print(cursor_bitmap, cursor_bitmap.width, "x", cursor_bitmap.height)

for by in range(0, cursor_bitmap.height):
    s = str(by) + ":\t"
    for bx in range(0, cursor_bitmap.width):
        b = cursor_bitmap[bx, by]
        if b == 0:
            s = s + " " + " "
        else:
            s = s + str(b) + " "
    print(s)

splash.append(inner_sprite)
splash.append(text_group3)
splash.append(text_group4)
splash.append(text_group5)
splash.append(text_group6)
"""
# initialize the mouse cursor object
mouse_cursor = adafruit_cursorcontrol.cursorcontrol.Cursor(
    display, display_group=splash)
"""
while True:
    offset_x = 0
    offset_y = 0
    delta_x = analog_A1.value-32768
    delta_y = analog_A0.value-32768
    
    if(delta_x >= 0):
        if delta_x > 30000:
            offset_x = 4
        elif delta_x > 20000:
            offset_x = 2
        elif delta_x > 10000:
            offset_x = 1
    else:
        if delta_x < -30000:
            offset_x = -4
        elif delta_x < -20000:
            offset_x = -2
        elif delta_x < -10000:
            offset_x = -1

    if(delta_y >= 0):
        if delta_y > 30000:
            offset_y = -4
        elif delta_y > 20000:
            offset_y = -2
        elif delta_y > 10000:
            offset_y = -1
    else:
        if delta_y < -30000:
            offset_y = 4
        elif delta_y < -20000:
            offset_y = 2
        elif delta_y < -10000:
            offset_y = 1
    
    mouse_cursor.x = mouse_cursor.x + offset_x
    mouse_cursor.y = mouse_cursor.y + offset_y
    
    time.sleep(0.05)
    
print("~ bye ~")


No comments: