Ausprobiert Teil 1

Rundes 1.28-Zoll-IPS-LCD-Touch Display -
Waveshare 24580
Anleitung für CircuitPython

Um es gleich vorwegzunehmen: "Mit dem runden IPS-1.28"-LCD Touch-Display stehen wir ganz am Anfang unserer eigenen Entwicklungsprojekte und solche Darstellungen, wie im oberen Bild von Waveshare als Muster gezeigt, sind noch meilenweit entfernt." Trotzdem war es schon ein erfolgreiches Stück Arbeit, bis die unten gezeigte Anwendung fertig war. Und sie funktioniert sehr gut:

- Ein Touch auf die Uhrzeit wechselt in einen Bildschrirm, in dem die Uhr gestellt werden kann;
- Eine Berührung des Stoppuhr Bitmaps wechselt in einen Screen mit Stopuhrfunktion;
- Eine Berührung des Frühstücksei Bitmaps wechselt in einen Screen mit Timerfunktion;
- Zum Stromsparen wird das Display jeweils nach 10 Sekunden dunkel geschaltet (nicht in den Funktionsscreens) und bei Berührung des grünen Button wieder auf hell.


Bildbox 2 (klick hier)


Wenn man den RP 2040 mit CircuitPython als Firmware nutzen will, muss man (fast) alles selbst entwickeln, denn im Netz ist dazu z.Z. nichts zu finden. Ich gehe deshalb zuerst darauf ein, wie man das Display in Betrieb nimmt und die Touchfunktionalität testet. Als erstes wird das Board mit der Firmware CircuitPython 9.0.5 geflasht. Eine ausführliche Beschreibung dazu finden Sie hier
unter dem Arbeitsschritt 'Installation von CircuitPython'.

Danach kopieren Sie die erforderlichen Bibliotheken in den 'lib'-Ordner. Das sind:

- cst816.py (Treiber für den Touch-Sensor)
- gc9a01.py (Treiber für das Display)
- adafruit_display_shapes (Ordner mit Treibern für grafische Elemente)
- adafruit_display_text (Ordner mit Treibern für Textlabels)
- adafruit_imageload (Ordner zur Darstellung von Bitmaps)
- adafruit_ticks.mpy (Treiber für Zeitmessungen)


Wenn Sie die zip-Datei von hier herunterladen und entpacken, können sie alle genannten Treiber passend für CircuitPython 9.0.5 in den Ordner 'CICUITPY/lib' kopieren. Dann sind alle Treiber für einen ersten Versuch vorhanden.

Dieser erste Versuch läuft in der Konsole von Thonny ab und zeigt an, ob das Display über I2C gefunden wurde und die Koordinaten, wenn man auf eine beliebige Stelle auf dem Display tippt. Kopieren Sie den Code aus dem unteren Kasten in Ihre Thonny IDE und führen ihn aus. (Beim Kopieren und Einsetzen in der Thonny IDE werden die Zeilen um eins nach unten verschoben. Deshalb löschen Sie einfach die leere Zeile 1, damit die Nummerierung wieder mit meinen Angaben übereinstimmt.) Die Funktion des Tests erklärt sich in Verbindung mit den Kommentaren praktisch von selbst.

  
  

1  import time
2  import board
3  import busio
4  import cst816
5
6  # Touch Pins
7  #I2C_SDA = 6
8  #I2C_SDL = 7
9  #I2C_INT = 17
10 #I2C_RST = 16
11
12 # Initialize I2C
13 i2c = busio.I2C(board.GP7,board.GP6)
14 touch = cst816.CST816(i2c)
15
16 # Check if the touch controller is detected
17 if touch.who_am_i():
18     print("CST816 detected.")
19 else:
20     print("CST816 not detected.")
21
22 # Read touch data continuously
23 while True:
24     point = touch.get_point()
25     gesture = touch.get_gesture()
26     press = touch.get_touch()
27     distance = touch.get_distance()
28     print("Position: {0},{1} - Gesture: {2} - Pressed? {3} - Distance: {4},{5}".format(point.x_point, point.y_point, gesture, press, distance.x_dist, distance.y_dist))
29     time.sleep(0.05)
  

Das Wichtigste aus dem Testbeispiel sind die vier Grundbefehle:

- point = touch.get_point()
- gesture = touch.get_gesture()
- press = touch.get_touch()
- distance = touch.get_distance()

Obwohl das Display rund ist, werden die Koordinaten (240x240 Pixel) wie bei einem Quadrat ermittelt. Koordinaten außerhalb des sichtbaren Bereichs werden einfach weggeschnitten.

Mit 'x = touch.x_point' und ' y = touch.y_point' kann man die x- und y-Koordinate auf dem Display bestimmen. Dabei spielt es aber eine wichtige Rolle, ob das Display gedreht wurde. Bei display.rotation = 0 befindet sich der USB-C Anschluss unten (siehe Bild). Die Bildschirmkoordinaten stimmen dann mit den 'touch-Koordinaten' überein. Das im Bild gezeigte Rechteck (mit abgerundeten Ecken) hat bei den dargestellten Kordinaten eine Länge (x-Richtung) von 120 Pixeln und eine Breite (y-Richtung) von 60 Pixeln.


Display-Koordinaten = touch-Koordinaten


Anders verhält es sich, wenn der Bildschirm um 90 Grad gedreht ist (kommt bei Uhranwendungen überwiegend vor). Der Wert ist dann display.rotation = 90 und der USB-C Anschluss rechts. Zur Darstellung des Rechtecks auf dem Display wählt man die gleichen Koordinaten wie oben, aber die 'touch-Koordinaten' ändern sich, weil das Touchfeld ja fest mit der Platine verbunden ist. Siehe Bild unten.



Das nachfolgende Programm veranschaulicht Ihnen das. Tragen Sie in Zeile 21 entweder display.rotation = 0 oder display.rotation = 90 ein. Wenn Sie das Reckteck berühren, ändert es seine Farbe. Damit das nur bei der Berührung geschieht, wird zusätzlich press = touch.get_touch() genutzt. Die Funktion liefert immer die logischen Werte True oder False. Eine Bemerkung vorab auch noch zur Zeile 31. Hier wird der Touch-Mode auf den Wert 3 gesetzt. Es gibt drei Möglichkeiten:

- touch.set_mode(1) - Point_Mode
- touch.set_mode(2) - Gesture_Mode
- touch.set_mode(3) - All_Mode
.

  
  

1  import time
2  import board
3  import busio
4  import displayio
5  import terminalio
6  import gc9a01
7  import cst816
8  from adafruit_display_text import label
9  from adafruit_ticks import ticks_ms
10 from adafruit_display_shapes.rect import Rect
11 from adafruit_display_shapes.roundrect import RoundRect
12 from adafruit_display_shapes.circle import Circle
13 from adafruit_display_shapes.line import Line
14
15 # Release any resources currently in use for the displays
16 displayio.release_displays()
17 # Make the displayio SPI bus and the GC9A01 display
18 spi = busio.SPI(clock=board.GP10, MOSI=board.GP11)
19 display_bus = displayio.FourWire(spi, command=board.GP8, chip_select=board.GP9, reset=board.GP13)
20 display = gc9a01.GC9A01(display_bus, width=240, height=240, backlight_pin=board.GP25, brightness = 1)
21 display.rotation = 90
22
23 ##Touch Pins
24 # I2C_SDA = 6
25 # I2C_SDL = 7
26 # I2C_INT = 17
27 # I2C_RST = 16
28 # Initialize I2C
29 i2c = busio.I2C(scl=board.GP7, sda=board.GP6)
30 touch = cst816.CST816(i2c)
31 touch.set_mode(3)
32
33 # Make the display context
34 main_screen = displayio.Group()
35 display.root_group = main_screen
36
37 # make bitmap for the display background
38 background = displayio.Bitmap(240, 240, 1)
39 mypal = displayio.Palette(3)
40 mypal[0] = 0x800000
41 background.fill(0)
42 # Background oben
43 main_screen.append(displayio.TileGrid(background, pixel_shader=mypal))
44
45 # show the roundrect
46 roundrect= RoundRect(40,90,160,60,20,fill=0x009900, outline=0x00ff00)
47 main_screen.append(roundrect)
48
49 while True:
50     point = touch.get_point()
51     gesture = touch.get_gesture()
52     press = touch.get_touch()
53     if display.rotation == 0:
54         if touch.x_point > 40 and touch.x_point < 160 and point.y_point > 90 and point.y_point < 150 and press == True:
55             roundrect.fill = 0x0000ff
56         else:
57             roundrect.fill = 0x009900
58     if display.rotation == 90:
59         if touch.x_point > 90 and touch.x_point < 150 and point.y_point > 40 and point.y_point < 160 and press == True:
60             roundrect.fill = 0x0000ff
61         else:
62             roundrect.fill = 0x009900
  

Der Befehl gesture = touch.get_gesture() erkennt die Gesten, wenn man über des Display streicht. Wenn display.rotation = 0 ist, funktionieren die Gesten wie folgt:

- gesture = 1 --> up
- gesture = 2 --> down
- gesture = 3 --> left
- gesture = 4 --> right
- gesture = 5 --> double click
- gesture = 12 --> long pressed

ist das Display hingegen um 90 Grad gedreht (display.rotation = 90) gelten:

- gesture = 1 --> left
- gesture = 2 --> right
- gesture = 3 --> down
- gesture = 4 --> up
- gesture = 5 --> double click
- gesture = 12 --> long pressed

Auch dafür können Sie das kleine Programm im unteren Kasten in Thonny einsetzen und testen. Beginnen Sie ohne Drehung des Displays und ändern dann alle notwendigen Programmzeilen ab, so dass das Display um 90 Grad gedreht ist und die Gesten erkannt werden.

  
  

1  import time
2  import board
3  import busio
4  import displayio
5  import terminalio
6  import gc9a01
7  import cst816
8  from adafruit_display_text import label
9  from adafruit_ticks import ticks_ms
10 from adafruit_display_shapes.rect import Rect
11 from adafruit_display_shapes.roundrect import RoundRect
12 from adafruit_display_shapes.circle import Circle
13 from adafruit_display_shapes.line import Line
14
15 # Release any resources currently in use for the displays
16 displayio.release_displays()
17 # Make the displayio SPI bus and the GC9A01 display
18 spi = busio.SPI(clock=board.GP10, MOSI=board.GP11)
19 display_bus = displayio.FourWire(spi, command=board.GP8, chip_select=board.GP9, reset=board.GP13)
20 display = gc9a01.GC9A01(display_bus, width=240, height=240, backlight_pin=board.GP25, brightness = 1)
21 display.rotation = 0
22
23 ##Touch Pins
24 # I2C_SDA = 6
25 # I2C_SDL = 7
26 # I2C_INT = 17
27 # I2C_RST = 16
28 # Initialize I2C
29 i2c = busio.I2C(scl=board.GP7, sda=board.GP6)
30 touch = cst816.CST816(i2c)
31 touch.set_mode(3)
32
33 # Make the display context
34 main_screen = displayio.Group()
35 display.root_group = main_screen
36
37 # make bitmap for the display background
38 background = displayio.Bitmap(240, 240, 1)
39 mypal = displayio.Palette(3)
40 mypal[0] = 0x800000
41 background.fill(0)
42 # Background oben
43 main_screen.append(displayio.TileGrid(background, pixel_shader=mypal))
44
45 #create the label
46 updating_label = label.Label(font=terminalio.FONT, text="direction", scale=2, color=0xffffff, line_spacing=1)
47 updating_label.anchor_point = (0, 0)
48 updating_label.anchored_position = (75, 110)
49 main_screen.append(updating_label)
50
51 while True:
52     point = touch.get_point()
53     gesture = touch.get_gesture()
54     press = touch.get_touch()
55     if display.rotation == 0:
56         if gesture == 1 and press == True: # up
57             updating_label.text = "Hoch"
58             time.sleep(0.5)
59         if gesture == 2 and press == True: # down
60             updating_label.text = "Runter"
61             time.sleep(0.5)
62         if gesture == 3 and press == True: # left
63             updating_label.text = "Links"
64             time.sleep(0.5)
65         if gesture == 4 and press == True: # right
66             updating_label.text = "rechts"
67             time.sleep(0.5)
68         if gesture == 5 and press == True: # double click
69             updating_label.text = "Doubleclick"
70             time.sleep(1)
71         if gesture == 12 and press == True: # long
72             updating_label.text = "long pressed"
73             time.sleep(1)
74         print(gesture)
75     gesture = 0
  

Dieser Beitrag wird mit weiteren interessanten Anregungen zur Nutzung des runden 1.28-Zoll-IPS-LCD-Touch Displays fortgesetzt.


Viel Spass und Erfolg beim Ausprobieren.