Display Hat Mini

Hi! I’ve just bought a the Display Hat Mini and I’m trying to get it to display my Pi desktop, just as a mini screen to do basic operation. I’ve followed all the GitHub installations, but all I can get it to do is play pong (so at least it works!). Can anyone help me please? Thanks!

I think you need to have a look see here to get that kind of functionality.

I’ll give it a go, thank you

Just a FYI post. I have the Official Pi 7 inch touch screen which is 800 x 480, and find it cramped. The Display hat MINI is only 2 inch 320x480 so don’t be surprised if its a bit hard to see what your doing. If your booting to command line it may be OK, assuming you can read the small text.

Unfortunately this package doesn’t recognise the Pi4 yet. ☹️

To your other point, I just want to use the screen for three mouse clicks to run the program.

Right, I’ve managed to find the line to insert the board revision in. Now I have to work this out! 😱⬇️⬇️

Can’t help you there, that’s above my current skill level. Post your issue on that github page and you’ll likely get better help than I can offer you here.

You probably want to leave out the [options] bit from your cmake command (that’s a placeholder to indicate you could include options, from whatever tutorial you’re following)

Cmake is not great at explaining what’s upsetting it, but giving a literal [options] is not going to make much sense to it.

Thanks I’ll give that a go!

In fact, reading slightly further down the README on that project, it tells you what you should have instead of [options] - GitHub - juj/fbcp-ili9341: A blazing fast display driver for SPI-based LCD displays for Raspberry Pi A, B, 2, 3, 4 and Zero

Looks like it doesn’t know about that Mini, so you’d need to specify the driver (st7789) and the pins used (which will be on the pinout, I guess?)

1 Like

SPI0 CE1, GPIO 13 for the backlight.
Display HAT Mini at Raspberry Pi GPIO Pinout

1 Like

If you do figure this out @Sir_Loin then please ping me to let me know how you did it! I’ve struggled for the best part of a few hours trying to get it to display more than pong / backlight test!

These examples will work with the Display Hat Mini. These show you how to write and draw on the screen using PIL to display shapes, text and gifs.
st7789-python/examples at master · pimoroni/st7789-python (github.com)

1 Like

Hey guys
Got a code here ,just copy paste.
dont forget first to install mms (pip install mss)

import time
from PIL import Image
from st7789 import ST7789
import RPi.GPIO as GPIO
import mss
import numpy as np
import threading
import queue

# Параметры дисплея и подключения
SPI_PORT = 0
SPI_CS = 1
SPI_DC = 9
BACKLIGHT = 13
WIDTH = 320
HEIGHT = 240

# Кнопки
BUTTON_A = 5
BUTTON_B = 6
BUTTON_X = 16
BUTTON_Y = 24

# Светодиоды
LED_R = 17
LED_G = 27
LED_B = 22

# Настройка GPIO
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.setup(BUTTON_A, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(BUTTON_B, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(BUTTON_X, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(BUTTON_Y, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(LED_R, GPIO.OUT)
GPIO.setup(LED_G, GPIO.OUT)
GPIO.setup(LED_B, GPIO.OUT)

# Инициализация дисплея
display = ST7789(
    port=SPI_PORT,
    cs=SPI_CS,
    dc=SPI_DC,
    backlight=BACKLIGHT,
    width=WIDTH,
    height=HEIGHT,
    rotation=180,
    spi_speed_hz=60 * 1000 * 1000,
)

# Очередь для обмена данными между потоками
image_queue = queue.Queue(maxsize=1)

def capture_screen(image_queue):
    with mss.mss() as sct:
        while True:
            monitor = sct.monitors[0]  # Используем первый доступный монитор
            sct_img = sct.grab(monitor)
            img = Image.frombytes("RGB", sct_img.size, sct_img.rgb)
            if img.mode != 'RGB':
                img = img.convert('RGB')
            if not image_queue.full():
                image_queue.put(img)
            time.sleep(0.01)  # Небольшая пауза для снижения нагрузки на CPU

def display_image(display, image_queue, fps):
    while True:
        start_time = time.time()
        if not image_queue.empty():
            img = image_queue.get()
            img = img.resize((WIDTH, HEIGHT))
            display.display(img)
        elapsed_time = time.time() - start_time
        sleep_time = max(1.0 / fps - elapsed_time, 0)
        time.sleep(sleep_time)

def main(fps=30):
    capture_thread = threading.Thread(target=capture_screen, args=(image_queue,))
    display_thread = threading.Thread(target=display_image, args=(display, image_queue, fps))

    capture_thread.start()
    display_thread.start()

    try:
        capture_thread.join()
        display_thread.join()
    except KeyboardInterrupt:
        GPIO.cleanup()
    except Exception as e:
        print(f"An error occurred: {e}")
        GPIO.cleanup()

if __name__ == "__main__":
    main(fps=30)  # Устанавливаем частоту обновления 30 кадров в секунду

I’ve fixed it for you this time, but if you enclose your code in triple backticks (```) it will stop the forum from messing up the formatting.

Clicking the Preformatted Text button </> will also do it. ;)

1 Like

How to make that screen to show more tan 10 fps , i tried basically everything but nothing can boost my fps .

Here si all the code that i manage to make .
import time
import numpy as np
import spidev
import pyautogui
import RPi.GPIO as GPIO
from PIL import Image, ImageDraw, ImageFont
from st7789 import ST7789

Параметры дисплея и настройки подключения

SPI_PORT = 0
SPI_CS = 1
SPI_DC = 9
BACKLIGHT = 13
WIDTH = 320
HEIGHT = 240

Кнопки GPIO для Display HAT Mini

BUTTON_A = 5
BUTTON_B = 6
BUTTON_X = 16
BUTTON_Y = 24

Инициализация дисплея

spi = spidev.SpiDev()
spi.open(SPI_PORT, SPI_CS)
spi.max_speed_hz = 80 * 1000 * 1000 # Увеличенная скорость SPI

display = ST7789(
port=SPI_PORT,
cs=SPI_CS,
dc=SPI_DC,
backlight=BACKLIGHT,
width=WIDTH,
height=HEIGHT,
rotation=180,
spi_speed_hz=spi.max_speed_hz,
)

Инициализация GPIO для кнопок

GPIO.setmode(GPIO.BCM)
GPIO.setup(BUTTON_A, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(BUTTON_B, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(BUTTON_X, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(BUTTON_Y, GPIO.IN, pull_up_down=GPIO.PUD_UP)

Запуск дисплея

display.begin()

Инициализация шрифта для счетчика FPS

font = ImageFont.truetype(“arial.ttf”, 18)

Функция для перемещения курсора мыши

def move_cursor(x, y):
current_x, current_y = pyautogui.position()
pyautogui.moveTo(current_x + x, current_y + y)

Функция для обработки нажатий кнопок

def button_callback(channel):
if channel == BUTTON_A and GPIO.input(BUTTON_X) == GPIO.LOW:
pyautogui.click(button=‘right’) # Правый клик
elif channel == BUTTON_A and GPIO.input(BUTTON_Y) == GPIO.LOW:
pyautogui.click(button=‘left’) # Левый клик
elif channel == BUTTON_A:
move_cursor(0, -10) # Переместить курсор вверх
elif channel == BUTTON_B:
move_cursor(0, 10) # Переместить курсор вниз
elif channel == BUTTON_X:
move_cursor(-10, 0) # Переместить курсор влево
elif channel == BUTTON_Y:
move_cursor(10, 0) # Переместить курсор вправо

Добавление обнаружения событий для кнопок

GPIO.add_event_detect(BUTTON_A, GPIO.FALLING, callback=button_callback, bouncetime=100)
GPIO.add_event_detect(BUTTON_B, GPIO.FALLING, callback=button_callback, bouncetime=100)
GPIO.add_event_detect(BUTTON_X, GPIO.FALLING, callback=button_callback, bouncetime=100)
GPIO.add_event_detect(BUTTON_Y, GPIO.FALLING, callback=button_callback, bouncetime=100)

def capture_screen():
import mss
with mss.mss() as sct:
monitor = sct.monitors[0]
last_time = time.perf_counter()
frame_count = 0
fps = 0 # Инициализация переменной FPS

    while True:
        start_time = time.perf_counter()

        # Захват экрана
        screenshot = sct.grab(monitor)
        img = Image.frombytes('RGB', screenshot.size, screenshot.rgb)

        # Получение позиции мыши
        mouse_x, mouse_y = pyautogui.position()

        # Вычисление коэффициентов масштабирования
        screen_width, screen_height = pyautogui.size()
        scale_x = WIDTH / screen_width
        scale_y = HEIGHT / screen_height

        # Масштабирование позиции мыши
        scaled_mouse_x = int(mouse_x * scale_x)
        scaled_mouse_y = int(mouse_y * scale_y)

        # Рисование курсора мыши
        draw = ImageDraw.Draw(img)
        cursor_size = 2  # Уменьшенный размер курсора для уменьшения времени обработки
        draw.rectangle(
            (scaled_mouse_x - cursor_size, scaled_mouse_y - cursor_size, scaled_mouse_x + cursor_size, scaled_mouse_y + cursor_size),
            outline="white", fill="black"
        )

        # Изменение размера изображения для соответствия дисплею
        img = img.resize((WIDTH, HEIGHT), Image.BILINEAR)

        # Вычисление FPS
        frame_count += 1
        current_time = time.perf_counter()
        if current_time - last_time >= 1.0:
            fps = frame_count
            frame_count = 0
            last_time = current_time

        # Отображение счетчика FPS с использованием PIL
        draw.text((10, 10), f"FPS: {fps}", font=font, fill="black")

        # Преобразование изображения в массив numpy
        arr = np.array(img)

        # Отображение изображения на дисплее
        display.display(arr)

        # Контроль частоты кадров до 60 FPS
        elapsed_time = time.perf_counter() - start_time
        sleep_time = max(0, (1 / 60) - elapsed_time)
        if sleep_time > 0:
            time.sleep(sleep_time)

if name == “main”:
try:
capture_screen()
except KeyboardInterrupt:
GPIO.cleanup()

Thank you.