diff --git a/.gitignore b/.gitignore index 8f8e8b9..499d6dc 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,6 @@ JC_Display_Firmware_7zoll/8-Burn operation/flash_download_tool_3.9.7/ JC_Display_Firmware_7zoll/1-Demo/Demo_Arduino/*/lvgl/ JC_Display_Firmware_7zoll/1-Demo/Demo_IDF/ JC_Display_Firmware_7zoll/7-Character&Picture_Molding_Tool/ + +# Python-Zwischenablage der Werkzeugskripte +__pycache__/ diff --git a/P4_Display_Firmware/Changelog.txt b/P4_Display_Firmware/Changelog.txt index a9367d5..5e20372 100644 --- a/P4_Display_Firmware/Changelog.txt +++ b/P4_Display_Firmware/Changelog.txt @@ -1,3 +1,45 @@ +Version 1.13.0: +- Neue Oberfläche für die Startseite und das Menü. Die Anordnung bleibt, was sie war - + Statuszeile, zwei Kessel, darunter die Werte -, aber jede Beschriftung trägt jetzt ihr + eigenes Sinnbild, und alles ist linksbündig gesetzt. Mittig gesetzte Überschriften + wanderten mit der Wortlänge hin und her; das Auge musste den Zeilenanfang jedes Mal neu + suchen. +- Eco-Zeit und Tassenablage-Temperatur haben jetzt je eine eigene Kachel und stehen beide + dauerhaft. Bisher teilten sie sich eine Kachel und wechselten sich alle fünf Sekunden ab: + Wer die Temperatur ablesen wollte, musste warten, bis sie wieder an der Reihe war. +- Die Flow-Kachel steht ebenfalls dauerhaft, statt erst mit dem Bezug zu erscheinen. Dabei + rückten bisher alle anderen Kacheln zur Seite - ausgerechnet in dem Moment, in dem man + hinschaut. Im Ruhezustand zeigt sie die mittlere Flussrate des letzten Bezugs; die sagt + beim Nachschmecken mehr als der Momentanwert. +- Zielwerte stehen nicht mehr im Messwert, sondern in einer eigenen Nebenzeile darunter. + Bisher teilten sich Ist und Ziel denselben Platz und dieselbe Größe ("24,8 g / 36,0 g"), + obwohl das Ziel sich während eines Bezugs gar nicht ändert. Der Zielwert der Waage ist + dabei immer der eingestellte Wert ohne Nachlauf-Offset. +- Die Nebenzeile trägt auch im Ruhezustand etwas: die Dauer des letzten Bezugs, das + eingestellte Zielgewicht, die Dampf-Abschaltzeit, den Grund des Eco-Countdowns. +- Die Fortschrittsbalken sind jetzt durchsichtig statt versteckt, wenn kein Bezug läuft. + Ein verstecktes Element fällt aus dem Layout heraus - die Zahl darüber rückte deshalb bei + jedem Bezugsbeginn ein Stück nach unten. +- Zeiten, Gewichte und Flussraten werden mit deutschem Dezimalkomma geschrieben. Die + Temperaturen taten das längst, die übrigen Zahlen standen mit Punkt daneben. +- In den Verlaufskurven markiert eine feine Waagerechte den Sollwert. Ohne sie zeigt die + Kurve nur, DASS die Temperatur schwingt - mit ihr sieht man, worum herum. +- Die Verlaufs-Darstellung ist die neue Vorgabe (vorher das Zustandsband). Der + Fortschrittsbalken am Fuß der Kesselkarte entfällt dort: Die Kurve sagt dasselbe und mehr. + Die übrigen drei Darstellungen bleiben unter "Darstellung" wählbar. +- Das Menü ist linksbündig, trägt Sinnbilder und ist in vier Gruppen geteilt: Betrieb, + Bezug, Maschine, System. Zwölf Einträge als eine Liste waren zwölf gleichwertige Zeilen, + durch die man suchen musste. Rechts in der Zeile steht der Nebenwert der Seite dahinter - + Solltemperaturen, geladenes Profil, Licht an oder aus, WLAN-Netz, fällige Wartung, + Firmware-Stand. Alle zwölf Seiten passen ohne Scrollen auf das Panel. +- Der Menüknopf zeigt jetzt, was ein Tipp bewirkt: Striche zum Öffnen, Kreuz zum Schließen. +- Die Sinnbilder sind ein eigener Satz von 22 Zeichen (Tasse, Thermometer, Dampf, Waage, + Schneeflocke, Zahnrad und weitere). Der in LVGL eingebaute Zeichensatz hat davon keines. + Sie liegen als reine Deckkraftbilder im Flash und werden beim Zeichnen eingefärbt - ein + Zeichen genügt damit für alle Farben, in denen es vorkommt, und im RAM steht nur der + Bildkopf. Erzeugt werden sie von Werkzeuge/symbole_erzeugen.py; dort liegen auch die + Zeichnungen. + Version 1.12.0: - Die Dampf-/Thermoblock-Temperatur wird jetzt mit einer Nachkommastelle angezeigt, wie die Wassertemperatur. Das gilt für die große Zahl auf der Startseite, den Sollwert darunter und diff --git a/P4_Display_Firmware/Werkzeuge/symbole_erzeugen.py b/P4_Display_Firmware/Werkzeuge/symbole_erzeugen.py new file mode 100644 index 0000000..f0a9ab3 --- /dev/null +++ b/P4_Display_Firmware/Werkzeuge/symbole_erzeugen.py @@ -0,0 +1,374 @@ +#!/usr/bin/env python3 +# ===================================================================================== +# symbole_erzeugen.py - erzeugt ui_symbole.c aus den Zeichnungen weiter unten +# ===================================================================================== +# Die Oberflaeche des Displays braucht Sinnbilder, die es im eingebauten LVGL-Zeichensatz +# nicht gibt: Tasse, Thermometer, Dampf, Waage, Schneeflocke. Statt eine komplette +# Symbolschrift einzubinden, wird jedes Zeichen hier als Strichzeichnung beschrieben und +# zu einem reinen Deckkraftbild (LV_COLOR_FORMAT_A8) gerastert. +# +# Warum Deckkraftbilder und keine Schrift: +# - Ein A8-Bild traegt nur Deckkraft, keine Farbe. LVGL faerbt es beim Zeichnen mit +# 'image_recolor' ein - dasselbe Zeichen dient also in Gold, Tuerkis, Grau und Rot, +# ohne dass es mehrfach im Speicher liegt. +# - Die Daten sind const und liegen damit im Flash, nicht im ohnehin knappen RAM. +# - Es braucht keine Fremdwerkzeuge (lv_font_conv, Node); dieses Skript genuegt. +# +# Aufruf (aus diesem Ordner): python symbole_erzeugen.py +# Schreibt: ../ui_symbole.c +# +# Gezeichnet wird in einem 24x24-Raster (wie bei den ueblichen Strichsymbolsaetzen) und +# auf SIZE herunterskaliert. Die Kantenglaettung entsteht aus dem Abstand zum Strich: +# Ein Punkt genau auf der Strichkante bekommt halbe Deckkraft, ein Punkt eine halbe +# Pixelbreite daneben gar keine mehr. +# ===================================================================================== + +import math +import os + +GRID = 24.0 # Koordinatenraster der Zeichnungen +SIZE = 20 # Kantenlaenge des erzeugten Bildes in Pixeln +STROKE = 1.8 # Strichbreite im 24er-Raster + + +# --------------------------------------------------------------------------------- +# Bausteine +# --------------------------------------------------------------------------------- +def cubic(p0, p1, p2, p3, steps=18): + """Bezierkurve zu einem Streckenzug aufloesen.""" + out = [] + for i in range(steps + 1): + t = i / steps + u = 1.0 - t + x = u*u*u*p0[0] + 3*u*u*t*p1[0] + 3*u*t*t*p2[0] + t*t*t*p3[0] + y = u*u*u*p0[1] + 3*u*u*t*p1[1] + 3*u*t*t*p2[1] + t*t*t*p3[1] + out.append((x, y)) + return out + + +def arc(cx, cy, r, a0, a1, steps=None): + """Kreisbogen als Streckenzug. Winkel in Grad, 0 = rechts, im Uhrzeigersinn.""" + if steps is None: + steps = max(6, int(abs(a1 - a0) / 8)) + out = [] + for i in range(steps + 1): + a = math.radians(a0 + (a1 - a0) * i / steps) + out.append((cx + r * math.cos(a), cy + r * math.sin(a))) + return out + + +def circle(cx, cy, r): + return arc(cx, cy, r, 0, 360) + + +def teardrop(apex, cx, cy, r): + """Tropfen: zwei Tangenten von der Spitze an den Kreis, dazu der grosse Bogen.""" + dx, dy = cx - apex[0], cy - apex[1] + d = math.hypot(dx, dy) + if d <= r: + return circle(cx, cy, r) + base = math.atan2(dy, dx) + off = math.acos(r / d) + a_l = base + off + a_r = base - off + t_l = (cx + r * math.cos(a_l + math.pi), cy + r * math.sin(a_l + math.pi)) + t_r = (cx + r * math.cos(a_r + math.pi), cy + r * math.sin(a_r + math.pi)) + bogen = arc(cx, cy, r, + math.degrees(a_l + math.pi), + math.degrees(a_r + math.pi) + 360) + return [apex, t_l] + bogen + [t_r, apex] + + +def zahnrad(cx, cy, r_aussen, r_innen, zaehne=8, laenge=1.9): + """Zahnrad: Ring mit kurzen Zaehnen nach aussen.""" + teile = [circle(cx, cy, r_aussen), circle(cx, cy, r_innen)] + for i in range(zaehne): + a = math.radians(360.0 * i / zaehne) + ca, sa = math.cos(a), math.sin(a) + teile.append([(cx + ca * (r_aussen - 0.4), cy + sa * (r_aussen - 0.4)), + (cx + ca * (r_aussen + laenge), cy + sa * (r_aussen + laenge))]) + return teile + + +def welle(x, y_oben, y_unten, weite): + """Stehende S-Kurve - der Dampf steigt geschlaengelt auf.""" + h = (y_unten - y_oben) / 2.0 + a = cubic((x, y_unten), (x + weite, y_unten - h * 0.7), + (x + weite, y_oben + h * 1.3), (x, y_oben + h)) + b = cubic((x, y_oben + h), (x - weite, y_oben + h - h * 0.7), + (x - weite, y_oben + h * 0.3), (x, y_oben)) + return a + b + + +# --------------------------------------------------------------------------------- +# Die Zeichnungen +# --------------------------------------------------------------------------------- +# Jeder Eintrag ist eine Liste von Streckenzuegen. Ein Streckenzug ist entweder +# ('s', [punkte...]) - als Strich gezeichnet +# ('f', [punkte...]) - als gefuellte Flaeche gezeichnet (fuer Punkte und Vollformen) +# --------------------------------------------------------------------------------- +def s(pts): + return ('s', pts) + + +def f(pts): + return ('f', pts) + + +def linie(x1, y1, x2, y2): + return s([(x1, y1), (x2, y2)]) + + +SYMBOLE = { + # --- Kessel und Messwerte --------------------------------------------------- + 'tropfen': [ # Wasserkessel + s(teardrop((12, 3.4), 12, 12.9, 5.6)), + ], + 'dampf': [ # Dampfkessel + s(welle(7.5, 10.4, 21.0, 1.5)), + s(welle(12.0, 10.4, 21.0, 1.5)), + s(welle(16.5, 10.4, 21.0, 1.5)), + linie(5, 6.6, 19, 6.6), + ], + 'stoppuhr': [ # Shot-Timer + s(circle(12, 13.8, 7.0)), + linie(12, 13.8, 12, 9.9), + linie(9.4, 3.2, 14.6, 3.2), + linie(12, 3.2, 12, 6.8), + linie(18.3, 7.4, 19.8, 5.9), + ], + 'waage': [ # Waage + linie(12, 4.6, 12, 19.6), + linie(5.5, 19.6, 18.5, 19.6), + linie(4, 8.6, 20, 8.6), + s([(7, 8.6), (4, 13.8), (10, 13.8), (7, 8.6)]), + s([(17, 8.6), (14, 13.8), (20, 13.8), (17, 8.6)]), + ], + 'fluss': [ # Flussrate + s(teardrop((12, 3.4), 12, 12.9, 5.6)), + s(arc(12, 12.9, 2.8, 90, 180)), + ], + 'blatt': [ # Eco + s(cubic((19.8, 4.4), (19.8, 13.0), (15.0, 16.9), (10.9, 16.9)) + + cubic((10.9, 16.9), (8.0, 16.9), (6.3, 15.1), (6.3, 12.6)) + + cubic((6.3, 12.6), (6.3, 7.5), (12.6, 4.4), (19.8, 4.4))), + s(cubic((8.4, 19.8), (9.4, 15.2), (12.0, 12.1), (16.0, 10.2))), + ], + 'tasse': [ # Tassenablage + s([(4.0, 8.6), (15.5, 8.6), (15.5, 13.6)] + + arc(10.3, 13.6, 5.2, 0, 90) + + arc(9.2, 13.6, 5.2, 90, 180) + + [(4.0, 13.6), (4.0, 8.6)]), + s(arc(15.5, 12.2, 2.4, -90, 90)), + linie(3.4, 21.2, 16.6, 21.2), + ], + + # --- Menue und Zustand ------------------------------------------------------ + 'haus': [ # Dashboard + s([(4, 11.2), (12, 4.2), (20, 11.2)]), + s([(6.5, 10.0), (6.5, 19.8), (17.5, 19.8), (17.5, 10.0)]), + ], + 'kurve': [ # Verlauf + s([(4, 4.6), (4, 19.6), (20, 19.6)]), + s([(7, 15.4), (11, 10.2), (14, 13.2), (18, 7.2)]), + ], + 'balken': [ # Statistik + linie(5.6, 19.8, 5.6, 10.6), + linie(12, 19.8, 12, 4.6), + linie(18.4, 19.8, 18.4, 13.2), + ], + 'thermometer': [ # Temperatur + s([(10, 13.6), (10, 6.2)] + arc(12, 6.2, 2.0, 180, 360) + [(14, 13.6)]), + s(arc(12, 17.2, 4.2, -60, 240)), + linie(12, 9.2, 12, 15.4), + ], + 'schneeflocke': [ # Cold Extraction + linie(12, 3.2, 12, 20.8), + linie(4.4, 7.6, 19.6, 16.4), + linie(19.6, 7.6, 4.4, 16.4), + s([(9.2, 5.4), (12, 7.2), (14.8, 5.4)]), + s([(9.2, 18.6), (12, 16.8), (14.8, 18.6)]), + ], + 'zahnrad': [ # Reinigung/Wartung + ] + [s(t) for t in zahnrad(12, 12, 6.2, 2.6)], + 'lesezeichen': [ # Profile + s([(6.6, 4.2), (6.6, 20.4), (12, 16.4), (17.4, 20.4), (17.4, 4.2), (6.6, 4.2)]), + ], + 'gluehbirne': [ # Licht + s(arc(12, 9.4, 5.3, 145, 395) + [(9.7, 14.0), (9.7, 16.2)]), + s([(14.3, 14.0), (14.3, 16.2)]), + linie(9.5, 17.4, 14.5, 17.4), + linie(10.0, 20.2, 14.0, 20.2), + ], + 'wlan': [ # WiFi + s(arc(12, 18.4, 10.4, 206, 334)), + s(arc(12, 18.4, 6.9, 202, 338)), + s(arc(12, 18.4, 3.4, 196, 344)), + f(circle(12, 18.4, 1.25)), + ], + 'regler': [ # Darstellung + linie(4, 7.6, 13.4, 7.6), + s(circle(16.2, 7.6, 2.4)), + linie(19.0, 7.6, 20, 7.6), + linie(20, 16.4, 10.6, 16.4), + s(circle(7.8, 16.4, 2.4)), + linie(5.0, 16.4, 4, 16.4), + ], + 'info': [ # Info + s(circle(12, 12, 8.6)), + linie(12, 11.4, 12, 16.8), + f(circle(12, 7.8, 1.0)), + ], + 'menue': [ # Menueknopf + linie(4.5, 7, 19.5, 7), + linie(4.5, 12, 19.5, 12), + linie(4.5, 17, 19.5, 17), + ], + 'haken': [ # Statuszeile: alles in Ordnung + s([(4.8, 12.4), (9.6, 17.2), (19.2, 7.0)]), + ], + 'warnung': [ # Statuszeile/Menue: Hinweis + s([(12, 4.2), (20.6, 19.6), (3.4, 19.6), (12, 4.2)]), + linie(12, 10.2, 12, 14.2), + f(circle(12, 16.9, 1.0)), + ], + 'kreuz': [ # Menueknopf, wenn die Schublade offen ist + linie(5.6, 6.6, 18.4, 17.4), + linie(18.4, 6.6, 5.6, 17.4), + ], +} + + +# --------------------------------------------------------------------------------- +# Rasterung +# --------------------------------------------------------------------------------- +def dist_segment(px, py, ax, ay, bx, by): + vx, vy = bx - ax, by - ay + wx, wy = px - ax, py - ay + ll = vx * vx + vy * vy + t = 0.0 if ll == 0.0 else (wx * vx + wy * vy) / ll + t = max(0.0, min(1.0, t)) + return math.hypot(px - (ax + t * vx), py - (ay + t * vy)) + + +def punkt_in_polygon(px, py, pts): + drin = False + n = len(pts) + for i in range(n): + x1, y1 = pts[i] + x2, y2 = pts[(i + 1) % n] + if (y1 > py) != (y2 > py): + xs = x1 + (py - y1) * (x2 - x1) / (y2 - y1) + if px < xs: + drin = not drin + return drin + + +def rastern(zuege): + """Zeichnung zu einem SIZE x SIZE grossen Deckkraftbild machen.""" + skala = SIZE / GRID + halb = STROKE * skala / 2.0 + # Koordinaten einmal umrechnen + vorbereitet = [] + for art, pts in zuege: + sp = [(x * skala, y * skala) for x, y in pts] + vorbereitet.append((art, sp)) + + daten = bytearray(SIZE * SIZE) + for py in range(SIZE): + for px in range(SIZE): + cx, cy = px + 0.5, py + 0.5 + deckung = 0.0 + for art, pts in vorbereitet: + if art == 'f': + # Gefuellt: innen voll, an der Kante weich auslaufend + d = min(dist_segment(cx, cy, pts[i][0], pts[i][1], + pts[(i + 1) % len(pts)][0], pts[(i + 1) % len(pts)][1]) + for i in range(len(pts))) + if punkt_in_polygon(cx, cy, pts): + a = 1.0 + else: + a = 0.5 - d + else: + d = min(dist_segment(cx, cy, pts[i][0], pts[i][1], + pts[i + 1][0], pts[i + 1][1]) + for i in range(len(pts) - 1)) + a = halb - d + 0.5 + if a > deckung: + deckung = a + deckung = max(0.0, min(1.0, deckung)) + daten[py * SIZE + px] = int(deckung * 255.0 + 0.5) + return daten + + +# --------------------------------------------------------------------------------- +# Ausgabe +# --------------------------------------------------------------------------------- +KOPF = """// ===================================================================================== +// ui_symbole.c - Sinnbilder der Oberflaeche als Deckkraftbilder +// ===================================================================================== +// ERZEUGT - nicht von Hand aendern. +// Quelle: Werkzeuge/symbole_erzeugen.py (dort liegen die Zeichnungen) +// Neu erzeugen: cd P4_Display_Firmware/Werkzeuge && python symbole_erzeugen.py +// +// Jedes Bild traegt nur Deckkraft (LV_COLOR_FORMAT_A8), keine Farbe. Eingefaerbt wird +// beim Zeichnen ueber den Stil 'image_recolor' - dasselbe Zeichen dient damit in Gold, +// Tuerkis, Gruen, Orange oder Rot, ohne mehrfach im Speicher zu liegen. Die Daten sind +// const und liegen im Flash; im RAM steht nur der Bildkopf. +// ===================================================================================== + +#include "ui_symbole.h" + +""" + + +def c_name(name): + return 'sym_' + name + + +def main(): + hier = os.path.dirname(os.path.abspath(__file__)) + ziel_c = os.path.join(hier, '..', 'ui_symbole.c') + ziel_h = os.path.join(hier, '..', 'ui_symbole.h') + + namen = sorted(SYMBOLE.keys()) + + teile = [KOPF] + for name in namen: + daten = rastern(SYMBOLE[name]) + cn = c_name(name) + zeilen = [] + for i in range(0, len(daten), 20): + zeilen.append(' ' + ' '.join('0x%02x,' % b for b in daten[i:i + 20])) + teile.append('static const uint8_t %s_map[] = {\n%s\n};\n\n' % (cn, '\n'.join(zeilen))) + teile.append( + 'const lv_image_dsc_t %s = {\n' + ' .header = { .magic = LV_IMAGE_HEADER_MAGIC, .cf = LV_COLOR_FORMAT_A8,\n' + ' .flags = 0, .w = %d, .h = %d, .stride = %d, .reserved_2 = 0 },\n' + ' .data_size = sizeof(%s_map),\n' + ' .data = %s_map,\n' + ' .reserved = NULL,\n' + '};\n\n' % (cn, SIZE, SIZE, SIZE, cn, cn)) + + with open(ziel_c, 'w', encoding='utf-8', newline='\n') as fh: + fh.write(''.join(teile)) + + kopf = ['// =====================================================================================\n', + '// ui_symbole.h - Sinnbilder der Oberflaeche (erzeugt, siehe ui_symbole.c)\n', + '// =====================================================================================\n', + '\n#pragma once\n\n#include \n\n', + '#ifdef __cplusplus\nextern "C" {\n#endif\n\n', + '// Kantenlaenge aller Sinnbilder in Pixeln\n', + '#define UI_SYMBOL_SIZE %d\n\n' % SIZE] + for name in namen: + kopf.append('extern const lv_image_dsc_t %s;\n' % c_name(name)) + kopf.append('\n#ifdef __cplusplus\n}\n#endif\n') + + with open(ziel_h, 'w', encoding='utf-8', newline='\n') as fh: + fh.write(''.join(kopf)) + + print('%d Sinnbilder erzeugt (%dx%d Pixel)' % (len(namen), SIZE, SIZE)) + + +if __name__ == '__main__': + main() diff --git a/P4_Display_Firmware/config.h b/P4_Display_Firmware/config.h index d778b12..d45217a 100644 --- a/P4_Display_Firmware/config.h +++ b/P4_Display_Firmware/config.h @@ -126,7 +126,7 @@ // ------------------------------------------------------------------------------------- // Firmware // ------------------------------------------------------------------------------------- -#define DISPLAY_FW_VERSION "1.12.0" // Firmware-Stand der P4-Display-Steuerung (Info-Seite) +#define DISPLAY_FW_VERSION "1.13.0" // Firmware-Stand der P4-Display-Steuerung (Info-Seite) // ------------------------------------------------------------------------------------- // Protokoll diff --git a/P4_Display_Firmware/ui.cpp b/P4_Display_Firmware/ui.cpp index e3d8224..06cffa7 100644 --- a/P4_Display_Firmware/ui.cpp +++ b/P4_Display_Firmware/ui.cpp @@ -26,6 +26,7 @@ #include "display_hal.h" #include "esp_rom_sys.h" #include "lvgl_private.h" +#include "ui_symbole.h" // Sinnbilder der Oberflaeche (erzeugt, siehe Werkzeuge/) #include // ------------------------------------------------------------------------------------ @@ -69,6 +70,16 @@ static const lv_font_t* font_title() { } } +// Die Zahl in einer Info-Kachel. Sie steht fuer sich allein in der Kachel und darf +// deshalb deutlich groesser sein als eine Ueberschrift - gelesen wird im Vorbeigehen. +static const lv_font_t* font_value() { + switch (g_fontStep) { + case FONT_GROSS: return &lv_font_maven_pro_48; + case FONT_MITTEL: return &lv_font_maven_pro_48; + default: return &lv_font_maven_pro_40; + } +} + static void font_step_load() { Preferences p; if (p.begin("anzeige", true)) { @@ -176,7 +187,7 @@ static void label_set_if_changed(lv_obj_t* lbl, const char* txt); // Definitio // TD_NEO - Soft-3D/Neumorph: Flaeche wirkt aus dem Hintergrund herausgedrueckt // TD_THERMO - vertikale Thermometer-Saeulen mit Kolben und Glanzstreifen enum TempDesign { TD_GEWICHTET = 0, TD_VERLAUF, TD_FLAECHEN, TD_BAND, TD_DESIGN_COUNT }; -static uint8_t g_tempDesign = TD_BAND; +static uint8_t g_tempDesign = TD_VERLAUF; static bool g_tempColored = false; // Temperaturzahl in der Zustandsfarbe statt weiss // Eine Minute Verlauf. Gemessen wird einmal je Sekunde, gezeichnet wird viermal so fein: // Zwischen zwei Messwerten liegen vier Stuetzpunkte auf einem Kosinusbogen. Aus dem @@ -199,6 +210,8 @@ static lv_chart_series_t* g_sparkSerW = nullptr; static lv_chart_series_t* g_sparkSerD = nullptr; static lv_obj_t* g_sparkDotW = nullptr; // pulsierender Punkt am juengsten Messwert static lv_obj_t* g_sparkDotD = nullptr; +static lv_obj_t* g_sparkSollW = nullptr; // feine Waagerechte auf dem Sollwert +static lv_obj_t* g_sparkSollD = nullptr; static int32_t g_dotCxW = 0, g_dotCyW = 0; // Mitte des Punktes in der Kurvenflaeche static int32_t g_dotCxD = 0, g_dotCyD = 0; static lv_obj_t* g_readyBand = nullptr; // Zustandsband der Darstellung TD_BAND @@ -298,7 +311,19 @@ static uint8_t g_bzTick = 0; // Chart nur alle 200 ms fuettern ( static lv_obj_t* swBrewLive = nullptr; // Ein/Aus-Schalter auf der Info-Seite // Kombi-Zelle Eco/Gehaeuse (wechselt sich ab, wenn beide aktiv) static lv_obj_t* cellEco; static lv_obj_t* lblEco; static lv_obj_t* lblEcoTitle; -static bool g_ecoCasePhase = false; // false = Eco, true = Gehaeuse (bei Wechselanzeige) +static lv_obj_t* icoEco = nullptr; static lv_obj_t* lblEcoSub = nullptr; +// Gehaeuse-/Tassenablagetemperatur: eigene Kachel. Frueher teilte sie sich eine Kachel mit +// der Eco-Anzeige und die beiden wechselten sich alle 5 s ab - wer die Temperatur ablesen +// wollte, musste warten, bis sie wieder an der Reihe war. +static lv_obj_t* cellCase = nullptr; static lv_obj_t* lblCase = nullptr; +static lv_obj_t* lblCaseTitle = nullptr; static lv_obj_t* lblCaseSub = nullptr; +static lv_obj_t* icoCase = nullptr; +// Nebenzeilen der uebrigen Kacheln (Zielwerte, Vergleichswerte) +static lv_obj_t* lblShotSub = nullptr; static lv_obj_t* lblBezugSub = nullptr; +static lv_obj_t* lblFlowSub = nullptr; static lv_obj_t* lblSteamSub = nullptr; +// Letzter abgeschlossener Bezug - fuer die Nebenzeilen im Ruhezustand +static float g_letzteShotSek = 0.0f; // Dauer des letzten Bezugs +static float g_letzterFlowSch = 0.0f; // mittlere Flussrate des letzten Bezugs // Timer-Zustand: Anzeige laeuft displayseitig im 100-ms-Timer und haelt nach Ende 2 s nach static bool g_shotActive = false; // Wasser-Timer laeuft (Bezug ODER Spuelen/Flush) static uint32_t g_shotStartMs = 0; // displayseitiger Start (bei Bezug aus shotElapsedMs synchronisiert) @@ -403,11 +428,50 @@ static String tempStr(float v, int dec) { s += "°C"; return s; } +// Zahl mit deutschem Dezimalkomma. Die Temperaturen schreiben es laengst so (tempStr) - +// Zeiten, Gewichte und Flussraten standen bisher mit Punkt daneben. +static String zahlStr(float v, int dec, const char* einheit) { + String s(v, (unsigned int)dec); + s.replace('.', ','); + if (einheit && *einheit) { s += ' '; s += einheit; } + return s; +} + static void sw_set(lv_obj_t* sw, bool on) { if (on) lv_obj_add_state(sw, LV_STATE_CHECKED); else lv_obj_remove_state(sw, LV_STATE_CHECKED); } static bool sw_get(lv_obj_t* sw) { return lv_obj_has_state(sw, LV_STATE_CHECKED); } +// Ein Sinnbild. Die Bilddaten liegen im Flash und tragen nur Deckkraft, keine Farbe - +// eingefaerbt wird beim Zeichnen ueber den Stil. Dasselbe Zeichen dient damit in Gold, +// Tuerkis, Gruen oder Rot, ohne mehrfach im Speicher zu liegen. +static lv_obj_t* symbol(lv_obj_t* parent, const lv_image_dsc_t* bild, lv_color_t farbe) { + lv_obj_t* i = lv_image_create(parent); + lv_image_set_src(i, bild); + lv_obj_set_style_image_recolor(i, farbe, 0); + lv_obj_set_style_image_recolor_opa(i, LV_OPA_COVER, 0); + lv_obj_remove_flag(i, LV_OBJ_FLAG_CLICKABLE); + lv_obj_remove_flag(i, LV_OBJ_FLAG_SCROLLABLE); + return i; +} + +static void symbol_farbe(lv_obj_t* i, lv_color_t farbe) { + if (i) lv_obj_set_style_image_recolor(i, farbe, 0); +} + +// Waagerechte Reihe ohne eigene Optik - traegt Sinnbild und Beschriftung nebeneinander. +static lv_obj_t* zeile_blank(lv_obj_t* parent, int32_t abstand) { + lv_obj_t* r = lv_obj_create(parent); + lv_obj_remove_style_all(r); + lv_obj_set_width(r, LV_PCT(100)); + lv_obj_set_height(r, LV_SIZE_CONTENT); + lv_obj_set_flex_flow(r, LV_FLEX_FLOW_ROW); + lv_obj_set_flex_align(r, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); + lv_obj_set_style_pad_column(r, abstand, 0); + lv_obj_clear_flag(r, LV_OBJ_FLAG_SCROLLABLE); + return r; +} + // ===================================================================================== // Globaler Toast // ===================================================================================== @@ -785,6 +849,7 @@ static void populate_service(const MachineState& st) { static void flush_heatup(); // Aufheizzeit jetzt senden (entprellt / beim Seitenwechsel) static void flush_targ(); // Solltemperaturen jetzt senden (entprellt / beim Seitenwechsel) static void stats_request(); // Nutzungsstatistik anfordern (Definition weiter unten) +static void menu_aktiv_refresh(); // Definition weiter unten static void show_page(int idx) { if (idx < 0 || idx >= PG_COUNT) return; if (g_curPage == PG_TEMP && idx != PG_TEMP) { flush_heatup(); flush_targ(); } // beim Verlassen sofort sichern @@ -795,26 +860,81 @@ static void show_page(int idx) { else lv_obj_add_flag(g_pages[i], LV_OBJ_FLAG_HIDDEN); } if (g_hdrTitle) lv_label_set_text(g_hdrTitle, PAGE_NAMES[idx]); + menu_aktiv_refresh(); if (idx == PG_PROFILE && g_client) g_client->sendListProfiles(); if (idx == PG_STATS) stats_request(); // Nutzungsstatistik beim Oeffnen frisch anfordern if (idx == PG_BREW) populate_brew(g_state); // Felder beim Oeffnen frisch laden if (idx == PG_COLDEX) populate_coldex(g_state); if (idx == PG_SERVICE) populate_service(g_state); } +// ===================================================================================== +// Menue: zwoelf Seiten in vier Gruppen +// ===================================================================================== +// Als eine Liste sind zwoelf Eintraege zwoelf gleichwertige Zeilen, durch die man sucht. +// In Gruppen gebuendelt liest man vier kurze Listen und weiss schon vorher, in welcher +// man nachsieht. Die Beschriftung steht links neben ihrem Sinnbild - mittig gesetzt +// wanderte der Zeilenanfang mit der Wortlaenge, und das Auge musste ihn jedes Mal neu +// suchen. +// ===================================================================================== +struct MenuGruppe { const char* titel; uint8_t seite[4]; uint8_t anzahl; }; +static const MenuGruppe MENU_GRUPPEN[] = { + { "BETRIEB", { PG_DASH, PG_CHART, PG_STATS, PG_TEMP }, 4 }, + { "BEZUG", { PG_BREW, PG_COLDEX, PG_PROFILE, 0 }, 3 }, + { "MASCHINE", { PG_SERVICE, PG_LIGHT, 0, 0 }, 2 }, + { "SYSTEM", { PG_WIFI, PG_DISPLAY, PG_INFO, 0 }, 3 }, +}; +static const lv_image_dsc_t* const MENU_SYMBOLE[PG_COUNT] = { + &sym_haus, &sym_kurve, &sym_balken, &sym_thermometer, + &sym_tasse, &sym_schneeflocke, &sym_zahnrad, &sym_lesezeichen, + &sym_gluehbirne, &sym_wlan, &sym_regler, &sym_info, +}; +static lv_obj_t* g_menuItem[PG_COUNT] = {}; +static lv_obj_t* g_menuIcon[PG_COUNT] = {}; +static lv_obj_t* g_menuLbl[PG_COUNT] = {}; +static lv_obj_t* g_menuSide[PG_COUNT] = {}; // Nebenwert rechts in der Zeile +static lv_obj_t* g_burgerIcon = nullptr; // Menueknopf: Striche bzw. Kreuz +static bool g_maintDue = false; // Wartung faellig (faerbt den Nebenwert) + +// Der offene Eintrag ist die einzige gefuellte Flaeche im Menue - damit braucht es kein +// zweites Erkennungszeichen dafuer, wo man gerade ist. +static void menu_aktiv_refresh() { + for (int i = 0; i < PG_COUNT; i++) { + if (!g_menuItem[i]) continue; + const bool aktiv = (i == g_curPage); + lv_obj_set_style_bg_opa(g_menuItem[i], aktiv ? LV_OPA_COVER : LV_OPA_TRANSP, 0); + lv_obj_set_style_text_color(g_menuLbl[i], aktiv ? lv_color_black() : COL_TEXT, 0); + symbol_farbe(g_menuIcon[i], aktiv ? lv_color_black() : COL_TEXT_DIM); + if (g_menuSide[i]) { + lv_color_t sc = COL_TEXT_MUT; + if (aktiv) sc = lv_color_hex(0x4a3603); + else if (i == PG_SERVICE && g_maintDue) sc = COL_WARN; + lv_obj_set_style_text_color(g_menuSide[i], sc, 0); + } + } +} + static void drawer_open() { if (g_drawer) { lv_obj_remove_flag(g_drawer, LV_OBJ_FLAG_HIDDEN); lv_obj_move_foreground(g_drawer); } } static void drawer_close() { if (g_drawer) lv_obj_add_flag(g_drawer, LV_OBJ_FLAG_HIDDEN); } +// Der Knopf zeigt, was ein Tipp bewirkt: Striche zum Oeffnen, Kreuz zum Schliessen. +static void burger_icon_refresh() { + if (!g_burgerIcon || !g_drawer) return; + const bool offen = !lv_obj_has_flag(g_drawer, LV_OBJ_FLAG_HIDDEN); + lv_image_set_src(g_burgerIcon, offen ? &sym_kreuz : &sym_menue); +} static void hamburger_cb(lv_event_t*) { if (g_drawer && lv_obj_has_flag(g_drawer, LV_OBJ_FLAG_HIDDEN)) drawer_open(); else drawer_close(); + burger_icon_refresh(); } static void scrim_cb(lv_event_t* e) { // Klick auf den abdunkelnden Hintergrund schliesst - if ((lv_obj_t*)lv_event_get_target(e) == g_drawer) drawer_close(); + if ((lv_obj_t*)lv_event_get_target(e) == g_drawer) { drawer_close(); burger_icon_refresh(); } } static void nav_cb(lv_event_t* e) { int idx = (int)(intptr_t)lv_event_get_user_data(e); show_page(idx); drawer_close(); + burger_icon_refresh(); } static void brew_cell_cb(lv_event_t*) { show_page(PG_BREW); } // Tipp auf Waage-/Flow-Zelle -> Brew-Control static void err_icon_cb(lv_event_t*) { show_page(PG_DASH); } // Tipp auf Fehler-Symbol -> Dashboard (mit Fehlerbanner) @@ -1050,9 +1170,10 @@ static lv_color_t temp_value_color(lv_color_t zustand) { // Ein Kesselfeld. 'grow' verteilt die Breite zwischen den beiden, 'valueFont' bestimmt die // Groesse der Zahl, 'flat' laesst den Kartenrahmen weg und faerbt stattdessen die Flaeche. static lv_obj_t* tempField(lv_obj_t* parent, const char* title, lv_color_t accent, + const lv_image_dsc_t* bild, lv_obj_t** big, lv_obj_t** setp, lv_obj_t** bar, uint8_t grow, const lv_font_t* valueFont, - bool flat, uint32_t flatBg) { + bool flat, uint32_t flatBg, bool mitBalken = true) { lv_obj_t* c; if (flat) { c = lv_obj_create(parent); @@ -1073,7 +1194,12 @@ static lv_obj_t* tempField(lv_obj_t* parent, const char* title, lv_color_t accen lv_obj_add_flag(c, LV_OBJ_FLAG_CLICKABLE); // antippbar -> Temperatur-Seite lv_obj_add_event_cb(c, temp_card_cb, LV_EVENT_CLICKED, nullptr); - lv_obj_t* t = lv_label_create(c); + // Ueberschrift linksbuendig, mit Sinnbild davor. Mittig gesetzt wirkte sie wie eine + // Bildunterschrift zur Zahl; links gelesen ist sie das, was sie ist - die Beschriftung + // der Karte. + lv_obj_t* kopf = zeile_blank(c, 8); + symbol(kopf, bild, accent); + lv_obj_t* t = lv_label_create(kopf); lv_label_set_text(t, title); lv_obj_set_style_text_color(t, accent, 0); lv_obj_set_style_text_font(t, font_small(), 0); @@ -1110,6 +1236,10 @@ static lv_obj_t* tempField(lv_obj_t* parent, const char* title, lv_color_t accen lv_obj_set_style_text_align(*setp, LV_TEXT_ALIGN_CENTER, 0); lv_obj_set_height(*setp, lv_font_get_line_height(font_text()) + 6); + // Der Balken zeigt Ist/Soll als Fortschritt. In der Verlaufs-Darstellung sagt die + // Kurve dasselbe und mehr, deshalb entfaellt er dort. + if (!mitBalken) { *bar = nullptr; return c; } + *bar = lv_bar_create(c); lv_obj_set_size(*bar, LV_PCT(92), 8); lv_obj_set_style_bg_color(*bar, lv_color_hex(0x2c2c2c), 0); @@ -1310,6 +1440,22 @@ static void spark_dot_place(lv_obj_t* ch, lv_chart_series_t* ser, lv_obj_t* dot, lv_obj_remove_flag(dot, LV_OBJ_FLAG_HIDDEN); } +// Die Soll-Linie an ihre Hoehe setzen. Sie macht aus der Kurve erst eine Aussage: Man +// sieht nicht nur, DASS die Temperatur schwingt, sondern worum herum. Liegt der Sollwert +// ausserhalb des gezeigten Ausschnitts, bleibt sie weg - eine an den Rand geklemmte Linie +// wuerde eine Lage vortaeuschen, die nicht stimmt. +static void spark_soll_place(lv_obj_t* ch, lv_obj_t* linie, float soll, int32_t mn, int32_t mx) { + if (!ch || !linie) return; + if (mx <= mn) return; + int32_t v = (int32_t)(soll * 10.0f + (soll >= 0.0f ? 0.5f : -0.5f)); + if (v < mn || v > mx) { lv_obj_add_flag(linie, LV_OBJ_FLAG_HIDDEN); return; } + int32_t h = lv_obj_get_content_height(ch); + if (h <= 0) return; + int32_t y = h - (int32_t)(((int64_t)(v - mn) * h) / (mx - mn)); + lv_obj_align(linie, LV_ALIGN_TOP_LEFT, 0, y); + lv_obj_remove_flag(linie, LV_OBJ_FLAG_HIDDEN); +} + // Gefilterte Sekundenprobe, vom Abtaster gesetzt und vom Schritt-Timer abgeholt. static float g_probeW = 0.0f, g_probeD = 0.0f; static bool g_probeGueltig = false; @@ -1336,6 +1482,7 @@ static void spark_ranges_fit() { lv_chart_set_range(g_sparkW, LV_CHART_AXIS_PRIMARY_Y, mn, mx); } spark_dot_place(g_sparkW, g_sparkSerW, g_sparkDotW, g_sparkMinW, g_sparkMaxW); + spark_soll_place(g_sparkW, g_sparkSollW, g_state.setW, g_sparkMinW, g_sparkMaxW); } if (okD) { int32_t mn = aD - halb, mx = aD + halb; @@ -1344,6 +1491,7 @@ static void spark_ranges_fit() { lv_chart_set_range(g_sparkD, LV_CHART_AXIS_PRIMARY_Y, mn, mx); } spark_dot_place(g_sparkD, g_sparkSerD, g_sparkDotD, g_sparkMinD, g_sparkMaxD); + spark_soll_place(g_sparkD, g_sparkSollD, g_state.setD, g_sparkMinD, g_sparkMaxD); } } @@ -1379,7 +1527,7 @@ static void spark_dot_puls(lv_obj_t* dot) { } static lv_obj_t* tempSpark(lv_obj_t* parent, lv_color_t col, lv_chart_series_t** ser, - lv_obj_t** dot, float jetzt, float soll) { + lv_obj_t** dot, lv_obj_t** sollLinie, float jetzt, float soll) { lv_obj_t* ch = lv_chart_create(parent); // Die Kurve nimmt den Platz unterhalb der Zahlen ein, statt als schmaler Streifen in // der Mitte zu haengen. Sie beginnt damit weiter unten auf der Karte und hat deutlich @@ -1431,6 +1579,19 @@ static lv_obj_t* tempSpark(lv_obj_t* parent, lv_color_t col, lv_chart_series_t** lv_obj_add_flag(*dot, LV_OBJ_FLAG_HIDDEN); spark_dot_puls(*dot); + // Feine Waagerechte auf dem Sollwert. Ohne sie zeigt die Kurve nur, DASS die + // Temperatur schwingt - mit ihr sieht man, worum herum. Ihre Hoehe setzt + // spark_soll_place, sobald der Ausschnitt steht. + *sollLinie = lv_obj_create(ch); + lv_obj_remove_style_all(*sollLinie); + lv_obj_set_width(*sollLinie, LV_PCT(100)); + lv_obj_set_height(*sollLinie, 1); + lv_obj_set_style_bg_color(*sollLinie, lv_color_hex(0x707070), 0); + lv_obj_set_style_bg_opa(*sollLinie, LV_OPA_60, 0); + lv_obj_remove_flag(*sollLinie, LV_OBJ_FLAG_CLICKABLE); + lv_obj_remove_flag(*sollLinie, LV_OBJ_FLAG_SCROLLABLE); + lv_obj_add_flag(*sollLinie, LV_OBJ_FLAG_HIDDEN); + // Startwert sofort setzen. Ein frisch angelegtes Diagramm hat lauter "kein Wert"-Punkte // und zeichnet deshalb nichts - beim Umschalten der Darstellung saehe man bis zur // ersten Sekundenprobe eine leere Flaeche. @@ -1450,6 +1611,7 @@ static void build_temp_row_content() { g_sparkW = g_sparkD = nullptr; g_sparkSerW = g_sparkSerD = nullptr; g_sparkDotW = g_sparkDotD = nullptr; + g_sparkSollW = g_sparkSollD = nullptr; g_sparkMinW = g_sparkMaxW = INT32_MIN; // gemerkter Ausschnitt gilt fuer die alten Kurven g_sparkMinD = g_sparkMaxD = INT32_MIN; g_readyBand = g_readyBandLbl = nullptr; @@ -1466,23 +1628,23 @@ static void build_temp_row_content() { // Beim Espresso zaehlt die Wassertemperatur; der Dampfkessel ist Nebenwert. Also // zwei Drittel Flaeche fuer Wasser, ein Drittel fuer Dampf - die Asymmetrie ist die // Aussage, nicht ein Versehen. - tempField(g_tempRow, "WASSER", COL_ACCENT, &lblTempW, &lblSetW, &barDutyW, + tempField(g_tempRow, "WASSER", COL_ACCENT, &sym_tropfen, &lblTempW, &lblSetW, &barDutyW, 2, &lv_font_maven_pro_bold_140, false, 0); - tempField(g_tempRow, "DAMPF", teal, &lblTempD, &lblSetD, &barDutyD, + tempField(g_tempRow, "DAMPF", teal, &sym_dampf, &lblTempD, &lblSetD, &barDutyD, 1, &lv_font_maven_pro_48, false, 0); break; } case TD_VERLAUF: { - lv_obj_t* cw = tempField(g_tempRow, "WASSER", COL_ACCENT, &lblTempW, &lblSetW, &barDutyW, - 1, &lv_font_maven_pro_bold_96, false, 0); + lv_obj_t* cw = tempField(g_tempRow, "WASSER", COL_ACCENT, &sym_tropfen, &lblTempW, &lblSetW, &barDutyW, + 1, &lv_font_maven_pro_bold_96, false, 0, false); // Beide Linien weiss: Die Farbe der Karte steckt schon in der Ueberschrift, und // zwei verschiedenfarbige Linien nebeneinander wirken unruhiger als eine Sprache. - g_sparkW = tempSpark(cw, lv_color_white(), &g_sparkSerW, &g_sparkDotW, + g_sparkW = tempSpark(cw, lv_color_white(), &g_sparkSerW, &g_sparkDotW, &g_sparkSollW, g_state.tempW, g_state.setW); - lv_obj_t* cd = tempField(g_tempRow, "DAMPF", teal, &lblTempD, &lblSetD, &barDutyD, - 1, &lv_font_maven_pro_bold_96, false, 0); - g_sparkD = tempSpark(cd, lv_color_white(), &g_sparkSerD, &g_sparkDotD, + lv_obj_t* cd = tempField(g_tempRow, "DAMPF", teal, &sym_dampf, &lblTempD, &lblSetD, &barDutyD, + 1, &lv_font_maven_pro_bold_96, false, 0, false); + g_sparkD = tempSpark(cd, lv_color_white(), &g_sparkSerD, &g_sparkDotD, &g_sparkSollD, g_state.tempD, g_state.setD); spark_ranges_fit(); break; @@ -1491,9 +1653,9 @@ static void build_temp_row_content() { case TD_FLAECHEN: { // Keine Kartenkanten: Der Bereich ist in zwei Felder geteilt, getrennt nur durch // einen Hauch Helligkeitsunterschied. - tempField(g_tempRow, "WASSER", COL_ACCENT, &lblTempW, &lblSetW, &barDutyW, + tempField(g_tempRow, "WASSER", COL_ACCENT, &sym_tropfen, &lblTempW, &lblSetW, &barDutyW, 1, &lv_font_maven_pro_bold_140, true, 0x0d0d0d); - tempField(g_tempRow, "DAMPF", teal, &lblTempD, &lblSetD, &barDutyD, + tempField(g_tempRow, "DAMPF", teal, &sym_dampf, &lblTempD, &lblSetD, &barDutyD, 1, &lv_font_maven_pro_bold_140, true, 0x151515); lv_obj_set_style_pad_column(g_tempRow, 0, 0); // Felder stossen direkt aneinander break; @@ -1524,37 +1686,79 @@ static void build_temp_row_content() { lv_obj_set_style_pad_column(inner, 12, 0); lv_obj_set_flex_flow(inner, LV_FLEX_FLOW_ROW); lv_obj_clear_flag(inner, LV_OBJ_FLAG_SCROLLABLE); - tempField(inner, "WASSER", COL_ACCENT, &lblTempW, &lblSetW, &barDutyW, + tempField(inner, "WASSER", COL_ACCENT, &sym_tropfen, &lblTempW, &lblSetW, &barDutyW, 1, &lv_font_maven_pro_bold_96, false, 0); - tempField(inner, "DAMPF", teal, &lblTempD, &lblSetD, &barDutyD, + tempField(inner, "DAMPF", teal, &sym_dampf, &lblTempD, &lblSetD, &barDutyD, 1, &lv_font_maven_pro_bold_96, false, 0); break; } } } -static lv_obj_t* infoCell(lv_obj_t* parent, const char* title, lv_obj_t** val, lv_color_t accent, lv_obj_t** titleOut = nullptr) { +// Eine Kachel der unteren Zeile. Aufbau von oben nach unten: Sinnbild und Beschriftung, +// die Zahl, eine Nebenzeile (Zielwert, Vergleich, Hinweis). Der Zielwert stand frueher als +// zweite Zeile IM Wert ("24,8 g / 36,0 g") - dort konkurrierte er mit dem Messwert um +// dieselbe Groesse, obwohl er sich waehrend eines Bezugs gar nicht aendert. +// +// Feste Masse in beide Richtungen - siehe die ausfuehrliche Begruendung in tempField. +static lv_obj_t* infoCell(lv_obj_t* parent, const char* title, const lv_image_dsc_t* bild, + lv_obj_t** val, lv_color_t accent, lv_obj_t** sub = nullptr, + lv_obj_t** titleOut = nullptr, lv_obj_t** iconOut = nullptr) { lv_obj_t* card = th_card(parent); lv_obj_set_height(card, LV_PCT(100)); lv_obj_set_flex_grow(card, 1); // alle Zellen teilen sich die Breite gleichmaessig - lv_obj_set_style_pad_all(card, 6, 0); + lv_obj_set_style_pad_all(card, 10, 0); lv_obj_set_flex_flow(card, LV_FLEX_FLOW_COLUMN); - lv_obj_set_flex_align(card, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); + // Oben die Beschriftung, unten die Nebenzeile, die Zahl dazwischen - der Platz verteilt + // sich von selbst, ohne Fuellelemente. + lv_obj_set_flex_align(card, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_START); lv_obj_clear_flag(card, LV_OBJ_FLAG_SCROLLABLE); - lv_obj_t* t = lv_label_create(card); + + lv_obj_t* kopf = zeile_blank(card, 7); + lv_obj_t* ic = symbol(kopf, bild, accent); + if (iconOut) *iconOut = ic; + lv_obj_t* t = lv_label_create(kopf); lv_label_set_text(t, title); lv_obj_set_style_text_color(t, accent, 0); + lv_obj_set_style_text_font(t, font_small(), 0); + lv_obj_set_style_text_letter_space(t, 1, 0); // gesperrt gesetzt: liest sich als Etikett if (titleOut) *titleOut = t; + *val = lv_label_create(card); lv_label_set_text(*val, "--"); lv_obj_set_style_text_color(*val, COL_TEXT, 0); - lv_obj_set_style_text_font(*val, font_title(), 0); - lv_obj_set_style_text_align(*val, LV_TEXT_ALIGN_CENTER, 0); // fuer mehrzeilige Werte - // Feste Masse in BEIDE Richtungen - siehe die ausfuehrliche Begruendung in tempField. - // Zwei Zeilen Platz, weil manche Werte zweizeilig sind ("32,4 g / 36,0 g"). + lv_obj_set_style_text_font(*val, font_value(), 0); lv_obj_set_width(*val, LV_PCT(100)); - lv_obj_set_height(*val, lv_font_get_line_height(font_title()) * 2 + 6); + lv_obj_set_height(*val, lv_font_get_line_height(font_value()) + 4); + + lv_obj_t* sl = lv_label_create(card); + lv_label_set_text(sl, ""); + lv_obj_set_style_text_color(sl, COL_TEXT_MUT, 0); + lv_obj_set_style_text_font(sl, font_small(), 0); + lv_obj_set_width(sl, LV_PCT(100)); + lv_obj_set_height(sl, lv_font_get_line_height(font_small()) + 2); + if (sub) *sub = sl; + return card; } + +// Zielfortschritt unter einer Kachel (Shot-Zeit, Bezugsgewicht, Dampfzeit). +static lv_obj_t* zielBalken(lv_obj_t* card) { + lv_obj_t* b = lv_bar_create(card); + lv_obj_set_width(b, LV_PCT(100)); + lv_obj_set_height(b, 6); + lv_obj_set_style_bg_color(b, lv_color_hex(0x3a3a3a), 0); + lv_obj_set_style_bg_opa(b, LV_OPA_COVER, 0); + lv_obj_set_style_radius(b, 3, 0); + lv_obj_set_style_bg_color(b, COL_ACCENT, LV_PART_INDICATOR); + lv_obj_set_style_radius(b, 3, LV_PART_INDICATOR); + lv_bar_set_range(b, 0, 100); + lv_bar_set_value(b, 0, LV_ANIM_OFF); + // Ausserhalb eines Bezugs durchsichtig, NICHT versteckt: Ein verstecktes Element + // faellt aus dem Flex-Layout heraus, und die Zahl darueber rueckte dann bei jedem + // Bezugsbeginn ein Stueck nach unten. + lv_obj_set_style_opa(b, LV_OPA_TRANSP, 0); + return b; +} // Tipp auf die Statuszeile: Wartung -> Serviceseite, Reinigung -> Sub-Screen, // PID-Tuning -> Verlauf-Seite (dort liegen Live-Karte und Schwingungskurve) static void status_line_cb(lv_event_t*) { @@ -1637,54 +1841,31 @@ static void build_dashboard(lv_obj_t* p) { lv_obj_set_flex_flow(ir, LV_FLEX_FLOW_ROW); lv_obj_set_flex_align(ir, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); lv_obj_clear_flag(ir, LV_OBJ_FLAG_SCROLLABLE); - cellShot = infoCell(ir, "SHOT-TIMER", &lblShotTimer, COL_ACCENT); - // Brew-by-Time-Fortschrittsbalken (unter dem Shot-Timer; nur waehrend BBT-Bezug sichtbar) - g_bbtBar = lv_bar_create(cellShot); - lv_obj_set_width(g_bbtBar, LV_PCT(90)); - lv_obj_set_height(g_bbtBar, 8); - lv_obj_set_style_bg_color(g_bbtBar, lv_color_hex(0x3a3a3a), 0); - lv_obj_set_style_bg_opa(g_bbtBar, LV_OPA_COVER, 0); - lv_obj_set_style_radius(g_bbtBar, 4, 0); - lv_obj_set_style_bg_color(g_bbtBar, COL_OK, LV_PART_INDICATOR); - lv_obj_set_style_radius(g_bbtBar, 4, LV_PART_INDICATOR); - lv_bar_set_range(g_bbtBar, 0, 100); - lv_bar_set_value(g_bbtBar, 0, LV_ANIM_OFF); - lv_obj_add_flag(g_bbtBar, LV_OBJ_FLAG_HIDDEN); - cellBezug = infoCell(ir, "WAAGE", &lblBezug, COL_ACCENT); + cellShot = infoCell(ir, "SHOT", &sym_stoppuhr, &lblShotTimer, COL_ACCENT, &lblShotSub); + g_bbtBar = zielBalken(cellShot); // Brew-by-Time: verstrichen/Ziel + + cellBezug = infoCell(ir, "WAAGE", &sym_waage, &lblBezug, COL_ACCENT, &lblBezugSub); lv_obj_add_flag(cellBezug, LV_OBJ_FLAG_CLICKABLE); // antippbar -> Brew-Control lv_obj_add_event_cb(cellBezug, brew_cell_cb, LV_EVENT_CLICKED, nullptr); - // Brew-by-Weight-Fortschrittsbalken (unter dem Gewichtswert; nur waehrend BBW-Bezug sichtbar) - g_bbwBar = lv_bar_create(cellBezug); - lv_obj_set_width(g_bbwBar, LV_PCT(90)); - lv_obj_set_height(g_bbwBar, 8); - lv_obj_set_style_bg_color(g_bbwBar, lv_color_hex(0x3a3a3a), 0); - lv_obj_set_style_bg_opa(g_bbwBar, LV_OPA_COVER, 0); - lv_obj_set_style_radius(g_bbwBar, 4, 0); - lv_obj_set_style_bg_color(g_bbwBar, COL_OK, LV_PART_INDICATOR); - lv_obj_set_style_radius(g_bbwBar, 4, LV_PART_INDICATOR); - lv_bar_set_range(g_bbwBar, 0, 100); - lv_bar_set_value(g_bbwBar, 0, LV_ANIM_OFF); - lv_obj_add_flag(g_bbwBar, LV_OBJ_FLAG_HIDDEN); - cellFlow = infoCell(ir, "FLOW", &lblFlow, lv_color_hex(0x64b5f6)); + g_bbwBar = zielBalken(cellBezug); // Brew-by-Weight: Gewicht/Ziel + + // Die Flusskachel steht dauerhaft, auch wenn gerade nichts laeuft. Frueher erschien sie + // erst mit dem Bezug - dabei ruecken alle anderen Kacheln zur Seite, und genau in dem + // Moment schaut man hin. Im Ruhezustand traegt sie den Mittelwert des letzten Bezugs. + cellFlow = infoCell(ir, "FLOW", &sym_fluss, &lblFlow, lv_color_hex(0x64b5f6), &lblFlowSub); lv_obj_add_flag(cellFlow, LV_OBJ_FLAG_CLICKABLE); // antippbar -> Brew-Control lv_obj_add_event_cb(cellFlow, brew_cell_cb, LV_EVENT_CLICKED, nullptr); - cellSteam = infoCell(ir, "DAMPF-TIMER", &lblSteamTimer, lv_color_hex(0x80cbc4)); - // Steam-by-Time-Fortschrittsbalken (unter dem Dampf-Timer; nur waehrend SBT-Dampfbezug sichtbar) - g_sbtBar = lv_bar_create(cellSteam); - lv_obj_set_width(g_sbtBar, LV_PCT(90)); - lv_obj_set_height(g_sbtBar, 8); - lv_obj_set_style_bg_color(g_sbtBar, lv_color_hex(0x3a3a3a), 0); - lv_obj_set_style_bg_opa(g_sbtBar, LV_OPA_COVER, 0); - lv_obj_set_style_radius(g_sbtBar, 4, 0); - lv_obj_set_style_bg_color(g_sbtBar, COL_OK, LV_PART_INDICATOR); - lv_obj_set_style_radius(g_sbtBar, 4, LV_PART_INDICATOR); - lv_bar_set_range(g_sbtBar, 0, 100); - lv_bar_set_value(g_sbtBar, 0, LV_ANIM_OFF); - lv_obj_add_flag(g_sbtBar, LV_OBJ_FLAG_HIDDEN); - // Kombi-Zelle: zeigt Eco-Info und/oder Gehaeusetemperatur (abwechselnd, siehe refresh_eco_case) - cellEco = infoCell(ir, "ECO", &lblEco, COL_OK, &lblEcoTitle); - lv_obj_add_flag(cellFlow, LV_OBJ_FLAG_HIDDEN); // nur waehrend Brew-by-Weight-Bezug (+ Nachhalten) - lv_obj_add_flag(cellEco, LV_OBJ_FLAG_HIDDEN); // erst zeigen, wenn Eco-Info und/oder Gehaeusesensor aktiv + + cellSteam = infoCell(ir, "DAMPF", &sym_dampf, &lblSteamTimer, lv_color_hex(0x80cbc4), &lblSteamSub); + g_sbtBar = zielBalken(cellSteam); // Steam-by-Time: verstrichen/Ziel + + cellEco = infoCell(ir, "ECO", &sym_blatt, &lblEco, COL_OK, &lblEcoSub, &lblEcoTitle, &icoEco); + cellCase = infoCell(ir, "TASSENABLAGE", &sym_tasse, &lblCase, lv_color_hex(0xffb74d), + &lblCaseSub, &lblCaseTitle, &icoCase); + + // Beide zeigen sich, sobald es etwas zu zeigen gibt - unabhaengig voneinander. + lv_obj_add_flag(cellEco, LV_OBJ_FLAG_HIDDEN); // erst zeigen, wenn die S3 Eco-Info meldet + lv_obj_add_flag(cellCase, LV_OBJ_FLAG_HIDDEN); // erst zeigen, wenn ein Zusatzsensor da ist } // ===================================================================================== @@ -3581,48 +3762,50 @@ static void build_stats(lv_obj_t* p) { stat_list_build(p); } +static void label_fmt_if_changed(lv_obj_t* lbl, const char* fmt, ...); // Definition weiter unten +static void label_color_if_changed(lv_obj_t* lbl, lv_color_t col); // Definition weiter unten + // ===================================================================================== -// Kombi-Zelle Eco / Gehaeuse -// - nur Eco aktiv -> Eco-Info -// - nur Gehaeuse aktiv -> Gehaeusetemperatur (an Stelle der Eco-Anzeige) -// - beide aktiv -> Wechsel alle 5 s (eco_case_timer_cb togglet g_ecoCasePhase) +// Eco-Kachel und Kachel des Zusatzsensors // ===================================================================================== -static void refresh_eco_case() { +// Beide hingen frueher in EINER Kachel und wechselten sich alle 5 s ab. Das war sparsam +// mit dem Platz und teuer fuer den Betrachter: Wer die Temperatur der Tassenablage sehen +// wollte, musste warten, bis sie wieder an der Reihe war - und wer auf den Eco-Countdown +// schaute, verlor ihn alle fuenf Sekunden. Jetzt hat jede ihre eigene Kachel und beide +// stehen dauerhaft. +// ===================================================================================== +static void refresh_eco() { if (!cellEco) return; - bool ecoShow = g_state.ecoShowInfo; - bool caseShow = g_state.hasCaseTemp; - if (!ecoShow && !caseShow) { lv_obj_add_flag(cellEco, LV_OBJ_FLAG_HIDDEN); return; } + if (!g_state.ecoShowInfo) { lv_obj_add_flag(cellEco, LV_OBJ_FLAG_HIDDEN); return; } lv_obj_remove_flag(cellEco, LV_OBJ_FLAG_HIDDEN); - bool showCase = caseShow && (!ecoShow || g_ecoCasePhase); - if (showCase) { - // Sensorart 1 = Tassenablage, sonst Gehaeuse - lv_label_set_text(lblEcoTitle, g_state.caseSensorType == 1 ? "TASSENABLAGE" : "GEHÄUSE"); - lv_obj_set_style_text_color(lblEcoTitle, lv_color_hex(0xffb74d), 0); - lv_label_set_text(lblEco, tempStr(g_state.caseTemp, 1).c_str()); - lv_obj_set_style_text_color(lblEco, COL_TEXT, 0); + if (g_state.ecoActive) { + label_set_if_changed(lblEcoTitle, "ECO"); + label_set_if_changed(lblEco, "AKTIV"); + label_color_if_changed(lblEco, COL_OK); + label_set_if_changed(lblEcoSub, "Kessel abgesenkt"); + } else if (g_state.ecoCountdownSec >= 0) { + long sek = g_state.ecoCountdownSec; + label_set_if_changed(lblEcoTitle, "ECO IN"); + if (sek >= 60) label_fmt_if_changed(lblEco, "%ld min", sek / 60); + else label_fmt_if_changed(lblEco, "%ld s", sek); + label_color_if_changed(lblEco, COL_TEXT); + label_set_if_changed(lblEcoSub, "ohne Bedienung"); } else { - lv_obj_set_style_text_color(lblEcoTitle, COL_OK, 0); - if (g_state.ecoActive) { - lv_label_set_text(lblEcoTitle, "ECO"); - lv_label_set_text(lblEco, "AKTIV"); - lv_obj_set_style_text_color(lblEco, COL_OK, 0); - } else if (g_state.ecoCountdownSec >= 0) { - lv_label_set_text(lblEcoTitle, "ECO IN"); - long s = g_state.ecoCountdownSec; - if (s >= 60) lv_label_set_text_fmt(lblEco, "%ld min", s / 60); - else lv_label_set_text_fmt(lblEco, "%ld s", s); - lv_obj_set_style_text_color(lblEco, COL_TEXT, 0); - } else { - lv_label_set_text(lblEcoTitle, "ECO"); - lv_label_set_text(lblEco, "AUS"); - lv_obj_set_style_text_color(lblEco, COL_TEXT_DIM, 0); - } + label_set_if_changed(lblEcoTitle, "ECO"); + label_set_if_changed(lblEco, "AUS"); + label_color_if_changed(lblEco, COL_TEXT_DIM); + label_set_if_changed(lblEcoSub, "kein Zeitgeber"); } } -static void eco_case_timer_cb(lv_timer_t*) { - g_ecoCasePhase = !g_ecoCasePhase; - refresh_eco_case(); + +static void refresh_case() { + if (!cellCase) return; + if (!g_state.hasCaseTemp) { lv_obj_add_flag(cellCase, LV_OBJ_FLAG_HIDDEN); return; } + lv_obj_remove_flag(cellCase, LV_OBJ_FLAG_HIDDEN); + // Sensorart 1 = Tassenablage, sonst Gehaeuse + label_set_if_changed(lblCaseTitle, g_state.caseSensorType == 1 ? "TASSENABLAGE" : "GEHÄUSE"); + label_set_if_changed(lblCase, tempStr(g_state.caseTemp, 1).c_str()); } // ===================================================================================== @@ -3778,7 +3961,6 @@ static void status_line_tick() { static void dash_timers_cb(lv_timer_t*) { uint32_t now = millis(); - char buf[24]; if (lblShotTimer) { if (g_shotActive) { g_shotFrozenMs = now - g_shotStartMs; @@ -3789,15 +3971,21 @@ static void dash_timers_cb(lv_timer_t*) { if (g_scaleTaring && !g_shotActive) { // Tarier-Phase vor Brew-by-Weight: signalisieren, dass die Waage genullt wird label_set_if_changed(lblShotTimer, "Tariere..."); + label_set_if_changed(lblShotSub, "Waage wird genullt"); } else if (g_shotActive || (int32_t)(g_shotHoldUntil - now) > 0) { float el = g_shotFrozenMs / 1000.0f; - if (g_shotBbtMode) snprintf(buf, sizeof(buf), "%.1f s\n/ %.1f s", el, g_bbtTarget); // Ist/Ziel - else snprintf(buf, sizeof(buf), "%.1f s", el); - label_set_if_changed(lblShotTimer, buf); + label_set_if_changed(lblShotTimer, zahlStr(el, 1, "s").c_str()); + // Der Zielwert gehoert in die Nebenzeile, nicht in den Wert: Er aendert sich + // waehrend des Bezugs nicht und muss deshalb nicht so gross sein wie die + // laufende Zeit, mit der er sich bisher denselben Platz geteilt hat. + if (g_shotWasFlush) label_set_if_changed(lblShotSub, "Spülen"); + else if (g_shotBbtMode && g_bbtTarget > 0.0f) label_set_if_changed(lblShotSub, ("Ziel " + zahlStr(g_bbtTarget, 1, "s")).c_str()); + else label_set_if_changed(lblShotSub, "läuft"); } else { - strcpy(buf, "--"); g_shotBbtMode = false; // nach dem Nachhalten zuruecksetzen - label_set_if_changed(lblShotTimer, buf); + label_set_if_changed(lblShotTimer, "0,0 s"); + if (g_letzteShotSek > 0.0f) label_set_if_changed(lblShotSub, ("zuletzt " + zahlStr(g_letzteShotSek, 1, "s")).c_str()); + else label_set_if_changed(lblShotSub, "kein Bezug"); } // Brew-by-Time-Fortschrittsbalken (verstrichen/Ziel), nur waehrend eines BBT-Bezugs if (g_bbtBar) { @@ -3805,9 +3993,9 @@ static void dash_timers_cb(lv_timer_t*) { int pct = (int)(g_shotFrozenMs / (g_bbtTarget * 1000.0f) * 100.0f + 0.5f); if (pct < 0) pct = 0; if (pct > 100) pct = 100; lv_bar_set_value(g_bbtBar, pct, LV_ANIM_OFF); - lv_obj_remove_flag(g_bbtBar, LV_OBJ_FLAG_HIDDEN); + lv_obj_set_style_opa(g_bbtBar, LV_OPA_COVER, 0); } else { - lv_obj_add_flag(g_bbtBar, LV_OBJ_FLAG_HIDDEN); + lv_obj_set_style_opa(g_bbtBar, LV_OPA_TRANSP, 0); } } } @@ -3819,13 +4007,16 @@ static void dash_timers_cb(lv_timer_t*) { } if (g_steamActive || (int32_t)(g_steamHoldUntil - now) > 0) { float el = g_steamFrozenMs / 1000.0f; - if (g_steamSbtMode) snprintf(buf, sizeof(buf), "%.1f s\n/ %.1f s", el, g_sbtTarget); // Ist/Ziel - else snprintf(buf, sizeof(buf), "%.1f s", el); - label_set_if_changed(lblSteamTimer, buf); + label_set_if_changed(lblSteamTimer, zahlStr(el, 1, "s").c_str()); + if (g_steamSbtMode && g_sbtTarget > 0.0f) label_set_if_changed(lblSteamSub, ("Ziel " + zahlStr(g_sbtTarget, 1, "s")).c_str()); + else label_set_if_changed(lblSteamSub, "läuft"); } else { - strcpy(buf, "--"); g_steamSbtMode = false; // nach dem Nachhalten zuruecksetzen - label_set_if_changed(lblSteamTimer, buf); + label_set_if_changed(lblSteamTimer, "0,0 s"); + if (g_state.sbtEnabled && g_state.sbtSecs > 0.0f) + label_set_if_changed(lblSteamSub, ("Abschaltung " + zahlStr(g_state.sbtSecs, 0, "s")).c_str()); + else + label_set_if_changed(lblSteamSub, "ohne Zeitziel"); } // Steam-by-Time-Fortschrittsbalken (verstrichen/Ziel), nur waehrend eines SBT-Dampfbezugs if (g_sbtBar) { @@ -3833,23 +4024,33 @@ static void dash_timers_cb(lv_timer_t*) { int pct = (int)(g_steamFrozenMs / (g_sbtTarget * 1000.0f) * 100.0f + 0.5f); if (pct < 0) pct = 0; if (pct > 100) pct = 100; lv_bar_set_value(g_sbtBar, pct, LV_ANIM_OFF); - lv_obj_remove_flag(g_sbtBar, LV_OBJ_FLAG_HIDDEN); + lv_obj_set_style_opa(g_sbtBar, LV_OPA_COVER, 0); } else { - lv_obj_add_flag(g_sbtBar, LV_OBJ_FLAG_HIDDEN); + lv_obj_set_style_opa(g_sbtBar, LV_OPA_TRANSP, 0); } } } - // Flow-Anzeige: Bezugswert (waehrend Bezug + 2,5 s Nachhalten), sonst 0,0 g/s - if (cellFlow && !lv_obj_has_flag(cellFlow, LV_OBJ_FLAG_HIDDEN)) { + // Flow-Anzeige: Bezugswert (waehrend Bezug + 2,5 s Nachhalten), sonst 0,0 g/s. + // Die Kachel steht dauerhaft; im Ruhezustand traegt die Nebenzeile den Mittelwert des + // letzten Bezugs - der sagt beim Nachschmecken mehr als der Momentanwert. + if (lblFlow) { if ((int32_t)(g_flowHoldUntil - now) > 0) { - // Wie bei der Waage: winzige negative Flusswerte nicht als "-0.0 g/s" zeigen. + // Wie bei der Waage: winzige negative Flusswerte nicht als "-0,0 g/s" zeigen. float fDisp = g_flowFrozen; if (fDisp > -0.05f && fDisp <= 0.0f) fDisp = 0.0f; - snprintf(buf, sizeof(buf), "%.1f g/s", fDisp); + label_set_if_changed(lblFlow, zahlStr(fDisp, 1, "g/s").c_str()); + float sek = g_shotFrozenMs / 1000.0f; + if (g_shotActive && !g_shotWasFlush && sek > 1.0f && g_state.weight > 0.0f) + label_set_if_changed(lblFlowSub, ("Mittel " + zahlStr(g_state.weight / sek, 1, "g/s")).c_str()); + else + label_set_if_changed(lblFlowSub, "läuft"); } else { - strcpy(buf, "0.0 g/s"); + label_set_if_changed(lblFlow, "0,0 g/s"); + if (g_letzterFlowSch > 0.0f) + label_set_if_changed(lblFlowSub, ("zuletzt " + zahlStr(g_letzterFlowSch, 1, "g/s")).c_str()); + else + label_set_if_changed(lblFlowSub, "kein Bezug"); } - label_set_if_changed(lblFlow, buf); } // Live-Bezugsschirm (Werte/Kurve/Zielfortschritt im 100-ms-Takt) brew_live_tick(); @@ -3970,8 +4171,8 @@ void ui_init(ProtocolClient* client) { { Preferences prefs; prefs.begin("ui", false); // Vorgabe ist jetzt TD_BAND. Aeltere Staende haben hier Werte der frueheren fuenf // Darstellungen stehen - liegt der Wert ausserhalb, faellt er auf die Vorgabe zurueck. - g_tempDesign = prefs.getUChar("tempdsgn", TD_BAND); - if (g_tempDesign >= TD_DESIGN_COUNT) g_tempDesign = TD_BAND; + g_tempDesign = prefs.getUChar("tempdsgn", TD_VERLAUF); + if (g_tempDesign >= TD_DESIGN_COUNT) g_tempDesign = TD_VERLAUF; g_brewLiveEnabled = prefs.getBool("brewlive", true); g_tempColored = prefs.getBool("tempcol", false); g_clockSize = prefs.getUChar("uhrgr", UHR_GROSS); @@ -4003,7 +4204,10 @@ void ui_init(ProtocolClient* client) { lv_obj_set_flex_align(header, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); lv_obj_clear_flag(header, LV_OBJ_FLAG_SCROLLABLE); - lv_obj_t* burger = th_button(header, LV_SYMBOL_LIST, COL_CARD2, COL_TEXT); + lv_obj_t* burger = th_button(header, "", COL_CARD2, COL_TEXT); + lv_obj_clean(burger); // die leere Beschriftung von th_button weicht dem Sinnbild + g_burgerIcon = symbol(burger, &sym_menue, COL_TEXT); + lv_obj_center(g_burgerIcon); lv_obj_set_size(burger, 48, 36); // Der Knopf bleibt optisch klein, faengt Tipps aber auch knapp daneben ab. 48x36 Pixel // sind auf dem 7-Zoll-Panel ein sehr kleines Ziel; gemessen wurde ein Fehlgriff von @@ -4119,25 +4323,73 @@ void ui_init(ProtocolClient* client) { lv_obj_add_event_cb(g_drawer, scrim_cb, LV_EVENT_CLICKED, nullptr); lv_obj_t* menu = lv_obj_create(g_drawer); - lv_obj_set_size(menu, 240, LV_PCT(100)); + lv_obj_set_size(menu, 340, LV_PCT(100)); lv_obj_set_pos(menu, 0, 0); - lv_obj_set_style_bg_color(menu, COL_BG2, 0); + lv_obj_set_style_bg_color(menu, COL_CARD2, 0); lv_obj_set_style_border_width(menu, 0, 0); + lv_obj_set_style_border_side(menu, LV_BORDER_SIDE_RIGHT, 0); + lv_obj_set_style_border_color(menu, lv_color_hex(0x242424), 0); + lv_obj_set_style_border_width(menu, 1, 0); lv_obj_set_style_radius(menu, 0, 0); - lv_obj_set_style_pad_all(menu, 8, 0); - lv_obj_set_style_pad_row(menu, 6, 0); + lv_obj_set_style_pad_all(menu, 12, 0); + lv_obj_set_style_pad_row(menu, 2, 0); lv_obj_set_flex_flow(menu, LV_FLEX_FLOW_COLUMN); - lv_obj_set_scroll_dir(menu, LV_DIR_VER); // bei vielen Eintraegen vertikal scrollbar + lv_obj_set_scroll_dir(menu, LV_DIR_VER); // bei grosser Schrift vertikal scrollbar scroll_ohne_nachlauf(menu); lv_obj_set_scrollbar_mode(menu, LV_SCROLLBAR_MODE_AUTO); - for (int i = 0; i < PG_COUNT; i++) { - lv_obj_t* mb = th_button(menu, PAGE_NAMES[i], COL_CARD, COL_TEXT); - lv_obj_set_width(mb, LV_PCT(100)); - lv_obj_set_height(mb, 52); - lv_obj_set_style_flex_grow(mb, 0, 0); // feste Hoehe, nicht stauchen - lv_obj_clear_flag(mb, LV_OBJ_FLAG_SCROLLABLE); // Button selbst faengt keine Scrolls ab - lv_obj_add_event_cb(mb, nav_cb, LV_EVENT_CLICKED, (void*)(intptr_t)i); + + // Zeilenhoehe knapp bemessen, damit alle zwoelf Seiten samt Gruppenueberschriften + // ohne Scrollen auf das Panel passen - eine Liste, in der man rollen muss, um den + // letzten Eintrag zu sehen, verliert ihren Vorteil gegenueber der alten. + const int32_t zeileH = lv_font_get_line_height(font_text()) + 18; + for (size_t g = 0; g < sizeof(MENU_GRUPPEN) / sizeof(MENU_GRUPPEN[0]); g++) { + const MenuGruppe& gr = MENU_GRUPPEN[g]; + lv_obj_t* cap = lv_label_create(menu); + lv_label_set_text(cap, gr.titel); + lv_obj_set_style_text_color(cap, lv_color_hex(0x5e5e5e), 0); + lv_obj_set_style_text_font(cap, font_small(), 0); + lv_obj_set_style_text_letter_space(cap, 2, 0); + lv_obj_set_style_pad_top(cap, (g == 0) ? 2 : 10, 0); + lv_obj_set_style_pad_bottom(cap, 3, 0); + lv_obj_set_style_pad_left(cap, 14, 0); + + for (uint8_t k = 0; k < gr.anzahl; k++) { + const uint8_t seite = gr.seite[k]; + lv_obj_t* mb = lv_obj_create(menu); + lv_obj_remove_style_all(mb); + lv_obj_set_width(mb, LV_PCT(100)); + lv_obj_set_height(mb, zeileH); + lv_obj_set_style_flex_grow(mb, 0, 0); // feste Hoehe, nicht stauchen + lv_obj_set_style_radius(mb, zeileH / 2, 0); + lv_obj_set_style_bg_color(mb, COL_ACCENT, 0); + lv_obj_set_style_bg_opa(mb, LV_OPA_TRANSP, 0); + lv_obj_set_style_pad_hor(mb, 14, 0); + lv_obj_set_flex_flow(mb, LV_FLEX_FLOW_ROW); + lv_obj_set_flex_align(mb, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); + lv_obj_set_style_pad_column(mb, 12, 0); + lv_obj_clear_flag(mb, LV_OBJ_FLAG_SCROLLABLE); + lv_obj_add_flag(mb, LV_OBJ_FLAG_CLICKABLE); + lv_obj_add_event_cb(mb, nav_cb, LV_EVENT_CLICKED, (void*)(intptr_t)seite); + + g_menuIcon[seite] = symbol(mb, MENU_SYMBOLE[seite], COL_TEXT_DIM); + g_menuLbl[seite] = lv_label_create(mb); + lv_label_set_text(g_menuLbl[seite], PAGE_NAMES[seite]); + lv_obj_set_style_text_color(g_menuLbl[seite], COL_TEXT, 0); + lv_obj_set_style_text_font(g_menuLbl[seite], font_text(), 0); + // Die Beschriftung nimmt den Rest der Breite und schiebt den Nebenwert + // an den rechten Rand - ohne zusaetzliches Fuellelement. + lv_obj_set_flex_grow(g_menuLbl[seite], 1); + + g_menuSide[seite] = lv_label_create(mb); + lv_label_set_text(g_menuSide[seite], ""); + lv_obj_set_style_text_color(g_menuSide[seite], COL_TEXT_MUT, 0); + lv_obj_set_style_text_font(g_menuSide[seite], font_small(), 0); + g_menuItem[seite] = mb; + } } + // Der Nebenwert der Info-Zeile aendert sich nie - einmal setzen genuegt. + if (g_menuSide[PG_INFO]) lv_label_set_text(g_menuSide[PG_INFO], DISPLAY_FW_VERSION); + menu_aktiv_refresh(); // --- Reinigungsassistent-Sub-Screen (oberste Ebene, unter Tastatur/Toast/Overlays) --- build_cleaning_screen(); @@ -4353,7 +4605,6 @@ void ui_init(ProtocolClient* client) { ui_fade_in(g_splash, UI_FADE_MS); // weiches Erscheinen beim Boot lv_timer_create(dash_timers_cb, 100, nullptr); // Timer-Anzeige fortlaufend aktualisieren - lv_timer_create(eco_case_timer_cb, 5000, nullptr); // Eco/Gehaeuse alle 5 s wechseln lv_timer_create(chart_sample_cb, 1000, nullptr); // Verlauf jede Sekunde abtasten lv_timer_create(spark_step_cb, DASH_SPARK_STEP_MS, nullptr); // Kurven weich fortschreiben @@ -4711,6 +4962,23 @@ void ui_update(const MachineState& st) { // Intervall aktiv und Zaehler hat das Intervall erreicht/ueberschritten) bool maintDue = (st.maintenanceInterval > 0) && (st.maintenanceIntervalCounter >= (uint32_t)st.maintenanceInterval); + // Nebenwerte im Menue: was auf der Seite dahinter gerade gilt, ohne sie zu oeffnen. + if (g_menuSide[PG_TEMP]) + label_fmt_if_changed(g_menuSide[PG_TEMP], "%d / %d", (int)lroundf(st.setW), (int)lroundf(st.setD)); + if (g_menuSide[PG_PROFILE]) + label_set_if_changed(g_menuSide[PG_PROFILE], + st.activeProfile.length() + ? (st.activeProfile + (st.profileDirty ? "*" : "")).c_str() + : ""); + if (g_menuSide[PG_LIGHT]) label_set_if_changed(g_menuSide[PG_LIGHT], st.lightOn ? "An" : "Aus"); + if (g_menuSide[PG_WIFI]) + label_set_if_changed(g_menuSide[PG_WIFI], st.wifiConnected ? st.ssid.c_str() : "getrennt"); + if (g_menuSide[PG_SERVICE] && g_maintDue != maintDue) { + g_maintDue = maintDue; + label_set_if_changed(g_menuSide[PG_SERVICE], maintDue ? "fällig" : ""); + menu_aktiv_refresh(); + } + if (g_maintIcon) { if (maintDue) lv_obj_remove_flag(g_maintIcon, LV_OBJ_FLAG_HIDDEN); else lv_obj_add_flag(g_maintIcon, LV_OBJ_FLAG_HIDDEN); @@ -4956,6 +5224,14 @@ void ui_update(const MachineState& st) { ? g_shotFlushCapMs : (millis() - g_shotStartMs); g_shotHoldUntil = millis() + 2000; // Anzeige macht dash_timers_cb + // Dauer und mittlere Flussrate des Bezugs festhalten. Beide stehen danach in + // den Nebenzeilen von Shot- und Flow-Kachel - im Ruhezustand ist das die + // einzige Zahl, die dort noch etwas aussagt. + if (!g_shotWasFlush) { + g_letzteShotSek = g_shotFrozenMs / 1000.0f; + float gew = (st.weight > 0.0f) ? st.weight : st.lastShotWeight; + g_letzterFlowSch = (g_letzteShotSek > 0.5f && gew > 0.0f) ? (gew / g_letzteShotSek) : 0.0f; + } } g_shotActive = false; g_piShotMode = false; // Phasenleiste ausblenden (pi_bar_update) @@ -5016,11 +5292,14 @@ void ui_update(const MachineState& st) { if (wDisp > -0.05f && wDisp <= 0.0f) wDisp = 0.0f; if (!st.scaleEnabled) { label_set_if_changed(lblBezug, "--"); - } else if (bbwShot) { - // Waehrend des Bezugs mit Brew-by-Weight: Ist oben, Ziel darunter (zweizeilig) - label_fmt_if_changed(lblBezug, "%.1f g\n/ %.1f g", wDisp, shotTarget); + label_set_if_changed(lblBezugSub, "Waage aus"); } else { - label_fmt_if_changed(lblBezug, "%.1f g", wDisp); + label_set_if_changed(lblBezug, zahlStr(wDisp, 1, "g").c_str()); + // Der Zielwert ist immer der EINGESTELLTE Wert, ohne den Nachlauf-Offset. Der + // Offset korrigiert den Abschaltzeitpunkt; ihn in das Ziel einzurechnen wuerde + // eine Zahl anzeigen, die so nirgends eingestellt ist. + if (shotTarget > 0.0f) label_set_if_changed(lblBezugSub, ("Ziel " + zahlStr(shotTarget, 1, "g")).c_str()); + else label_set_if_changed(lblBezugSub, "ohne Zielgewicht"); } // Fortschrittsbalken Gewicht/Ziel (nur waehrend BBW-Bezug) if (g_bbwBar) { @@ -5028,27 +5307,29 @@ void ui_update(const MachineState& st) { int pct = (int)(st.weight / shotTarget * 100.0f + 0.5f); if (pct < 0) pct = 0; if (pct > 100) pct = 100; lv_bar_set_value(g_bbwBar, pct, LV_ANIM_OFF); - lv_obj_remove_flag(g_bbwBar, LV_OBJ_FLAG_HIDDEN); + lv_obj_set_style_opa(g_bbwBar, LV_OPA_COVER, 0); } else { - lv_obj_add_flag(g_bbwBar, LV_OBJ_FLAG_HIDDEN); + lv_obj_set_style_opa(g_bbwBar, LV_OPA_TRANSP, 0); } } } - // Flow-Zelle: permanent sichtbar, sobald Brew-by-Weight aktiviert ist. + // Flow-Zelle: dauerhaft sichtbar. Sie erschien frueher erst mit dem Bezug - dabei + // ruecken alle anderen Kacheln zur Seite, und genau in dem Moment schaut man hin. // (Anzeige selbst macht dash_timers_cb: Bezugswert + 2,5 s Nachhalten, sonst 0,0 g/s.) if (cellFlow) { - if (st.bbwEnabled) { - lv_obj_remove_flag(cellFlow, LV_OBJ_FLAG_HIDDEN); - if (st.shotActive) { - g_flowFrozen = st.flowRate; - g_flowHoldUntil = millis() + 2500; - } - } else { - lv_obj_add_flag(cellFlow, LV_OBJ_FLAG_HIDDEN); + // Die Flussrate kommt von der Waage. Ohne Waage gibt es nichts zu zeigen - das + // haengt an der Einstellung, nicht am Bezug, also rueckt waehrend eines Bezugs + // trotzdem nichts. + if (st.scaleEnabled) lv_obj_remove_flag(cellFlow, LV_OBJ_FLAG_HIDDEN); + else lv_obj_add_flag(cellFlow, LV_OBJ_FLAG_HIDDEN); + if (st.shotActive) { + g_flowFrozen = st.flowRate; + g_flowHoldUntil = millis() + 2500; } } - // Kombi-Zelle Eco/Gehaeuse (Sichtbarkeit + Inhalt; Wechsel macht eco_case_timer_cb) - refresh_eco_case(); + // Eco und Zusatzsensor: je eigene Kachel, beide dauerhaft + refresh_eco(); + refresh_case(); // Temperatur-Seite (Drehregler nicht ueberschreiben, wenn gerade bedient wird) if (lblTargW && (millis() - g_targEditMs > 1500)) { diff --git a/P4_Display_Firmware/ui_symbole.c b/P4_Display_Firmware/ui_symbole.c new file mode 100644 index 0000000..12d968e --- /dev/null +++ b/P4_Display_Firmware/ui_symbole.c @@ -0,0 +1,697 @@ +// ===================================================================================== +// ui_symbole.c - Sinnbilder der Oberflaeche als Deckkraftbilder +// ===================================================================================== +// ERZEUGT - nicht von Hand aendern. +// Quelle: Werkzeuge/symbole_erzeugen.py (dort liegen die Zeichnungen) +// Neu erzeugen: cd P4_Display_Firmware/Werkzeuge && python symbole_erzeugen.py +// +// Jedes Bild traegt nur Deckkraft (LV_COLOR_FORMAT_A8), keine Farbe. Eingefaerbt wird +// beim Zeichnen ueber den Stil 'image_recolor' - dasselbe Zeichen dient damit in Gold, +// Tuerkis, Gruen, Orange oder Rot, ohne mehrfach im Speicher zu liegen. Die Daten sind +// const und liegen im Flash; im RAM steht nur der Bildkopf. +// ===================================================================================== + +#include "ui_symbole.h" + +static const uint8_t sym_balken_map[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa6, 0xa6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x09, 0xe0, 0x5a, 0x00, 0x00, 0x00, 0xbf, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x15, 0xff, 0x6a, 0x00, 0x00, 0x00, 0xbf, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x15, 0xff, 0x6a, 0x00, 0x00, 0x00, 0xbf, 0xbf, 0x00, 0x00, 0x00, 0x47, 0xb8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x15, 0xff, 0x6a, 0x00, 0x00, 0x00, 0xbf, 0xbf, 0x00, 0x00, 0x00, 0x6a, 0xff, 0x15, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x15, 0xff, 0x6a, 0x00, 0x00, 0x00, 0xbf, 0xbf, 0x00, 0x00, 0x00, 0x6a, 0xff, 0x15, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x15, 0xff, 0x6a, 0x00, 0x00, 0x00, 0xbf, 0xbf, 0x00, 0x00, 0x00, 0x6a, 0xff, 0x15, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x15, 0xff, 0x6a, 0x00, 0x00, 0x00, 0xbf, 0xbf, 0x00, 0x00, 0x00, 0x6a, 0xff, 0x15, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x15, 0xff, 0x6a, 0x00, 0x00, 0x00, 0xbf, 0xbf, 0x00, 0x00, 0x00, 0x6a, 0xff, 0x15, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x15, 0xff, 0x6a, 0x00, 0x00, 0x00, 0xbf, 0xbf, 0x00, 0x00, 0x00, 0x6a, 0xff, 0x15, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +const lv_image_dsc_t sym_balken = { + .header = { .magic = LV_IMAGE_HEADER_MAGIC, .cf = LV_COLOR_FORMAT_A8, + .flags = 0, .w = 20, .h = 20, .stride = 20, .reserved_2 = 0 }, + .data_size = sizeof(sym_balken_map), + .data = sym_balken_map, + .reserved = NULL, +}; + +static const uint8_t sym_blatt_map[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x15, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x75, 0xb0, 0xdc, 0xfc, 0xff, 0xff, 0x3c, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0xbf, 0xff, 0xff, 0xd6, 0xa6, 0x85, 0x71, 0xff, 0x39, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0xa6, 0xff, 0xd5, 0x71, 0x1f, 0x00, 0x00, 0x00, 0x5b, 0xff, 0x27, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xc5, 0xff, 0x75, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0x07, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x9d, 0xff, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0xb7, 0xcf, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x26, 0xff, 0x85, 0x00, 0x00, 0x00, 0x00, 0x5d, 0xde, 0xff, 0x15, 0xff, 0x8a, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x67, 0xff, 0x23, 0x00, 0x00, 0x00, 0x9b, 0xff, 0xc1, 0x48, 0x7b, 0xff, 0x32, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0x01, 0x00, 0x00, 0xae, 0xff, 0x7d, 0x00, 0x26, 0xf9, 0xab, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x66, 0xff, 0x2c, 0x00, 0x93, 0xff, 0x67, 0x00, 0x14, 0xc8, 0xf2, 0x24, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1a, 0xfe, 0xae, 0x4b, 0xff, 0x86, 0x00, 0x4f, 0xda, 0xff, 0x4d, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x67, 0xff, 0xf1, 0xd9, 0xb0, 0xde, 0xff, 0xd0, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0xff, 0xcc, 0xcf, 0xa9, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0xff, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +const lv_image_dsc_t sym_blatt = { + .header = { .magic = LV_IMAGE_HEADER_MAGIC, .cf = LV_COLOR_FORMAT_A8, + .flags = 0, .w = 20, .h = 20, .stride = 20, .reserved_2 = 0 }, + .data_size = sizeof(sym_blatt_map), + .data = sym_blatt_map, + .reserved = NULL, +}; + +static const uint8_t sym_dampf_map[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0c, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x0c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x95, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x95, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0c, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x0c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x96, 0xf2, 0x00, 0x06, 0xc5, 0xb8, 0x00, 0x37, 0xf3, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x51, 0xff, 0x7f, 0x00, 0x8c, 0xff, 0x50, 0x00, 0xc7, 0xdf, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x6b, 0xff, 0x1d, 0x00, 0xaa, 0xd7, 0x00, 0x00, 0xe9, 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x2f, 0xff, 0x6e, 0x00, 0x6c, 0xff, 0x33, 0x00, 0xa8, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc5, 0xcc, 0x00, 0x13, 0xff, 0x91, 0x00, 0x4e, 0xff, 0x56, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0xff, 0x92, 0x00, 0x99, 0xff, 0x5d, 0x00, 0xc8, 0xf8, 0x25, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x94, 0xed, 0x00, 0x00, 0xd2, 0xad, 0x00, 0x20, 0xff, 0x6e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc2, 0xc8, 0x00, 0x0d, 0xfe, 0x8b, 0x00, 0x49, 0xff, 0x4e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x2e, 0xff, 0x75, 0x00, 0x69, 0xff, 0x39, 0x00, 0xa4, 0xec, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0x17, 0x00, 0xbf, 0xc9, 0x00, 0x00, 0xff, 0x8d, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +const lv_image_dsc_t sym_dampf = { + .header = { .magic = LV_IMAGE_HEADER_MAGIC, .cf = LV_COLOR_FORMAT_A8, + .flags = 0, .w = 20, .h = 20, .stride = 20, .reserved_2 = 0 }, + .data_size = sizeof(sym_dampf_map), + .data = sym_dampf_map, + .reserved = NULL, +}; + +static const uint8_t sym_fluss_map[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa6, 0xa6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0xff, 0xff, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0xff, 0xab, 0xab, 0xff, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcd, 0xe3, 0x15, 0x15, 0xe3, 0xcd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x95, 0xff, 0x4d, 0x00, 0x00, 0x4d, 0xff, 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x5d, 0xff, 0x84, 0x00, 0x00, 0x00, 0x00, 0x84, 0xff, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x45, 0xff, 0x4d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0xff, 0x45, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x68, 0xff, 0x19, 0xf2, 0x61, 0x00, 0x00, 0x00, 0x00, 0x19, 0xff, 0x68, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x5a, 0xff, 0x2b, 0xf8, 0x99, 0x00, 0x00, 0x00, 0x00, 0x2b, 0xff, 0x5a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x22, 0xff, 0x81, 0x86, 0xff, 0xbc, 0x7b, 0x00, 0x00, 0x81, 0xff, 0x22, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xff, 0x4f, 0x71, 0xc8, 0x99, 0x00, 0x4f, 0xff, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xc7, 0xff, 0xa1, 0x60, 0x60, 0xa1, 0xff, 0xc7, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x8b, 0xec, 0xff, 0xff, 0xec, 0x8b, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +const lv_image_dsc_t sym_fluss = { + .header = { .magic = LV_IMAGE_HEADER_MAGIC, .cf = LV_COLOR_FORMAT_A8, + .flags = 0, .w = 20, .h = 20, .stride = 20, .reserved_2 = 0 }, + .data_size = sizeof(sym_fluss_map), + .data = sym_fluss_map, + .reserved = NULL, +}; + +static const uint8_t sym_gluehbirne_map[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x4e, 0x4e, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0xa8, 0xff, 0xff, 0xff, 0xff, 0xa8, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xd2, 0xff, 0x7f, 0x37, 0x37, 0x7f, 0xff, 0xd2, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x96, 0xff, 0x43, 0x00, 0x00, 0x00, 0x00, 0x43, 0xff, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0xf6, 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x95, 0xf6, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x26, 0xff, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a, 0xff, 0x26, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1d, 0xff, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0xff, 0x1d, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0xb7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0xb7, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0xff, 0x20, 0x35, 0x70, 0xaa, 0xe4, 0xff, 0xff, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0xa4, 0xff, 0xff, 0xdb, 0xcc, 0xa4, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xd5, 0x1d, 0x00, 0xd4, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xd5, 0x40, 0x40, 0xd4, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0xff, 0xff, 0xff, 0xff, 0xd5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x40, 0x40, 0x40, 0x40, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a, 0xea, 0xea, 0xea, 0xea, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2f, 0x95, 0x95, 0x95, 0x95, 0x2f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +const lv_image_dsc_t sym_gluehbirne = { + .header = { .magic = LV_IMAGE_HEADER_MAGIC, .cf = LV_COLOR_FORMAT_A8, + .flags = 0, .w = 20, .h = 20, .stride = 20, .reserved_2 = 0 }, + .data_size = sizeof(sym_gluehbirne_map), + .data = sym_gluehbirne_map, + .reserved = NULL, +}; + +static const uint8_t sym_haken_map[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0xa6, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9d, 0xff, 0x6d, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x92, 0xff, 0x78, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, 0xff, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x47, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xff, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xb8, 0xff, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x71, 0xff, 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x12, 0xc7, 0xff, 0x4e, 0x00, 0x00, 0x66, 0xff, 0xa4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x12, 0xc7, 0xff, 0x4e, 0x5b, 0xff, 0xaf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0xc7, 0xff, 0xff, 0xba, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0xc7, 0xc5, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +const lv_image_dsc_t sym_haken = { + .header = { .magic = LV_IMAGE_HEADER_MAGIC, .cf = LV_COLOR_FORMAT_A8, + .flags = 0, .w = 20, .h = 20, .stride = 20, .reserved_2 = 0 }, + .data_size = sizeof(sym_haken_map), + .data = sym_haken_map, + .reserved = NULL, +}; + +static const uint8_t sym_haus_map[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0xeb, 0xeb, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, 0xff, 0xd3, 0xd3, 0xff, 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0xff, 0xbb, 0x13, 0x13, 0xbb, 0xff, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x8b, 0xff, 0xa3, 0x00, 0x00, 0x00, 0x00, 0xa3, 0xff, 0x8b, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xa3, 0xff, 0x8b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8b, 0xff, 0xa3, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x12, 0xbb, 0xff, 0xff, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0xff, 0xff, 0xbb, 0x12, 0x00, 0x00, + 0x00, 0x00, 0x66, 0xff, 0x5b, 0xff, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0xff, 0x5b, 0xff, 0x66, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x12, 0x55, 0xff, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0xff, 0x55, 0x12, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x55, 0xff, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0xff, 0x55, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x55, 0xff, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0xff, 0x55, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x55, 0xff, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0xff, 0x55, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x55, 0xff, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0xff, 0x55, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x55, 0xff, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0xff, 0x55, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x55, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x55, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +const lv_image_dsc_t sym_haus = { + .header = { .magic = LV_IMAGE_HEADER_MAGIC, .cf = LV_COLOR_FORMAT_A8, + .flags = 0, .w = 20, .h = 20, .stride = 20, .reserved_2 = 0 }, + .data_size = sizeof(sym_haus_map), + .data = sym_haus_map, + .reserved = NULL, +}; + +static const uint8_t sym_info_map[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x7e, 0xc0, 0xe2, 0xe2, 0xc2, 0x82, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xff, 0xff, 0xc2, 0x9d, 0x9d, 0xc5, 0xff, 0xff, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xa1, 0xff, 0x9e, 0x24, 0x00, 0x00, 0x00, 0x00, 0x23, 0x9d, 0xff, 0x9f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x80, 0xff, 0x74, 0x00, 0x00, 0x00, 0x36, 0x37, 0x00, 0x00, 0x00, 0x76, 0xff, 0x7e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x20, 0xff, 0x9e, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x9b, 0xff, 0x22, 0x00, 0x00, + 0x00, 0x00, 0x80, 0xff, 0x24, 0x00, 0x00, 0x00, 0x00, 0x36, 0x37, 0x00, 0x00, 0x00, 0x00, 0x21, 0xff, 0x7f, 0x00, 0x00, + 0x00, 0x00, 0xc3, 0xc2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc5, 0xc0, 0x00, 0x00, + 0x00, 0x00, 0xe5, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9e, 0xe1, 0x00, 0x00, + 0x00, 0x00, 0xe5, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9e, 0xe1, 0x00, 0x00, + 0x00, 0x00, 0xc3, 0xc2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc5, 0xc0, 0x00, 0x00, + 0x00, 0x00, 0x80, 0xff, 0x24, 0x00, 0x00, 0x00, 0x00, 0xbf, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x21, 0xff, 0x7f, 0x00, 0x00, + 0x00, 0x00, 0x20, 0xff, 0x9e, 0x00, 0x00, 0x00, 0x00, 0xbf, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x9b, 0xff, 0x22, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x80, 0xff, 0x74, 0x00, 0x00, 0x00, 0x8a, 0x8a, 0x00, 0x00, 0x00, 0x76, 0xff, 0x7e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xa1, 0xff, 0x9e, 0x24, 0x00, 0x00, 0x00, 0x00, 0x23, 0x9d, 0xff, 0x9f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xff, 0xff, 0xc2, 0x9d, 0x9d, 0xc5, 0xff, 0xff, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x7e, 0xc0, 0xe2, 0xe2, 0xc2, 0x82, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +const lv_image_dsc_t sym_info = { + .header = { .magic = LV_IMAGE_HEADER_MAGIC, .cf = LV_COLOR_FORMAT_A8, + .flags = 0, .w = 20, .h = 20, .stride = 20, .reserved_2 = 0 }, + .data_size = sizeof(sym_info_map), + .data = sym_info_map, + .reserved = NULL, +}; + +static const uint8_t sym_kreuz_map[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x15, 0xff, 0xb6, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xb6, 0xff, 0x15, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x60, 0xff, 0xd4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x30, 0xd4, 0xff, 0x60, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0xe6, 0xf3, 0x4e, 0x00, 0x00, 0x4e, 0xf3, 0xe6, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0xc8, 0xff, 0x6d, 0x6d, 0xff, 0xc8, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xaa, 0xff, 0xff, 0xaa, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xaa, 0xff, 0xff, 0xaa, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0xc8, 0xff, 0x6d, 0x6d, 0xff, 0xc8, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0xe6, 0xf3, 0x4e, 0x00, 0x00, 0x4e, 0xf3, 0xe6, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x60, 0xff, 0xd4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x30, 0xd4, 0xff, 0x60, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x15, 0xff, 0xb6, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xb6, 0xff, 0x15, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +const lv_image_dsc_t sym_kreuz = { + .header = { .magic = LV_IMAGE_HEADER_MAGIC, .cf = LV_COLOR_FORMAT_A8, + .flags = 0, .w = 20, .h = 20, .stride = 20, .reserved_2 = 0 }, + .data_size = sizeof(sym_kreuz_map), + .data = sym_kreuz_map, + .reserved = NULL, +}; + +static const uint8_t sym_kurve_map[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x5a, 0xe0, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x6a, 0xff, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x6a, 0xff, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8a, 0x8a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x6a, 0xff, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0xff, 0x8e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x6a, 0xff, 0x15, 0x00, 0x00, 0x00, 0x0c, 0x32, 0x00, 0x00, 0x00, 0xd5, 0xd5, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x6a, 0xff, 0x15, 0x00, 0x00, 0x00, 0xb8, 0xff, 0x4e, 0x00, 0x8e, 0xff, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x6a, 0xff, 0x15, 0x00, 0x00, 0x89, 0xff, 0xc7, 0xff, 0x4e, 0xff, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x6a, 0xff, 0x15, 0x00, 0x5b, 0xff, 0x8f, 0x12, 0xc7, 0xff, 0xd5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x6a, 0xff, 0x15, 0x2c, 0xf6, 0xbd, 0x00, 0x00, 0x12, 0xb8, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x6a, 0xff, 0x15, 0xc8, 0xec, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x6a, 0xff, 0x15, 0x81, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x6a, 0xff, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x6a, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x12, 0x00, 0x00, + 0x00, 0x00, 0x66, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x66, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +const lv_image_dsc_t sym_kurve = { + .header = { .magic = LV_IMAGE_HEADER_MAGIC, .cf = LV_COLOR_FORMAT_A8, + .flags = 0, .w = 20, .h = 20, .stride = 20, .reserved_2 = 0 }, + .data_size = sizeof(sym_kurve_map), + .data = sym_kurve_map, + .reserved = NULL, +}; + +static const uint8_t sym_lesezeichen_map[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0xff, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0xff, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0xff, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xff, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0xff, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xff, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0xff, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xff, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0xff, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xff, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0xff, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xff, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0xff, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xff, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0xff, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xff, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0xff, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xff, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0xff, 0x40, 0x00, 0x39, 0xd1, 0xd1, 0x39, 0x00, 0x40, 0xff, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0xff, 0x40, 0x6e, 0xff, 0xe0, 0xe0, 0xff, 0x6e, 0x40, 0xff, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0xff, 0xa3, 0xff, 0xab, 0x13, 0x13, 0xab, 0xff, 0xa3, 0xff, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0xff, 0xff, 0x76, 0x00, 0x00, 0x00, 0x00, 0x76, 0xff, 0xff, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x22, 0xbf, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0xbf, 0x22, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +const lv_image_dsc_t sym_lesezeichen = { + .header = { .magic = LV_IMAGE_HEADER_MAGIC, .cf = LV_COLOR_FORMAT_A8, + .flags = 0, .w = 20, .h = 20, .stride = 20, .reserved_2 = 0 }, + .data_size = sizeof(sym_lesezeichen_map), + .data = sym_lesezeichen_map, + .reserved = NULL, +}; + +static const uint8_t sym_menue_map[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xd4, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xd4, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x89, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x89, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xb0, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xb0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xb0, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xb0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x89, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x89, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xd5, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xd5, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +const lv_image_dsc_t sym_menue = { + .header = { .magic = LV_IMAGE_HEADER_MAGIC, .cf = LV_COLOR_FORMAT_A8, + .flags = 0, .w = 20, .h = 20, .stride = 20, .reserved_2 = 0 }, + .data_size = sizeof(sym_menue_map), + .data = sym_menue_map, + .reserved = NULL, +}; + +static const uint8_t sym_regler_map[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x69, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0xff, 0xff, 0xff, 0x88, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x12, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0xff, 0x8e, 0x16, 0x8d, 0xff, 0x6a, 0x12, 0x00, 0x00, + 0x00, 0x00, 0x66, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x44, 0x00, 0x44, 0xff, 0xff, 0x66, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0xed, 0xca, 0x6b, 0xc9, 0xee, 0x15, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, 0xdb, 0xff, 0xdc, 0x4d, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x4c, 0xdb, 0xff, 0xdc, 0x4d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x15, 0xed, 0xca, 0x6b, 0xc9, 0xee, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x66, 0xff, 0xff, 0x44, 0x00, 0x44, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x66, 0x00, 0x00, + 0x00, 0x00, 0x12, 0x6a, 0xff, 0x8e, 0x16, 0x8d, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x12, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x88, 0xff, 0xff, 0xff, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x69, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +const lv_image_dsc_t sym_regler = { + .header = { .magic = LV_IMAGE_HEADER_MAGIC, .cf = LV_COLOR_FORMAT_A8, + .flags = 0, .w = 20, .h = 20, .stride = 20, .reserved_2 = 0 }, + .data_size = sizeof(sym_regler_map), + .data = sym_regler_map, + .reserved = NULL, +}; + +static const uint8_t sym_schneeflocke_map[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0xbf, 0xbf, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xff, 0xcc, 0xbf, 0xbf, 0xcc, 0xff, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x66, 0x1c, 0x00, 0x00, 0x51, 0xdb, 0xff, 0xff, 0xdb, 0x51, 0x00, 0x00, 0x1c, 0x66, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x12, 0xff, 0xf9, 0x79, 0x00, 0x00, 0x05, 0xbf, 0xbf, 0x05, 0x00, 0x00, 0x79, 0xf9, 0xff, 0x12, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x28, 0xa8, 0xff, 0xd6, 0x56, 0x00, 0xbf, 0xbf, 0x00, 0x56, 0xd6, 0xff, 0xa8, 0x28, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x4b, 0xcb, 0xff, 0xb3, 0xbf, 0xbf, 0xb3, 0xff, 0xcb, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0xed, 0xff, 0xff, 0xed, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0xed, 0xff, 0xff, 0xed, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x4b, 0xcb, 0xff, 0xb3, 0xbf, 0xbf, 0xb3, 0xff, 0xcb, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x28, 0xa8, 0xff, 0xd6, 0x56, 0x00, 0xbf, 0xbf, 0x00, 0x56, 0xd6, 0xff, 0xa8, 0x28, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x12, 0xff, 0xf9, 0x79, 0x00, 0x00, 0x05, 0xbf, 0xbf, 0x05, 0x00, 0x00, 0x79, 0xf9, 0xff, 0x12, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x66, 0x1c, 0x00, 0x00, 0x51, 0xdb, 0xff, 0xff, 0xdb, 0x51, 0x00, 0x00, 0x1c, 0x66, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xff, 0xcc, 0xbf, 0xbf, 0xcc, 0xff, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0xbf, 0xbf, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +const lv_image_dsc_t sym_schneeflocke = { + .header = { .magic = LV_IMAGE_HEADER_MAGIC, .cf = LV_COLOR_FORMAT_A8, + .flags = 0, .w = 20, .h = 20, .stride = 20, .reserved_2 = 0 }, + .data_size = sizeof(sym_schneeflocke_map), + .data = sym_schneeflocke_map, + .reserved = NULL, +}; + +static const uint8_t sym_stoppuhr_map[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x15, 0x15, 0x15, 0x15, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x6a, 0xbf, 0xbf, 0x6a, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xd4, 0x2a, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x94, 0xe5, 0xff, 0xff, 0xe2, 0x91, 0x1f, 0x3f, 0xf4, 0xd6, 0x18, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x57, 0xf7, 0xff, 0xa6, 0x72, 0x74, 0xa5, 0xff, 0xf8, 0x6d, 0xd5, 0x21, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x48, 0xff, 0xbe, 0x25, 0x00, 0x59, 0x59, 0x00, 0x25, 0xbc, 0xff, 0x44, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xd0, 0xd5, 0x0a, 0x00, 0x00, 0xbf, 0xbf, 0x00, 0x00, 0x08, 0xd5, 0xcd, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x45, 0xff, 0x5b, 0x00, 0x00, 0x00, 0xbf, 0xbf, 0x00, 0x00, 0x00, 0x58, 0xff, 0x47, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7e, 0xff, 0x08, 0x00, 0x00, 0x00, 0xbf, 0xbf, 0x00, 0x00, 0x00, 0x0a, 0xff, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x91, 0xed, 0x00, 0x00, 0x00, 0x00, 0xbf, 0xbf, 0x00, 0x00, 0x00, 0x00, 0xea, 0x95, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7e, 0xff, 0x08, 0x00, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x00, 0x0a, 0xff, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x45, 0xff, 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0xff, 0x47, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xd0, 0xd5, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xd5, 0xcd, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x48, 0xff, 0xbe, 0x25, 0x00, 0x00, 0x00, 0x00, 0x25, 0xbc, 0xff, 0x44, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x57, 0xf7, 0xff, 0xa6, 0x72, 0x74, 0xa5, 0xff, 0xf8, 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x94, 0xe5, 0xff, 0xff, 0xe2, 0x91, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +const lv_image_dsc_t sym_stoppuhr = { + .header = { .magic = LV_IMAGE_HEADER_MAGIC, .cf = LV_COLOR_FORMAT_A8, + .flags = 0, .w = 20, .h = 20, .stride = 20, .reserved_2 = 0 }, + .data_size = sizeof(sym_stoppuhr_map), + .data = sym_stoppuhr_map, + .reserved = NULL, +}; + +static const uint8_t sym_tasse_map[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x2f, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x6a, 0xff, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xaa, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x6a, 0xff, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0xff, 0xf1, 0x2d, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x6a, 0xff, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0xaa, 0xf8, 0x94, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x6a, 0xff, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0xaa, 0xdf, 0xa4, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x68, 0xff, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0xb5, 0xff, 0x56, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x46, 0xff, 0x4d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xff, 0xd6, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xe0, 0xc2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0xff, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x56, 0xff, 0xc2, 0x4d, 0x19, 0x15, 0x37, 0xa0, 0xff, 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x56, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x09, 0x15, 0x15, 0x15, 0x46, 0x68, 0x6a, 0x54, 0x15, 0x15, 0x15, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x5a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x2f, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +const lv_image_dsc_t sym_tasse = { + .header = { .magic = LV_IMAGE_HEADER_MAGIC, .cf = LV_COLOR_FORMAT_A8, + .flags = 0, .w = 20, .h = 20, .stride = 20, .reserved_2 = 0 }, + .data_size = sizeof(sym_tasse_map), + .data = sym_tasse_map, + .reserved = NULL, +}; + +static const uint8_t sym_thermometer_map[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xac, 0xff, 0xff, 0xac, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0xff, 0x6b, 0x6b, 0xff, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6a, 0xff, 0x15, 0x15, 0xff, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6a, 0xff, 0x15, 0x15, 0xff, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6a, 0xff, 0xb8, 0xb8, 0xff, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6a, 0xff, 0xbf, 0xbf, 0xff, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6a, 0xff, 0xbf, 0xbf, 0xff, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6a, 0xff, 0xbf, 0xbf, 0xff, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0xf6, 0xff, 0xbf, 0xbf, 0xff, 0xf6, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xda, 0x20, 0xbf, 0xbf, 0x20, 0xda, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0xff, 0x64, 0x00, 0x6a, 0x6a, 0x00, 0x64, 0xff, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0xff, 0x43, 0x00, 0x00, 0x00, 0x00, 0x43, 0xff, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xff, 0x84, 0x00, 0x00, 0x00, 0x00, 0x84, 0xff, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xff, 0x64, 0x00, 0x00, 0x64, 0xff, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xb5, 0xff, 0xf6, 0xf6, 0xff, 0xb5, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, 0x8b, 0x8b, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +const lv_image_dsc_t sym_thermometer = { + .header = { .magic = LV_IMAGE_HEADER_MAGIC, .cf = LV_COLOR_FORMAT_A8, + .flags = 0, .w = 20, .h = 20, .stride = 20, .reserved_2 = 0 }, + .data_size = sizeof(sym_thermometer_map), + .data = sym_thermometer_map, + .reserved = NULL, +}; + +static const uint8_t sym_tropfen_map[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa6, 0xa6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0xff, 0xff, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0xff, 0xab, 0xab, 0xff, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcd, 0xe3, 0x15, 0x15, 0xe3, 0xcd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x95, 0xff, 0x4d, 0x00, 0x00, 0x4d, 0xff, 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x5d, 0xff, 0x84, 0x00, 0x00, 0x00, 0x00, 0x84, 0xff, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x45, 0xff, 0x4d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0xff, 0x45, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x68, 0xff, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xff, 0x68, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x5a, 0xff, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0xff, 0x5a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x22, 0xff, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0xff, 0x22, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xff, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x4f, 0xff, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xc7, 0xff, 0xa1, 0x60, 0x60, 0xa1, 0xff, 0xc7, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x8b, 0xec, 0xff, 0xff, 0xec, 0x8b, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +const lv_image_dsc_t sym_tropfen = { + .header = { .magic = LV_IMAGE_HEADER_MAGIC, .cf = LV_COLOR_FORMAT_A8, + .flags = 0, .w = 20, .h = 20, .stride = 20, .reserved_2 = 0 }, + .data_size = sizeof(sym_tropfen_map), + .data = sym_tropfen_map, + .reserved = NULL, +}; + +static const uint8_t sym_waage_map[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa6, 0xa6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x2f, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0xbf, 0xbf, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x2f, 0x00, 0x00, + 0x00, 0x00, 0x5a, 0xea, 0xea, 0xff, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xff, 0xea, 0xea, 0x5a, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xc2, 0xde, 0xff, 0x79, 0x00, 0xbf, 0xbf, 0x00, 0x79, 0xff, 0xde, 0xc2, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x65, 0xff, 0x5f, 0xa9, 0xf8, 0x1b, 0xbf, 0xbf, 0x1b, 0xf8, 0xa9, 0x5f, 0xff, 0x65, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x07, 0xe4, 0xbc, 0x40, 0x40, 0xff, 0x9b, 0xbf, 0xbf, 0x9b, 0xff, 0x40, 0x40, 0xbc, 0xe4, 0x07, 0x00, 0x00, + 0x00, 0x00, 0x6a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x6a, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x3c, 0xbf, 0xbf, 0x3c, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x69, 0x6a, 0x6a, 0x6a, 0x6a, 0xbf, 0xbf, 0x6a, 0x6a, 0x6a, 0x6a, 0x69, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x27, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x14, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x14, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +const lv_image_dsc_t sym_waage = { + .header = { .magic = LV_IMAGE_HEADER_MAGIC, .cf = LV_COLOR_FORMAT_A8, + .flags = 0, .w = 20, .h = 20, .stride = 20, .reserved_2 = 0 }, + .data_size = sizeof(sym_waage_map), + .data = sym_waage_map, + .reserved = NULL, +}; + +static const uint8_t sym_warnung_map[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcf, 0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6d, 0xff, 0xff, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0xe9, 0xb5, 0xb5, 0xe9, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, 0xff, 0x39, 0x39, 0xff, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x25, 0xff, 0x9b, 0x22, 0x22, 0x9b, 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xfe, 0x1f, 0xbf, 0xbf, 0x1f, 0xfe, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0x81, 0x00, 0xbf, 0xbf, 0x00, 0x81, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xbb, 0xe4, 0x05, 0x00, 0xbf, 0xbf, 0x00, 0x05, 0xe4, 0xbb, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x59, 0xff, 0x67, 0x00, 0x00, 0xbf, 0xbf, 0x00, 0x00, 0x67, 0xff, 0x59, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xd5, 0xca, 0x00, 0x00, 0x00, 0x6a, 0x6a, 0x00, 0x00, 0x00, 0xca, 0xd5, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x73, 0xff, 0x4d, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x4d, 0xff, 0x73, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x11, 0xef, 0xb0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xb0, 0xef, 0x11, 0x00, 0x00, + 0x00, 0x00, 0x8d, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0xff, 0x8d, 0x00, 0x00, + 0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, + 0x00, 0x00, 0x09, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x09, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +const lv_image_dsc_t sym_warnung = { + .header = { .magic = LV_IMAGE_HEADER_MAGIC, .cf = LV_COLOR_FORMAT_A8, + .flags = 0, .w = 20, .h = 20, .stride = 20, .reserved_2 = 0 }, + .data_size = sizeof(sym_warnung_map), + .data = sym_warnung_map, + .reserved = NULL, +}; + +static const uint8_t sym_wlan_map[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0xbc, 0xf1, 0xff, 0xff, 0xf1, 0xbc, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x53, 0xdd, 0xff, 0xd1, 0x94, 0x74, 0x74, 0x94, 0xd1, 0xff, 0xdd, 0x53, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x77, 0xff, 0xc6, 0x48, 0x00, 0x01, 0x26, 0x26, 0x01, 0x00, 0x48, 0xc6, 0xff, 0x77, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x64, 0xff, 0x9e, 0x00, 0x2f, 0xa3, 0xf6, 0xff, 0xff, 0xf6, 0xa3, 0x2f, 0x00, 0x9e, 0xff, 0x64, 0x00, 0x00, + 0x00, 0x1e, 0xfb, 0xb3, 0x00, 0x64, 0xff, 0xf1, 0x92, 0x5e, 0x5e, 0x92, 0xf1, 0xff, 0x64, 0x00, 0xb3, 0xfb, 0x1e, 0x00, + 0x00, 0x89, 0xff, 0x26, 0x48, 0xff, 0xb3, 0x17, 0x00, 0x37, 0x37, 0x00, 0x17, 0xb3, 0xff, 0x48, 0x26, 0xff, 0x89, 0x00, + 0x00, 0x0d, 0x3e, 0x00, 0xcc, 0xd3, 0x03, 0x4e, 0xde, 0xff, 0xff, 0xde, 0x4e, 0x03, 0xd3, 0xcc, 0x00, 0x3e, 0x0d, 0x00, + 0x00, 0x00, 0x00, 0x0a, 0xe2, 0x5c, 0x20, 0xf9, 0xca, 0x52, 0x52, 0xca, 0xf9, 0x20, 0x5c, 0xe2, 0x0a, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xff, 0x24, 0xff, 0xff, 0x24, 0xff, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x46, 0x08, 0xff, 0xff, 0x08, 0x46, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +const lv_image_dsc_t sym_wlan = { + .header = { .magic = LV_IMAGE_HEADER_MAGIC, .cf = LV_COLOR_FORMAT_A8, + .flags = 0, .w = 20, .h = 20, .stride = 20, .reserved_2 = 0 }, + .data_size = sizeof(sym_wlan_map), + .data = sym_wlan_map, + .reserved = NULL, +}; + +static const uint8_t sym_zahnrad_map[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x59, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x39, 0x79, 0x00, 0x5d, 0xb5, 0xe3, 0xe1, 0xb4, 0x5e, 0x00, 0x79, 0x39, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x79, 0xff, 0xb6, 0xff, 0xd6, 0xa6, 0xa6, 0xd4, 0xff, 0xb3, 0xff, 0x79, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4, 0xff, 0x65, 0x00, 0x00, 0x00, 0x00, 0x64, 0xff, 0xb4, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x5c, 0xff, 0x63, 0x00, 0x7f, 0xdc, 0xdc, 0x7f, 0x00, 0x65, 0xff, 0x5f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xb3, 0xd5, 0x00, 0x7f, 0xff, 0xab, 0xaa, 0xff, 0x7f, 0x00, 0xd6, 0xb6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x59, 0xbf, 0xe2, 0xa6, 0x00, 0xdd, 0xaa, 0x00, 0x00, 0xab, 0xdc, 0x00, 0xa6, 0xe1, 0xbf, 0x59, 0x00, 0x00, + 0x00, 0x00, 0x59, 0xbf, 0xe2, 0xa6, 0x00, 0xdd, 0xaa, 0x00, 0x00, 0xab, 0xdc, 0x00, 0xa6, 0xe1, 0xbf, 0x59, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xb3, 0xd5, 0x00, 0x7f, 0xff, 0xab, 0xaa, 0xff, 0x7f, 0x00, 0xd6, 0xb6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x5c, 0xff, 0x63, 0x00, 0x7f, 0xdc, 0xdc, 0x7f, 0x00, 0x65, 0xff, 0x5f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4, 0xff, 0x65, 0x00, 0x00, 0x00, 0x00, 0x64, 0xff, 0xb4, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x79, 0xff, 0xb6, 0xff, 0xd6, 0xa6, 0xa6, 0xd4, 0xff, 0xb3, 0xff, 0x79, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x39, 0x79, 0x00, 0x5d, 0xb5, 0xe3, 0xe1, 0xb4, 0x5e, 0x00, 0x79, 0x39, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x59, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +const lv_image_dsc_t sym_zahnrad = { + .header = { .magic = LV_IMAGE_HEADER_MAGIC, .cf = LV_COLOR_FORMAT_A8, + .flags = 0, .w = 20, .h = 20, .stride = 20, .reserved_2 = 0 }, + .data_size = sizeof(sym_zahnrad_map), + .data = sym_zahnrad_map, + .reserved = NULL, +}; + diff --git a/P4_Display_Firmware/ui_symbole.h b/P4_Display_Firmware/ui_symbole.h new file mode 100644 index 0000000..3ef33bb --- /dev/null +++ b/P4_Display_Firmware/ui_symbole.h @@ -0,0 +1,41 @@ +// ===================================================================================== +// ui_symbole.h - Sinnbilder der Oberflaeche (erzeugt, siehe ui_symbole.c) +// ===================================================================================== + +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// Kantenlaenge aller Sinnbilder in Pixeln +#define UI_SYMBOL_SIZE 20 + +extern const lv_image_dsc_t sym_balken; +extern const lv_image_dsc_t sym_blatt; +extern const lv_image_dsc_t sym_dampf; +extern const lv_image_dsc_t sym_fluss; +extern const lv_image_dsc_t sym_gluehbirne; +extern const lv_image_dsc_t sym_haken; +extern const lv_image_dsc_t sym_haus; +extern const lv_image_dsc_t sym_info; +extern const lv_image_dsc_t sym_kreuz; +extern const lv_image_dsc_t sym_kurve; +extern const lv_image_dsc_t sym_lesezeichen; +extern const lv_image_dsc_t sym_menue; +extern const lv_image_dsc_t sym_regler; +extern const lv_image_dsc_t sym_schneeflocke; +extern const lv_image_dsc_t sym_stoppuhr; +extern const lv_image_dsc_t sym_tasse; +extern const lv_image_dsc_t sym_thermometer; +extern const lv_image_dsc_t sym_tropfen; +extern const lv_image_dsc_t sym_waage; +extern const lv_image_dsc_t sym_warnung; +extern const lv_image_dsc_t sym_wlan; +extern const lv_image_dsc_t sym_zahnrad; + +#ifdef __cplusplus +} +#endif