Skocz do zawartości

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


matsobdev

Pomocna odpowiedź

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
Link do komentarza
Share on other sites

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...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.