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 ~")


Sunday, May 8, 2022

OpenEuler 22.03 LTS (UKUI Desktop) run on Raspberry Pi 4

OpenEuler is an innovative platform nurtured by community collaboration. It aims to build a unified and open OS that supports multiple processor architectures, and to advance the hardware/software application ecosystem.

To download image of OpenEuler 22.03 LTS for Raspberry Pi, visit https://gitee.com/openeuler/raspberrypi (You can switch to English here). It provide various desktops include UKUI, DDE, Xfce and LXDE.

UKUI is a Linux desktop built by the KylinSoft software team over the years, primarily based on GTK and QT. Compared to other UI interfaces, UKUI is easy to use. The components of UKUI are small and low coupling, can run alone without relying on other suites. It can provide user a friendly and efficient experience. UKUI supports both x86_64 and aarch64 architectures.



This video show the steps to download image of OpenEuler 22.03 LTS (UKUI Desktop) for Raspberry Pi, boot on Raspberry Pi 4B/4G and setup changing to English, and some more.