Problem mit Waveshare ST7789 Display

  • Hallo, ich versuche mich gerade an einem Waveshare 1.3 LCD HAT, 240x240 mit ST7789. Alles nach Anleitung installiert. Der Framebuffer mit Spiegelung des Desktops und die Darstellung eines Bildes funktionieren. Beim python script main.py bekomme ich die Fehlermeldung:

    pi@RPiUSB:~/RaspberryPi/python $ sudo python main.py (Democode aus Waveshare-Wiki)

    Traceback (most recent call last):

    File "main.py", line 15, in <module>

    disp = ST7789.ST7789(SPI.SpiDev(bus, device),RST, DC, BL)

    IOError: [Errno 2] No such file or directory

    Linux RPiUSB 4.19.118+ #1311 Mon Apr 27 14:16:15 BST 2020 armv6l GNU/Linux

    ich vermute, daß es mit der Linuxversion zusammenhängt, nach apt upgrade oder rpi-update geht auch der Framebuffer nicht mehr.

    Kennt noch jemand dieses Problem?

    Gruß Micha

  • SPI ist aktiviert, sonst würde ja die Desktopspiegelung und Bildanzeige nicht gehen. Es sieht nach einem Problem mit dem ST7789 Treiber aus. Habe jetzt eine Installation mit 4.14 gemacht, geht auch nicht.

  • danke, das bewirkt aber auch nichts:

    pi@RPiZeroS:~/TFT/python $ sudo python /home/pi/TFT/python/main.py

    der Treiber wird schon erkannt, als noch Komponenten, wie SPIDev und numpy fehlten, hat er es auch bemerkt.

  • micha-uhl zeig mal bitte den kompletten Code, und die komplette Fehlermeldung. Ein vager Hinweis auf ein Wiki führt zu 10 Minuten suche & dann weiß immer noch keiner, ob’s das richtige Skript ist.

  • hier die Dateien ST7789.py und main.py , sowie die Fehlermeldung:

    aus

    http://www.waveshare.com/wiki/1.3inch_LCD_HAT

    #ST7789.py

    import spidev

    import RPi.GPIO as GPIO

    import time

    import numpy as np


    class ST7789(object):

    """class for ST7789 240*240 1.3inch OLED displays."""

    def __init__(self,spi,rst = 27,dc = 25,bl = 24):

    self.width = 240

    self.height = 240

    #Initialize DC RST pin

    self._dc = dc

    self._rst = rst

    self._bl = bl

    GPIO.setmode(GPIO.BCM)

    GPIO.setwarnings(False)

    GPIO.setup(self._dc,GPIO.OUT)

    GPIO.setup(self._rst,GPIO.OUT)

    GPIO.setup(self._bl,GPIO.OUT)

    GPIO.output(self._bl, GPIO.HIGH)

    #Initialize SPI

    self._spi = spi

    self._spi.max_speed_hz = 40000000

    """ Write register address and data """

    def command(self, cmd):

    GPIO.output(self._dc, GPIO.LOW)

    self._spi.writebytes([cmd])

    def data(self, val):

    GPIO.output(self._dc, GPIO.HIGH)

    self._spi.writebytes([val])

    def Init(self):

    """Initialize dispaly"""

    self.reset()

    self.command(0x36)

    self.data(0x70) #self.data(0x00)

    self.command(0x3A)

    self.data(0x05)

    self.command(0xB2)

    self.data(0x0C)

    self.data(0x0C)

    self.data(0x00)

    self.data(0x33)

    self.data(0x33)

    self.command(0xB7)

    self.data(0x35)

    self.command(0xBB)

    self.data(0x19)

    self.command(0xC0)

    self.data(0x2C)

    self.command(0xC2)

    self.data(0x01)

    self.command(0xC3)

    self.data(0x12)

    self.command(0xC4)

    self.data(0x20)

    self.command(0xC6)

    self.data(0x0F)

    self.command(0xD0)

    self.data(0xA4)

    self.data(0xA1)

    self.command(0xE0)

    self.data(0xD0)

    self.data(0x04)

    self.data(0x0D)

    self.data(0x11)

    self.data(0x13)

    self.data(0x2B)

    self.data(0x3F)

    self.data(0x54)

    self.data(0x4C)

    self.data(0x18)

    self.data(0x0D)

    self.data(0x0B)

    self.data(0x1F)

    self.data(0x23)

    self.command(0xE1)

    self.data(0xD0)

    self.data(0x04)

    self.data(0x0C)

    self.data(0x11)

    self.data(0x13)

    self.data(0x2C)

    self.data(0x3F)

    self.data(0x44)

    self.data(0x51)

    self.data(0x2F)

    self.data(0x1F)

    self.data(0x1F)

    self.data(0x20)

    self.data(0x23)

    self.command(0x21)

    self.command(0x11)

    self.command(0x29)

    def reset(self):

    """Reset the display"""

    GPIO.output(self._rst,GPIO.HIGH)

    time.sleep(0.01)

    GPIO.output(self._rst,GPIO.LOW)

    time.sleep(0.01)

    GPIO.output(self._rst,GPIO.HIGH)

    time.sleep(0.01)

    def SetWindows(self, Xstart, Ystart, Xend, Yend):

    #set the X coordinates

    self.command(0x2A)

    self.data(0x00) #Set the horizontal starting point to the high octet

    self.data(Xstart & 0xff) #Set the horizontal starting point to the low octet

    self.data(0x00) #Set the horizontal end to the high octet

    self.data((Xend - 1) & 0xff) #Set the horizontal end to the low octet

    #set the Y coordinates

    self.command(0x2B)

    self.data(0x00)

    self.data((Ystart & 0xff))

    self.data(0x00)

    self.data((Yend - 1) & 0xff )

    self.command(0x2C)

    def ShowImage(self,Image,Xstart,Ystart):

    """Set buffer to value of Python Imaging Library image."""

    """Write display buffer to physical display"""

    imwidth, imheight = Image.size

    if imwidth != self.width or imheight != self.height:

    raise ValueError('Image must be same dimensions as display \

    ({0}x{1}).' .format(self.width, self.height))

    img = np.asarray(Image)

    pix = np.zeros((self.width,self.height,2), dtype = np.uint8)

    pix[...,[0]] = np.add(np.bitwise_and(img[...,[0]],0xF8),np.right_shift(img[...,[1]],5))

    pix[...,[1]] = np.add(np.bitwise_and(np.left_shift(img[...,[1]],3),0xE0),np.right_shift(img[...,[2]],3))

    pix = pix.flatten().tolist()

    self.SetWindows ( 0, 0, self.width, self.height)

    GPIO.output(self._dc,GPIO.HIGH)

    for i in range(0,len(pix),4096):

    self._spi.writebytes(pix[i:i+4096])

    def clear(self):

    """Clear contents of image buffer"""

    _buffer = [0xff]*(self.width * self.height * 2)

    self.SetWindows ( 0, 0, self.width, self.height)

    GPIO.output(self._dc,GPIO.HIGH)

    for i in range(0,len(_buffer),4096):

    self._spi.writebytes(_buffer[i:i+4096])

    ============================================================================

    #main.py

    import spidev as SPI

    import ST7789

    import time

    from PIL import Image,ImageDraw,ImageFont

    # Raspberry Pi pin configuration:

    RST = 27

    DC = 25

    BL = 24

    bus = 0

    device = 0

    # 240x240 display with hardware SPI:

    disp = ST7789.ST7789(SPI.SpiDev(bus, device),RST, DC, BL)

    # Initialize library.

    disp.Init()

    # Clear display.

    disp.clear()

    # Create blank image for drawing.

    image1 = Image.new("RGB", (disp.width, disp.height), "WHITE")

    draw = ImageDraw.Draw(image1)

    #font = ImageFont.truetype('/usr/share/fonts/truetype/freefont/FreeMonoBold.ttf', 16)

    print "***draw line"

    draw.line([(60,60),(180,60)], fill = "BLUE",width = 5)

    draw.line([(180,60),(180,180)], fill = "BLUE",width = 5)

    draw.line([(180,180),(60,180)], fill = "BLUE",width = 5)

    draw.line([(60,180),(60,60)], fill = "BLUE",width = 5)

    print "***draw rectangle"

    draw.rectangle([(70,70),(170,80)],fill = "RED")

    print "***draw text"

    draw.text((90, 70), 'WaveShare ', fill = "BLUE")

    draw.text((90, 120), 'Electronic ', fill = "BLUE")

    draw.text((90, 140), '1.3inch LCD ', fill = "BLUE")

    disp.ShowImage(image1,0,0)

    time.sleep(3)

    image = Image.open('pic.jpg')

    disp.ShowImage(image,0,0)

    ====================================================================================

    Ausführung:

    pi@RPiZeroS:~/TFT/python $ python main.py

    Traceback (most recent call last):

    File "main.py", line 15, in <module>

    disp = ST7789.ST7789(SPI.SpiDev(bus, device),RST, DC, BL)

    IOError: [Errno 2] No such file or directory

    pi@RPiZeroS:~/TFT/python $

    Edited once, last by micha-uhl (August 11, 2020 at 10:39 AM).

  • Naja, du kannst ja auch nicht einfach das device ändern. Das muss schon zur Hardware passen. Kann es sein, das du einen Treiber laufen hast, der sich das Gerät schon geschnappt hat? Der Star natürlich NICHT laufen.

  • das war ja auch nur zum Test, das der Treiber erkannt wird und läuft. Habe aber hier etwas gefunden, das meine Vermutung bestätigt:

    https://revolution.kunbus.de/forum/viewtopic.php?t=2191&p=8135

    Ansonsten habe ich alles nach Anleitung installiert, probeweise dtoverlay=bcm2850 in die config.txt eingetragen und auch in der blacklist war das bcm2850 mal aaskommentiert, keine Wirkung. Mit modprobe spidev wird auch nichts angezeigt.

    Ich werde mal nach einer älteren Debian version suchen und damit testen.

  • Wenn du spidev0.1 hast, ist der Spidev Treiber (also das Modul) da. Der Treiber IST derjenige, der das spidev0.0 für sich beansprucht. Den musst du schon wieder rausschmeißen, sonst holt der sich das Modul.

  • Klarstellung: der Wave Share Treiber greift sich das SPI device. Spidev holt sich dann nur den übriggebliebenen Rest.

  • Problem erkannt!

    Nach einer Neuinstallation sind fb0, spidev0.0 und spidev0.1 vorhanden und das python script funktioniert

    Wenn der Framebuffer fb1 aktiviert ist, verschwindet Spidev0.0

    Habe die module fbtft-device und flexfb aus /etc/modules entfernt, damit funktioniert python!

    Es können also nicht Framebuffer und SPIDev gleichzeitig betrieben werden? Oder gibt es da eine Möglichkeit.

    Es wundert mich nur, weil beide Varianten in Beispieldateien nebeneinander stehen und auch in der Anleitung zusammen beschrieben sind.

    Computer sind doof!

    Danke für die Unterstützung

    Micha

  • Wie sollte das denn aussehen, das der Fb und Python gleichzeitig Funktionieren? Winner takes it all? Der letzte Frame wird dargestellt? Das ist doch grauseliges geflacker.

    Entweder ist das Ding als FB betrieben, und dann kannst du mit Python eben in den FB schreiben. Oder du steuerst es selbst an. Gleichzeitig ist halt nicht.

Participate now!

Don’t have an account yet? Register yourself now and be a part of our community!