- C++ 93.1%
- Makefile 6.9%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
images/ enthält die 10 Einträge von DEMO[] aus examples/Eyes72x40 (01-05 normal, 06-10 übermüdet), pixelgenau aus Eyes.cpp mit der U8g2-C-Bibliothek und dem 72x40-Treiber gerendert. Zusätzlich die Roll-Varianten (roll_cw, roll_ccw, roll_converge) und das Blinzeln (blink) als SMIL-Animation. Das README zeigt die Bilder im Abschnitt "Beispiel". |
||
| examples | ||
| images | ||
| src | ||
| .gitignore | ||
| library.properties | ||
| LICENSE | ||
| LICENSE.de | ||
| LIZENZEN.md | ||
| Makefile | ||
| README.md | ||
Eyes – animiertes Cartoon-Augenpaar für U8g2-Displays
Zeichnet ein Augenpaar (Augapfel, Pupille, Lid, Augenbrauen) über die
U8g2-Basisklasse – funktioniert damit mit jedem U8g2-Treiber, egal ob
128x64-SSD1306, das 72x40-Fensterpanel (U8G2_SSD1306_72X40_ER_F_HW_I2C)
oder ein anderes u8g2-unterstütztes Display.
#include <U8g2lib.h>
#include <Eyes.h>
U8G2_SSD1306_72X40_ER_F_HW_I2C display(U8G2_R2, U8X8_PIN_NONE, /*SCL=*/6, /*SDA=*/5);
Eyes eyes(display);
void setup() {
eyes.begin(0x3C); // I2C-Adresse setzen + display.begin()
eyes.setBrow(BROW_RAISED);
eyes.setGaze(GAZE_UP);
eyes.update(); // erster Aufruf: zeichnet + startet Auto-Blinzeln
}
void loop() {
eyes.update(); // nicht-blockierendes Auto-Blinzeln am Laufen halten
}
Status: 1.1.0, aus einem früheren Einzel-Sketch (72x40-OLED-Projekt) herausgelöst und als eigenständige Library verpackt.
Konzept
- Zustand + Rendering getrennt: Setter (
setGaze,setBrow,setLid) ändern nur Zustand,render()zeichnet ihn. So lassen sich mehrere Setter aufrufen, bevor tatsächlich gezeichnet wird. - Nicht-blockierendes Auto-Blinzeln:
update()inloop()aufrufen – hält eine kleine State-Machine am Laufen, ohnedelay()zu benutzen. - Blockierende Spezialanimationen:
blink()(ein sofortiges Blinzeln) undroll(dir, turns)(Augen rollen) nutzen bewusstdelay(). Während sie laufen, pausiertupdate()faktisch – danach wird der vorherige Ausdruck automatisch wiederhergestellt. - Geometrie frei konfigurierbar: alle Masse stecken in
Eyes::geo(EyeGeometry), Defaults sind für ein 72x40-Panel ausgelegt.
API
enum Gaze { GAZE_CENTER, GAZE_LEFT, GAZE_RIGHT, GAZE_UP, GAZE_DOWN,
GAZE_UP_LEFT, GAZE_UP_RIGHT, GAZE_DOWN_LEFT, GAZE_DOWN_RIGHT };
enum Brow { BROW_ANGRY, BROW_NEUTRAL, BROW_RAISED, BROW_SAD, BROW_NONE };
enum Roll { ROLL_CW, ROLL_CCW, ROLL_CONVERGE };
class Eyes {
public:
explicit Eyes(U8G2& display);
bool begin(uint8_t i2cAddr = 0); // optional: I2C-Adresse (7 Bit) setzen + display.begin()
void setGaze(Gaze g);
void setGaze(int dx, int dy); // freie Verschiebung in px (wird an eyeR/pupilR begrenzt)
void setBrow(Brow b);
void setLid(float l); // 0.0 = offen ... 1.0 = ganz zu
void setTired(bool t); // übermüdet: Adern von der Pupille nach aussen
void setRotation(const u8g2_cb_t* r); // U8G2_R0 = normal, U8G2_R2 = 180°
void render(); // aktuellen Zustand zeichnen + anzeigen
void blink(); // EIN blockierendes Blinzeln
void roll(Roll dir, int turns = 1); // blockierendes Augenrollen
void update(); // nicht-blockierendes Auto-Blinzeln; in loop()
EyeGeometry geo; // alle Masse, frei änderbar
int blinkSteps, blinkFrameMs;
unsigned long blinkMinMs, blinkMaxMs;
int rollSteps, rollFrameMs;
};
EyeGeometry (Defaults für 72x40):
| Feld | Default | Bedeutung |
|---|---|---|
centerX |
36 | Bildmitte X |
eyeR |
13 | Augapfel-Radius |
eyeGap |
23 | Abstand Augenmitte <-> Bildmitte |
eyeCY |
25 | Augenmitte Y |
pupilR |
5 | Pupillen-Radius |
gazeRange |
5 | max. Pupillen-Verschiebung je Achse (px) |
browThick |
3 | Brauen-Balkendicke (px) |
browTopY |
2 | höchster Brauen-Punkt (Y) |
browSlant |
5 | Höhenunterschied innen/aussen (schräge Brauen) |
browHalf |
14 | halbe Brauenlänge |
veinCount |
8 | Anzahl Adern je Auge bei setTired(true) |
Für ein anderes Panel (z.B. 128x64) einfach geo.* im Sketch nach dem
Anlegen von Eyes eyes(display) überschreiben.
Beispiel
examples/Eyes72x40/ – Demo für ein ESP32-C3 SuperMini mit
aufgelötetem 0,42"-OLED (72x40, SSD1306/SSD1315). Wechselt alle 3 s den
Ausdruck und zeigt nach jedem Durchlauf alle drei Roll-Varianten.
Ausdrücke (DEMO[])
Pixelgenau aus src/Eyes.cpp auf 72x40 gerendert (Ordner images/).
| böse, geradeaus | böse, links unten | Brauen hoch, oben | neutral, rechts | traurig, unten |
|---|---|---|---|---|
Dieselben Ausdrücke mit setTired(true):
| böse, geradeaus | böse, links unten | Brauen hoch, oben | neutral, rechts | traurig, unten |
|---|---|---|---|---|
Animationen
| Rollen im Uhrzeigersinn | Rollen dagegen | Rollen gespiegelt | Blinzeln |
|---|---|---|---|
Die Animationen sind SMIL-SVGs und laufen im Browser bzw. auf Gitea/Codeberg.
Build
make example # Kompiliert examples/Eyes72x40
make upload PORT=/dev/ttyACM0
make monitor
make upload-monitor
Default-Board ist esp32:esp32:esp32c3 (ESP32-C3 SuperMini) – für ein
anderes Board BOARD= setzen, z.B. make example BOARD=esp32:esp32:esp32.
Installation als Arduino-Library
ln -s /pfad/zu/esp32-libEyes ~/Arduino/libraries/Eyes
arduino-cli findet die Library erst, wenn der Sketch #include <Eyes.h>
direkt einbindet.
Abhängigkeiten
- ESP32 Arduino Core (
Wire.h,Arduino.h) - U8g2 (Library Manager: "U8g2" von
oliver) – liefert die Treiberklassen, u.a.
U8G2_SSD1306_72X40_ER_F_HW_I2Cfür das 72x40-Fensterpanel.
arduino-cli lib install "U8g2"
Stolperfallen
- 72x40-Panel braucht den dedizierten Treiber: Das Panel ist nur ein
sichtbares Fenster im 128x64-GDDRAM des Controllers. Ein generischer
128x64-Treiber zeichnet daher falsch –
U8G2_SSD1306_72X40_ER_F_HW_I2Ckennt den Offset. - I2C-Pins prüfen: beim ESP32-C3-SuperMini mit aufgelötetem OLED SDA=GPIO5/SCL=GPIO6 – NICHT die sonst übliche 8/9-Belegung des nackten SuperMini.
- Verschobenes/abgeschnittenes Bild: abweichende Panel-Charge möglich
– dann
u8g2.getU8x8()->x_offset = 30;voreyes.begin()bzw.u8g2.begin()setzen. blink()/roll()sind blockierend (delay()) – während der Laufzeit reagiert der Sketch nicht auf andere Eingaben. Für reaktionsfreudige Sketches sparsam einsetzen bzw. in eigenem Task/Core auslagern.- Pupille kann den Augapfel nicht verlassen:
setGaze(dx, dy)begrenzt automatisch aufeyeR - pupilR - 1.
Dateien
src/Eyes.h Klasse Eyes, Enums (Gaze/Brow/Roll), EyeGeometry
src/Eyes.cpp Implementierung (Zeichnen, Blinzeln, Rollen)
examples/Eyes72x40/ Demo für ein 72x40-OLED-Board
images/ gerenderte Vorschau der Demo-Ausdrücke und Animationen (SVG)
Lizenz
Der Bibliotheks-Quelltext unter src/ steht unter der GNU Lesser
General Public License v3 (oder später) – siehe LICENSE
bzw. LICENSE.de (inoffizielle deutsche Übersetzung).
Die Beispiel-Sketches unter examples/ stehen unter der GNU General
Public License v3 (oder später) – siehe
examples/LICENSE bzw.
examples/LICENSE.de.
Abhängigkeiten und deren Lizenzen: siehe LIZENZEN.md.