Skocz do zawartości

Wyświetlacz na ST7789 262K proste demko - Pico (W) i MicroPython, odczyt z pliku *.bmp z pamięci kontrolera


Pomocna odpowiedź

Napisano (edytowany)

Jak w temacie, w sumie na sucho przed zakupem trochę pomodziłem przykład Waveshare'a dla ich wyświetlacza 1,9" 170x320. Główny cel, to brak konieczności konwersji pliku graficznego z użyciem wygody wbudowanego systemu plików i wykorzystanie potencjału wyświetlacza (zapłacone za 262 tysiące kolorów). Nawet się udało i zagadało prawie z pierwszego - mały babol, linijka po linijce CS w dół i górę.

Choć mając już ekranik w rękach, nie byłem zadowolony z jakości obrazu, choć ustawienia (gamma itd.) zebrałem z ich przykładów Arduino, STM32 lub pełnego Pythona (nie pamiętam już który) dla tego właśnie wyświetlacza. Obraz migotał (jak kiedyś wspomniałem, mówiąc o tanim module 128x128, było tak samo) poruszając modułem i/lub głową (oczami :P), były białe plamy na białych detalach na zdjęciu, a obrazy typu ich pokazowe tarcze dla "mondrych" zegarków miały wyżarte krawędzie detali i pojawiały się pojedyncze fałszywe piksele, a obraz była przesadnie ostry (antyaliasing na obrazkach nic nie dawał).

Okazało się, że ustawienia dla innego ich wyświetlacza: 1,69" 240x280 (też 262K) pasują (poza oczywiście ustawieniem bramek, czy coś, które przy 320 pikselach w pionie mogło mieć wartość domyślną) najlepiej i nie ma się już do czego przyczepić. Poniżej kod:

from machine import Pin, SPI
import time
import gc

BL = 13
DC = 8
RST = 15
MOSI = 11
SCK = 10
CS = 9

class LCD_1inch3():
    def __init__(self):        
        self.cs = Pin(CS, Pin.OUT)
        self.rst = Pin(RST, Pin.OUT)
        self.cs(1)
        self.spi = SPI(1, baudrate=62500000,
                       polarity = 0, phase = 0, sck = Pin(SCK), mosi = Pin(MOSI), miso = None)
        self.dc = Pin(DC, Pin.OUT)
        self.dc(1)
        super().__init__()
        self.init_display()
        
        self.red    =   0x07E0
        self.green  =   0x001F
        self.blue   =   0xF800
        self.yellow =   0x07FF
        self.white  =   0xFFFF
        self.black  =   0x0000
        
    def write_cmd(self, cmd):
        self.cs(1)
        self.dc(0)
        self.cs(0)
        self.spi.write(bytearray([cmd]))
        self.cs(1)
        
    def write_data(self, buf):
        self.cs(1)
        self.dc(1)
        self.cs(0)
        self.spi.write(bytearray([buf]))
        self.cs(1)
        
    def init_display(self):
        self.rst(1)
        time.sleep_ms(1)
        self.rst(0)
        time.sleep_ms(1)
        self.rst(1)
        time.sleep_ms(1)
        self.write_cmd(0x01)
        time.sleep_ms(150)
        self.write_cmd(0x11)
        time.sleep_ms(10)
        self.write_cmd(0x3A)
        self.write_data(0x06) # 18 bit
        self.write_cmd(0x36)
        self.write_data(0x28) # Żeby rysować bezpośrednio z *.bmp
        self.write_cmd(0xB2)
        self.write_data(0x0B)
        self.write_data(0x0B)
        self.write_data(0x00)
        self.write_data(0x33)
        self.write_data(0x35)
        self.write_cmd(0xB7)
        self.write_data(0x11)
        self.write_cmd(0xBB)
        self.write_data(0x35)
        self.write_cmd(0xC0)
        self.write_data(0x2C)
        self.write_cmd(0xC2)
        self.write_data(0x01)
        self.write_cmd(0xC3)
        self.write_data(0x0D)
        self.write_cmd(0xC4)
        self.write_data(0x20)
        self.write_cmd(0xC6)
        self.write_data(0x13)
        self.write_cmd(0xD0)
        self.write_data(0xA4)
        self.write_data(0xA1)
        self.write_cmd(0xD6)
        self.write_data(0xA1)
        self.write_cmd(0xE0)
        self.write_data(0xF0)
        self.write_data(0x06)
        self.write_data(0x0B)
        self.write_data(0x0A)
        self.write_data(0x09)
        self.write_data(0x26)
        self.write_data(0x29)
        self.write_data(0x33)
        self.write_data(0x41)
        self.write_data(0x18)
        self.write_data(0x16)
        self.write_data(0x15)
        self.write_data(0x29)
        self.write_data(0x2D)
        self.write_cmd(0xE1)
        self.write_data(0xF0)
        self.write_data(0x04)
        self.write_data(0x08)
        self.write_data(0x08)
        self.write_data(0x07)
        self.write_data(0x03)
        self.write_data(0x28)
        self.write_data(0x32)
        self.write_data(0x40)
        self.write_data(0x3B)
        self.write_data(0x19)
        self.write_data(0x18)
        self.write_data(0x2A)
        self.write_data(0x2E)
        self.write_cmd(0x21)
        self.write_cmd(0x29)
        time.sleep_ms(100)
        
    def show(self):
        self.write_cmd(0x2A)
        self.write_data(0x00)
        self.write_data(0x00)
        self.write_data(0x01)
        self.write_data(0x3F)
        self.write_cmd(0x2B)
        self.write_data(0x00)
        self.write_data(0x23)
        self.write_data(0x00)
        self.write_data(0xCC)
        self.write_cmd(0x2C)
        self.cs(1)
        self.dc(1)
        self.cs(0)
        file = open('flower_h.bmp', 'rb')
        file.seek(54)
        flower = file.read(40800)
        self.spi.write(flower)
        del flower
        gc.collect
        flower = file.read(40800)
        self.spi.write(flower)
        del flower
        gc.collect
        flower = file.read(40800)
        self.spi.write(flower)
        del flower
        gc.collect
        flower = file.read(40800)
        self.spi.write(flower)
        del flower
        gc.collect
        file.close()
        self.cs(1)

LCD_LED = Pin(BL, Pin.OUT)
LCD_LED.on()

LCD = LCD_1inch3()
LCD.show()
print("Gotowe")

Plik wskazuje się oczywiście tutaj:

file = open('flower_h.bmp', 'rb')

Mniej oczywista jest linijka:

file.seek(54)

To różnica (dla obrazka pełnoekranowego): rozmiar_w_bajtach_pliku_bmp - 170x320x3. Zakładając, że nie ma meta danych itp. Po to, żeby ominąć nagłówek pliku i przejść do surowych danych. Zwykły obrazek przycięty i zapisany w Paincie, czy IrfanView. Obraz musi być w poziomie (w pliku *.bmp), no i tutaj na twardo jest tylko pełny ekran, 170x320. Tylko proste demko, dalej można zrobić z tego co się chce (oparametryzować: wielkość, pozycja itp.). Same obrazki przerzucić na płytkę w Thonnym, czy innym IDE pozwalającym na zapis do partycji MP.

PS.: Musiałem wcześniej coś namieszać (albo raczej poprzednie wersje plików miały inne ustawienia  - ustawienia w korespondujących plikach się różnią) i oryginalne ustawienia dla 1,9" wyglądają ok, ale te dla 1,69" jednak wyglądają najlepiej. Kolory są bardziej nasycone zachowując tą samą jasność, czerń głębsza.

Edytowano przez matsobdev

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...