Bewegte Bilder auf PicoBoy Color


technische Daten wie beim RPi Pico
Microcontroller RP2040 - 1,69 Zoll Farbdisplay mit 240 x 280 Pixeln

Projekte und Anleitung in CircuitPython 9.x.x



Bildbox 1 (klick hier)

Beim Weihnachtsgadget in der oberen Box lassen sich die Kerzen einschalten und im Hintergrund schneit es. Aber das zweite Bild in der Bildbox lässt noch viel mehr vermuten. Der Microcontroller des PicoBoy-Color hat genug Rechenleistung, um PicoMax wie Super Mario über den Bildschirm laufen zu lassen. Wie das in CircuitPython geht, wird in der folgenden mehrteiligen Anleitungen gezeigt.

Hardware

- PicoBoy-Color


Bitmaps darstellen

In Circuitpython lassen sich Bilddateien auf zwei Arten darstellen. Die erste ist 'Imageload' und die zweite 'OnDiskBitmap'. Bei OnDiskBitmap wird das Bitmap-Bild direkt aus dem Flash-Speicher geladen, während es bei Imageload zuerst in den Speicher geladen wird. Die erste Methode belegt also weniger Speicher bei langsameren Pixel-Zeichnungszeiten. Die zweite Methode hält das Bild im Speicher und belegt dadurch entsprechend viel Platz, stellt aber das Bild sehr viel schneller dar, wenn es gebraucht wird.
In beiden Fällen sollte die Bilddatei der darstellbaren Pixelanzahl des Displays entsprechen, da keine automatische Skalierung möglich ist. Überstehende Bereiche werden einfach nicht dargestellt. Was man aber auch bewußt nutzen kann, z.B. mit quadratischen Bildern bei den runden Displays. Die Bereiche an den Ecken fehlen dann.
Ich habe für ein Beispiel auf dem PicoBoy-Color vier Bitmap-Dateien (240x 280 Pixel, max. 256 Farben!), die Sie von hier downloaden können und auf dem PicoBoy in einen Ordner 'pictures' speichern. Vorher müssen Sie Ihren PicoBoy-Color mit der Firmware 'CircuitPython' einrichten. Am einfachsten können Sie dazu das Weihnachtsgadget installieren und die Datei 'code.py' umbenennen (oder löschen). So haben Sie bereits alle notwendigen Bibliotheken 'an Bord'.

Zum Ausprobieren des Beispiels kopieren Sie den Code aus dem unteren Kasten ins Thonny, speichern ihn unter beliebigem Namen und starten den Test. In den Zeilen 31 und 32 wird die Bitmap-Datei in den Speicher geladen und in einem s.g. TileGrid (dt. Kachelgitter) abgelegt. Wenn Sie dagegen die Auskommentierung in den Zeilen 36 und 37 entfernen und dafür 31 und 32 mit Kommentarzeichen versehen, wird das Bild mit 'OnDiskBitmap' direkt aus dem Flashspeicher 'geholt' und in einer TileGrid abgelegt.

  
  
1  import time
2  import board
3  import busio
4  import displayio
5  import terminalio
6  from adafruit_st7789 import ST7789
7  import adafruit_imageload
8
9  # 1,69 Zoll 240x280 Pixel ST7789 Display
10 # SPI,  in Landscape format
11 dc=board.GP8
12 reset=board.GP9
13 cs=board.GP10
14 sck=board.GP18
15 mosi=board.GP19
16 bl=board.GP26
17 # Release any resources currently in use for the displays
18 displayio.release_displays()
19 spi = busio.SPI(sck, mosi)
20 display_bus = displayio.FourWire(spi, command=dc, chip_select=cs, reset=reset)
21 display = ST7789(display_bus, rotation=0, width=240, height=280, backlight_pin=bl, rowstart=20, colstart=0)
22 display.brightness = 1
23
24 # Create a Group to hold the TileGrid
25 group = displayio.Group()
26 # Add the Group to the Display
27 display.root_group = group
28
29 ## Example for Imageload
30 ## Load the bitmap and then create a TileGrid to hold the bitmap
31 bitmap, palette = adafruit_imageload.load("/pictures/bild_01.bmp", bitmap=displayio.Bitmap, palette=displayio.Palette)
32 tile_grid = displayio.TileGrid(bitmap, pixel_shader=palette)
33
34 ## Example for OnDiskBitmap
35 ## Setup the file as the bitmap data source and then create a TileGrid to hold the bitmap
36 #bitmap = displayio.OnDiskBitmap("/pictures/bild_01.bmp")
37 #tile_grid = displayio.TileGrid(bitmap, pixel_shader=bitmap.pixel_shader)
38
39 # Add the TileGrid to the Group
40 group.append(tile_grid)
  

Bis zu diesem Punkt ist rein visuell kein Unterschied zu erkennen und es bewegt sich auch noch nichts. Wenn Sie allerdings wegen der vier verschiedenen Bilder im Ordner 'pictures' diese nacheinander darstellen wollen, könnten Sie schon schnell einen ' MemoryError' erzeugen. Für eine solche 'Slideshow' gibt es in Circuitpython eine spezielle Bibliothek 'adafruit_slideshow.mpy'. Kopieren Sie die aus dem Bibliotheks-Bundle in Ihren lib-Ordner, dann können Sie das nachfolgende Beispiel testen:

  
  
1  import time
2  import board
3  import busio
4  import displayio
5  import terminalio
6  from adafruit_st7789 import ST7789
7  from adafruit_slideshow import PlayBackOrder, SlideShow
8
9  # 1,69 Zoll 240x280 Pixel ST7789 Display
10 # SPI,  in Landscape format
11 dc=board.GP8
12 reset=board.GP9
13 cs=board.GP10
14 sck=board.GP18
15 mosi=board.GP19
16 bl=board.GP26
17 # Release any resources currently in use for the displays
18 displayio.release_displays()
19 spi = busio.SPI(sck, mosi)
20 display_bus = displayio.FourWire(spi, command=dc, chip_select=cs, reset=reset)
21 display = ST7789(display_bus, rotation=0, width=240, height=280, backlight_pin=bl, rowstart=20, colstart=0)
22 display.brightness = 1
23
24 slideshow = SlideShow(display,
25                     None,
26                     folder="/pictures/",
27                     loop=True,
28                     order=PlayBackOrder.ALPHABETICAL,
29                     dwell=5,
30                     )
31
32 while slideshow.update():
33     pass
  

Um zu den bewegten Bildern zu kommen, müssen wir jetzt eine s.g. sprite_sheet, Blatt mit Sprites, anlegen mit der das Hintergrundbild dargestellt wird. Das erkläre ich in der nächsten Folge.

Viel Spass und Erfolg beim Ausprobieren.