FT817 / BT817 / BT81x GUI Widgets for Arduino and others

In diesem Artikel werden wir uns einem spannenden Thema widmen: der Erstellung einer Widget-Bibliothek für FT81x-Chips unter Nutzung der bestehenden EVE4-Bibliothek von Rudolph Riedel (github). Wir werden das Problem erklären, unsere Lösung vorstellen und die Vorteile beleuchten.

Einleitung

BT81x-Chips von Bridgetek bieten eine leistungsfähige Plattform für die Ansteuerung von Displays in Embedded-Systemen. Sie ermöglichen die Erstellung beeindruckender Benutzeroberflächen mit minimalem Aufwand. Dennoch kann die Verwaltung von Widgets, wie Texten und Buttons, in komplexen Anwendungen eine Herausforderung darstellen. Genau hier kommt unsere Lösung ins Spiel.

Das Problem

Beim Arbeiten mit BT81x-Chips und der EVE4-Bibliothek stellt sich oft das Problem, dass die Bibliothek keine objektorientierte Verwaltung von Widgets unterstützt. Stattdessen wird die Displayliste direkt manipuliert, was den Code unübersichtlich und schwer wartbar macht. Widgets können keine eigenen Zustände verwalten, was zu Problemen führt, wenn Änderungen an der Benutzeroberfläche vorgenommen werden müssen.

Herausforderungen

  • Komplexität: Direkte Manipulation der Displayliste führt zu komplexem und unübersichtlichem Code.
  • Wartbarkeit: Änderungen an der Benutzeroberfläche sind schwer zu implementieren.
  • Erweiterbarkeit: Hinzufügen neuer Widgets erfordert umfangreiche Änderungen im Code.

GUIs im 8-Bit-Umfeld: Eine Herausforderung für Arduino

Die Erstellung von grafischen Benutzeroberflächen (GUIs) auf 8-Bit-Mikrocontrollern wie dem Arduino stellt eine erhebliche Herausforderung dar. Dies liegt vor allem an den begrenzten Ressourcen, die diese Mikrocontroller zur Verfügung stellen. Typische 8-Bit-Mikrocontroller, wie der ATmega328P im Arduino Uno, verfügen nur über 2 KB RAM und 32 KB Flash-Speicher. Diese Einschränkungen machen es schwierig, aufwendige Grafiken und interaktive Elemente darzustellen. Mit dem BT81x z.B. dem BT817 von Bridgetek, wird dieses Problem jedoch elegant gelöst.

Unsere Lösung

Um diese Herausforderungen zu bewältigen, haben wir eine einfache Widget-Bibliothek entwickelt, die eine objektorientierte Verwaltung von Widgets ermöglicht. Diese Bibliothek basiert auf der EVE4-Bibliothek von Rudolph Riedel und erweitert deren Funktionalität.

Widget-Klasse

Wir haben eine generische Widget-Klasse erstellt, die als Basis für spezifische Widgets wie TextWidget und Button dient. Diese Klasse verwaltet grundlegende Eigenschaften wie Position, Größe und Farbe.

Screen-Klasse

Die Screen-Klasse ermöglicht die Verwaltung mehrerer Widgets und deren Zeichnung auf dem Display. Widgets können hinzugefügt, entfernt und aktualisiert werden.

ScreenManager-Klasse

Der ScreenManager verwaltet mehrere Screens und ermöglicht das einfache Wechseln zwischen ihnen. Dadurch können verschiedene Benutzeroberflächen für unterschiedliche Anwendungsfälle erstellt werden.

Vorteile

Unsere Lösung bietet mehrere Vorteile:

  • Modularität: Widgets können einfach hinzugefügt, entfernt und geändert werden.
  • Wartbarkeit: Der Code ist klar strukturiert und leicht verständlich.
  • Erweiterbarkeit: Neue Widgets können ohne umfangreiche Änderungen am bestehenden Code hinzugefügt werden.

Schritt-für-Schritt Anleitung

1. Installation der EVE4-Bibliothek

Installieren Sie die EVE4-Bibliothek über den Library Manager in der Arduino IDE.

2. Erstellen der Widget-Klassen

Definieren Sie die grundlegenden Widget-, TextWidget– und Button-Klassen.

// Widget.h
#ifndef WIDGET_H
#define WIDGET_H

class Widget {
public:
    Widget(int x, int y, int width, int height, uint32_t color);
    virtual void draw() = 0;
    virtual ~Widget() {}

protected:
    int x, y, width, height;
    uint32_t color;
};

#endif // WIDGET_H

3. Erstellen der Screen-Klasse

Die Screen-Klasse verwaltet eine Liste von Widgets und zeichnet diese auf dem Display.

// Screen.h
#ifndef SCREEN_H
#define SCREEN_H

#include "Widget.h"

class Screen {
public:
    void addWidget(Widget* widget);
    void draw();
    
private:
    Widget* head;
};

#endif // SCREEN_H

4. Erstellen des ScreenManagers

Der ScreenManager verwaltet mehrere Screens und ermöglicht das einfache Wechseln zwischen ihnen.

// ScreenManager.h
#ifndef SCREENMANAGER_H
#define SCREENMANAGER_H

#include "Screen.h"

class ScreenManager {
public:
    void addScreen(Screen* screen);
    void setActiveScreen(int index);
    Screen* getActiveScreen() const;
    void drawActiveScreen() const;

private:
    Screen* screens[10];
    int screenCount;
    int activeScreenIndex;
};

#endif // SCREENMANAGER_H

5. Implementierung der Widgets

Implementieren Sie spezifische Widgets wie TextWidget und Button.

// TextWidget.h
#ifndef TEXTWIDGET_H
#define TEXTWIDGET_H

#include "Widget.h"

class TextWidget : public Widget {
public:
    TextWidget(int x, int y, int fontSize, uint32_t color, const String& text);
    void draw() override;
    void setText(const String& text);

private:
    int fontSize;
    String text;
};

#endif // TEXTWIDGET_H

Anwendungsbeispiel

1. Initialisierung

Erstellen Sie eine Instanz von ScreenManager und fügen Sie Screens und Widgets hinzu.

#include <Arduino.h>
#include "ScreenManager.h"
#include "TextWidget.h"
#include "Button.h"

// Instanziieren Sie den ScreenManager
ScreenManager screenManager;

// Setup-Funktion
void setup() {
    Serial.begin(115200);

    // Erstellen Sie einen neuen Screen
    Screen* mainScreen = new Screen();

    // Erstellen Sie ein TextWidget und ein ButtonWidget
    TextWidget* textWidget = new TextWidget(10, 10, 28, 0xFFFFFF, "Hallo Welt");
    Button* buttonWidget = new Button(50, 50, 100, 40, 28, 0x00FF00, 0x0000FF, "Klick mich");

    // Fügen Sie die Widgets zum Screen hinzu
    mainScreen->addWidget(textWidget);
    mainScreen->addWidget(buttonWidget);

    // Fügen Sie den Screen zum ScreenManager hinzu und setzen Sie ihn als aktiv
    screenManager.addScreen(mainScreen);
    screenManager.setActiveScreen(0);
}

// Loop-Funktion
void loop() {
    // Zeichnen Sie den aktiven Screen
    screenManager.drawActiveScreen();
}

2. Text ändern

Ändern Sie den Text eines Widgets basierend auf einer bestimmten Bedingung.

void loop() {
    // Zeichnen Sie den aktiven Screen
    screenManager.drawActiveScreen();

    // Beispiel: Ändern Sie den Text des TextWidgets nach 5 Sekunden
    static unsigned long lastChangeTime = 0;
    if (millis() - lastChangeTime > 5000) {
        Screen* activeScreen = screenManager.getActiveScreen();
        if (activeScreen != nullptr) {
            TextWidget* textWidget = static_cast<TextWidget*>(activeScreen->getWidgetById(1)); // Annahme: id == 1
            if (textWidget != nullptr) {
                textWidget->setText("Text geändert!");
            }
        }
        lastChangeTime = millis();
    }
}

Fazit

Mit unserer Widget-Bibliothek für BT81x-Chips wird die Entwicklung von Benutzeroberflächen für Embedded-Systeme deutlich einfacher und übersichtlicher. Die modulare und objektorientierte Struktur ermöglicht eine einfache Wartung und Erweiterung des Codes.

ambrabyte GmbH ist stolz darauf, Ihnen diese innovative Lösung vorstellen zu dürfen. Wenn Sie Unterstützung bei der Implementierung oder Weiterentwicklung benötigen, stehen wir Ihnen gerne zur Verfügung.

Nach oben scrollen