PI – OLED: Ikony, Animace a Lopaka.app

Pro profesionální vzhled CanSat projektu nestačí jen text. Použití ikon (např. stav SD karty, síla signálu, stav baterie) a animací dělá rozhraní mnohem přehlednější. K jejich tvorbě využijeme online nástroj Lopaka.app.

Co je Lopaka.app?

Lopaka je specializovaný grafický editor pro malé displeje. Umožňuje vám „nakreslit“ rozhraní přímo v prohlížeči a následně vygenerovat kód, který displej SSD1306 chápe.

  1. Vyberte typ displeje (SSD1306) a rozlišení (128×32).
  2. Nakreslete ikonu nebo nahrajte malý obrázek.
  3. zaskrknete „declare images“
  4. zkopirujte data obrazku

Převod ikon pro Python

Lopaka často exportuje data ve formátu hexadecimálních polí (např. 0xff, 0x80...). V Pythonu tato data vložíme do objektu bytes a převedeme na obrázek pomocí knihovny PIL (Pillow).

Příklad: Animace ikon (Přesýpací hodiny)

Při „bootování“ (startu) systému je dobré ukázat, že se něco děje. K tomu slouží smyčka, která střídá různé snímky (framy) ikony.

Vytvořte soubor oled_anim.py:

nano oled_anim.py

Python

from luma.core.interface.serial import i2c
from luma.oled.device import ssd1306
from luma.core.render import canvas
from PIL import Image
import time
# definice dat pro animaci (7 snímků, každý o velikosti 24x24 pixelů)
# tato hexadecimální data představují jednotlivé řádky pixelů tvé ikony
frames_data = [
bytes([0x00,0x00,0x00,0x07,0xff,0xf0,0x04,0x00,0x10,0x03,0xff,0xe0,0x01,0x00,0x40,0x01,0x7f,0x40,0x01,0x7f,0x40,0x01,0x3e,0x40,0x00,0x9c,0x80,0x00,0x49,0x00,0x00,0x22,0x00,0x00,0x14,0x00,0x00,0x14,0x00,0x00,0x22,0x00,0x00,0x49,0x00,0x00,0x80,0x80,0x01,0x00,0x40,0x01,0x00,0x40,0x01,0x00,0x40,0x01,0x00,0x40,0x03,0xff,0xe0,0x04,0x00,0x10,0x07,0xff,0xf0,0x00,0x00,0x00]),
bytes([0x00,0x00,0x00,0x07,0xff,0xf0,0x04,0x00,0x10,0x03,0xff,0xe0,0x01,0x00,0x40,0x01,0x00,0x40,0x01,0x7f,0x40,0x01,0x3e,0x40,0x00,0x9c,0x80,0x00,0x49,0x00,0x00,0x22,0x00,0x00,0x14,0x00,0x00,0x14,0x00,0x00,0x22,0x00,0x00,0x49,0x00,0x00,0x80,0x80,0x01,0x08,0x40,0x01,0x3e,0x40,0x01,0x7f,0x40,0x01,0x00,0x40,0x03,0xff,0xe0,0x04,0x00,0x10,0x07,0xff,0xf0,0x00,0x00,0x00]),
bytes([0x00,0x00,0x00,0x07,0xff,0xf0,0x04,0x00,0x10,0x03,0xff,0xe0,0x01,0x00,0x40,0x01,0x00,0x40,0x01,0x00,0x40,0x01,0x3e,0x40,0x00,0x9c,0x80,0x00,0x49,0x00,0x00,0x22,0x00,0x00,0x14,0x00,0x00,0x14,0x00,0x00,0x22,0x00,0x00,0x49,0x00,0x00,0x80,0x80,0x01,0x3e,0x40,0x01,0x7f,0x40,0x01,0x7f,0x40,0x01,0x00,0x40,0x03,0xff,0xe0,0x04,0x00,0x10,0x07,0xff,0xf0,0x00,0x00,0x00]),
bytes([0x00,0x00,0x00,0x07,0xff,0xf0,0x04,0x00,0x10,0x03,0xff,0xe0,0x01,0x00,0x40,0x01,0x00,0x40,0x01,0x00,0x40,0x01,0x00,0x40,0x00,0x80,0x80,0x00,0x41,0x00,0x00,0x22,0x00,0x00,0x14,0x00,0x00,0x14,0x00,0x00,0x22,0x00,0x00,0x49,0x00,0x00,0x9c,0x80,0x01,0x3e,0x40,0x01,0x7f,0x40,0x01,0x7f,0x40,0x01,0x00,0x40,0x03,0xff,0xe0,0x04,0x00,0x10,0x07,0xff,0xf0,0x00,0x00,0x00]),
bytes([0x00,0x40,0x00,0x00,0xe0,0x00,0x01,0x40,0x00,0x02,0xa0,0x00,0x05,0x10,0x00,0x0a,0x08,0x00,0x14,0x08,0x00,0x28,0x08,0x00,0x50,0x08,0x00,0xe0,0x08,0x00,0x50,0x08,0x00,0x08,0x07,0xe0,0x07,0xe0,0x10,0x00,0x14,0x0a,0x00,0x17,0xe7,0x00,0x17,0xca,0x00,0x17,0x94,0x00,0x17,0x28,0x00,0x12,0x50,0x00,0x08,0xa0,0x00,0x05,0x40,0x00,0x02,0x80,0x00,0x07,0x00,0x00,0x02,0x00]),
bytes([0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x06,0x50,0x00,0x0a,0x5f,0x00,0xfa,0x50,0x81,0x0a,0x50,0x42,0x0a,0x50,0x24,0x0a,0x50,0x18,0x7a,0x50,0x03,0xfa,0x50,0x19,0xfa,0x50,0x24,0xfa,0x50,0x42,0x7a,0x50,0x81,0x0a,0x5f,0x00,0xfa,0x50,0x00,0x0a,0x60,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00]),
bytes([0x00,0x02,0x00,0x00,0x07,0x00,0x00,0x02,0x80,0x00,0x05,0x40,0x00,0x08,0xa0,0x00,0x10,0x50,0x00,0x10,0x28,0x00,0x13,0x94,0x00,0x17,0xca,0x00,0x17,0xe7,0x00,0x17,0xca,0x07,0xe0,0x10,0x08,0x07,0xe0,0x50,0x08,0x00,0xe0,0x08,0x00,0x50,0x08,0x00,0x28,0x08,0x00,0x14,0x08,0x00,0x0a,0x08,0x00,0x05,0x10,0x00,0x02,0xa0,0x00,0x01,0x40,0x00,0x00,0xe0,0x00,0x00,0x40,0x00])
]
# inicializace i2c rozhraní pro raspberry pi
# nastavujeme port na 1 a adresu na 0x3c, což je u oledů nejběžnější
serial = i2c(port=1, address=0x3C)
# vytvoření objektu samotného oled displeje
# zadáváme šířku 128 a výšku 32 pixelů přesně pro tvůj hardware
device = ssd1306(serial, width=128, height=32)
# převedení syrových bytů na formát obrázků knihovny pillow
# tímto krokem připravíme všechny snímky do paměti, aby se pak vykreslovaly rychleji
icons = [Image.frombytes('1', (24, 24), data) for data in frames_data]
# výpis do terminálu, abys věděl, že program běží
print("looping animation... press ctrl+c to stop.")
try:
# nekonečná smyčka, která bude neustále točit animaci dokola
while True:
# procházíme jednotlivé předpřipravené snímky v seznamu
for icon in icons:
# otevření kreslícího plátna pro aktuální snímek
# vše uvnitř tohoto 'with' bloku se připraví a po skončení pošle na displej
with canvas(device) as draw:
# vykreslení ikony na displej
# souřadnice (40, 4) ji posunou mírně doprava a vycentrují vertikálně (výška je 32, ikona má 24, takže (32-24)/2=4)
draw.bitmap((40, 4), icon, fill="white")
# přidání doprovodného textu napravo od ikony
# text začíná na x=70 a y=12, aby byl zhruba uprostřed výšky displeje
draw.text((70, 12), "BOOTING...", fill="white")
# vykreslení malého kontrolního čtverečku v levém horním rohu
# outline="white" udělá obrys a fill="black" zajistí, že vnitřek bude zhasnutý
draw.rectangle((0, 0, 15, 15), outline="white", fill="black")
# krátká pauza mezi snímky, aby animace nebyla příliš zběsilá
# hodnota 0.03 sekundy zajistí plynulý pohyb při i2c komunikaci
time.sleep(0.03)
except KeyboardInterrupt:
# ošetření ukončení programu pomocí kláves ctrl+c
# vypíše zprávu do terminálu a korektně ukončí skript
print("\nstopped.")
python3 oled_anim.py

Jak efektivně pracovat s ikonami v CanSatu

Při návrhu ikon v Lopaka.app se držte těchto pravidel:

  • Pevné rozměry: Standardizujte své ikony (např. 16×16 nebo 24×24 pixelů). Snadněji se pak umisťují do layoutu.
  • Indikátory stavu: Vytvořte si dvě verze jedné ikony (např. plná SD karta a přeškrtnutá SD karta). V kódu pak jen přepínáte, která se má vykreslit.
  • Využití průhlednosti: Pokud kreslíte ikonu přes text nebo tvary, ujistěte se, že používáte správné vkládání (image.paste), aby ikona nepřemazala zbytek grafiky černým čtvercem.

Proč používat animace?

V CanSatu animace slouží jako „Heartbeat“ (tlukot srdce). Pokud na displeji vidíte rotující ikonu nebo blikající tečku, víte, že procesor Raspberry Pi nezamrzl a program stále běží, i když se zrovna nemění hodnoty telemetrie.

Kategorie