Arduino Nesso N1: So einfach zeigst du eigene Bilder auf dem Display an
Du möchtest eigene Bilder auf dem Display des Arduino Nesso N1 anzeigen lassen? Perfekt – genau darum geht es in diesem Beitrag. Wir starten ganz bewusst mit der einfachsten und schnellsten Methode, bei der ein Bild direkt aus dem Flash-Speicher (PROGMEM) geladen und auf dem Display dargestellt wird. Diese Lösung kommt ohne SD-Karte, ohne Dateisystem und ohne zusätzliche Hardware aus – ideal für kleine Projekte, Menüs oder Startbildschirme.
https://youtu.be/OjLf1hFUJuc
Im späteren, separaten Beitrag zeige ich dir dann, wie du Bilder direkt vom internen Dateisystem des Nesso N1 laden kannst, inklusive flexibler Bildverwaltung und Slideshow-Optionen. Doch beginnen wir zunächst mit der Basis, die jeder sofort umsetzen kann.
Hinweis zur Bildqualität der Fotos
Die folgenden Fotos zeigen die ausgegebenen Bilder direkt auf dem Display des Arduino Nesso N1. Bitte beachte: Die Qualität der Aufnahmen wirkt fotografiert etwas unscharf oder mit sichtbaren Pixelstrukturen. In der Realität sieht das Display deutlich besser aus – die Farben sind kräftiger, die Schärfe höher und die Darstellung insgesamt klarer.
Das liegt schlicht daran, dass Kameraobjektive und Displays selten perfekt harmonieren und sich Moiré-Effekte oder Reflexionen einschleichen. Für die tatsächliche Darstellung solltest du dich daher auf das Live-Bild des Geräts verlassen – die Fotos dienen lediglich zur Veranschaulichung.
Was wird für dieses Projekt benötigt?
Damit du eigene Bilder auf dem Display des Arduino Nesso N1 anzeigen kannst, brauchst du nur wenige Dinge. Das Projekt kommt komplett ohne zusätzliche Sensoren oder externe Hardware aus und eignet sich daher ideal für Einsteiger.
FĂĽr dieses Beispiel verwende ich:
- Arduino Nesso N1*
Das Herzstück des Projekts – ein kompakter Mikrocontroller mit ESP32-C6 und integriertem 240×135-Pixel-Display.
- USB-C Datenkabel*
Zum Programmieren und zur Stromversorgung. Wichtig: Ein reines Ladekabel funktioniert nicht!
- Drei Bilder
FĂĽr die Demo verwende ich JPG, PNG und BMP. Du kannst aber beliebige Bilder nutzen, solange sie vorher zugeschnitten und in ein C-Array konvertiert wurden.
- Arduino IDE
Zum Schreiben und Hochladen des Programms. Empfohlen ist die aktuelle Version der IDE.
- M5Unified Bibliothek von M5Stack
Sie ĂĽbernimmt die Initialisierung des Displays, der Tasten und der ĂĽbrigen Peripherie.
Installation: Sketch → Bibliothek einbinden → Bibliotheken verwalten → „M5Unified“ suchen
Hinweis von mir: Die mit einem Sternchen (*) markierten Links sind Affiliate-Links. Wenn du über diese Links einkaufst, erhalte ich eine kleine Provision, die dazu beiträgt, diesen Blog zu unterstützen. Der Preis für dich bleibt dabei unverändert. Vielen Dank für deine Unterstützung!
Dieser minimale Aufbau reicht vollkommen aus, um Bilder im PROGMEM abzulegen, anzuzeigen und später sogar per Tastendruck durchzublättern.
Wichtiger Hinweis zum USB-C-Datenkabel
In meinem Test hat sich gezeigt, dass nicht jedes beliebige USB-C-Kabel zuverlässig mit dem Arduino Nesso N1 funktioniert. Besonders dünne oder ältere Kabel liefern oft nicht genug Strom oder verlieren die Datenverbindung während des Flashens.
Ich musste ein hochwertiges, kräftig abgeschirmtes USB-C-Datenkabel verwenden und den Nesso N1 zusätzlich über einen aktiven USB-Hub anschließen, damit genügend Strom anliegt und die Programmierung stabil funktioniert.
Wenn der Upload bei dir hängen bleibt, das Board nicht erkannt wird, lohnt es sich daher zuerst, ein besseres Kabel oder einen aktiven Hub zu testen. Oft ist das schon die komplette Lösung.
Bilder fĂĽr das Arduino Nesso N1 Display vorbereiten
Für dieses Beispiel verwende ich ein Foto meines kleinen Hundes. Damit das Bild später sauber und pixelgenau auf das Display des Arduino Nesso N1 passt, muss es zunächst auf die richtige Größe gebracht werden.
1. Bild auf Displaygröße zuschneiden
Das Display des Nesso N1 besitzt eine Auflösung von 240 × 135 Pixeln (Breite × Höhe im Querformat).
Daher schneide ich mein Foto zuerst in genau dieses Format zurecht:
- Breite: 240 Pixel
- Höhe: 135 Pixel
- Format: JPG
Das Zuschneiden kann mit jedem gängigen Bildeditor erfolgen, in meinem Fall verwende ich Paint.NET, dieses Tool ist kostenfrei und es gibt viele Plugins und Features um Bilder zu bearbeiten.
2. Bild in Array umwandeln
Damit das Bild direkt aus dem Flash-Speicher geladen werden kann, wird es in ein Byte-Array umgewandelt:
const uint8_t jpg = { ... };
DafĂĽr nutze ich das Online-Tool: https://notisrac.github.io/FileToCArray/
Es konvertiert jede Bilddatei in ein kompatibles C-Array (getestet mit JPG, PNG & BMP).
Wichtige Einstellungen im Tool:
- Treat as binary: anhaken
- Data type: unint8_t
Alle anderen Werte sind per Default gesetzt und passen.
Einstellungen fĂĽr den File to C style array converter
Nach dem Generieren erhältst du ein fertiges Stück Code, mit den Daten des Bildes in einem Array die so beginnt:
const unsigned char Mailo1_jpg = {
0xFF, 0xD8, 0xFF, 0xE0, ...
};
Diese Datei kannst du anschlieĂźend direkt in dein Arduino-Projekt einbinden und auf dem Display anzeigen.
Abspeichern der generierten Daten als C-Header-Dateii oder kopieren in die Zwischenablage
Arduino Nesso N1 Bild anzeigen – jetzt geht’s an die Programmierung
Nachdem wir unser Bild vorbereitet und mit dem Online-Tool in eine bild.h umgewandelt haben, geht es nun an die eigentliche Programmierung.
Der schwierigste Teil ist bereits erledigt: Das Bild liegt als fertiges PROGMEM-Array vor – jetzt müssen wir es nur noch im Sketch einbinden.
Damit du direkt loslegen kannst, stelle ich dir ein vollständiges Arduino-Beispielprojekt zum Download bereit. Lade das Projekt in die Arduino IDE, ersetze die beiliegende bild.h einfach durch deine eigene Datei – und schon kann das Bild auf dem Display des Arduino Nesso N1 angezeigt werden.
Programm zum Anzeigen eines Bildes auf dem Arduino Nesso N1 - einfach mit PROGMEMHerunterladen
- Beispielsketch herunterladen
- bild.h gegen dein eigenes Bild austauschen
- Sketch kompilieren
- Auf den Nesso N1 hochladen
- Bild erscheint direkt beim Start auf dem Display
Im nächsten Schritt schauen wir uns den Beispielcode genauer an und ich erkläre dir Zeile für Zeile, wie das Bild auf das Display gelangt.
/*******************************************************
* Arduino Nesso N1 – Bildanzeige aus PROGMEM
* ---------------------------------------------------
* Dieses Beispiel zeigt, wie ein JPG-Bild direkt aus
* dem Flash-Speicher (PROGMEM) geladen und auf dem
* Display des Arduino Nesso N1 dargestellt wird.
*
* Das Bild befindet sich in der Datei "bild.h" und
* wurde zuvor ĂĽber ein C-Array-Konvertierungstool
* (z. B. FileToCArray) erzeugt.
*
* Autor: Stefan Draeger
* Blogbeitrag:
* https://draeger-it.blog/arduino-nesso-n1-so-einfach-zeigst-du-eigene-bilder-auf-dem-display-an/
*
* Hardware:
* - Arduino Nesso N1 (ESP32-C6)
* - Integriertes 240Ă—135 SPI-Display (ST7789)
*
* Benötigte Libraries:
* - M5GFX (Displaytreiber)
*
* Dieses Beispiel zeigt nur ein statisches Standbild.
* Animationen oder das Laden aus dem Dateisystem
* werden in einem separaten Beitrag behandelt.
*******************************************************/
#include
#include
#include "bild.h" // enthält: const uint8_t jpg PROGMEM
M5GFX display; // Display-Objekt des Nesso N1
void setup() {
display.begin(); // Display initialisieren
display.setRotation(1);
// Dreht das Display ins Querformat
// 0 = Hochformat, 1 = Querformat, 2/3 = invertiert
display.fillScreen(TFT_BLACK);
// Hintergrund löschen, damit kein Artefakt sichtbar ist
// JPG direkt aus PROGMEM anzeigen
// Parameter:
// 1) jpg -> Byte-Array aus bild.h
// 2) sizeof(jpg) -> Bildgröße in Bytes
// 3) X-Position -> 0
// 4) Y-Position -> 0
display.drawJpg(jpg, sizeof(jpg), 0, 0);
}
void loop() {
// Keine Aktion notwendig – das Bild bleibt stehen
}
Das Array in eine eigene Datei auszulagern hat mehrere Vorteile.
Zum einen bleibt dein eigentlicher Arduino-Sketch deutlich übersichtlicher, weil die langen Byte-Arrays nicht mehr direkt im Code stehen. Gerade bei Bildern können diese schnell mehrere tausend Zeilen einnehmen und würden den Programmcode unlesbar machen.
Zum anderen bietet dir dieser Ansatz maximale Flexibilität:
Wenn du später mehrere Bilder nacheinander anzeigen möchtest – etwa für eine Slideshow oder für ein Menü –, musst du nicht jedes Mal den Sketch anpassen. Du legst einfach weitere Dateien wie bild2.h, bild3.h usw. an und bindest sie bei Bedarf ein. Der Code selbst bleibt schlank, klar strukturiert und leicht erweiterbar.
Wie der ESP32-C6 Bilder speichert: Flash vs. RAM einfach erklärt
Nachdem wir nun erfolgreich ein erstes Bild auf dem Display anzeigen können, lohnt sich ein kurzer Blick darauf, wo die Bilddaten eigentlich gespeichert werden – und warum das entscheidend für die Stabilität deines Programms ist.
Der Arduino Nesso N1 verfügt über 520 KB SRAM, von denen jedoch nur etwa 320 KB als „dynamischer Speicher“ für Variablen zur Verfügung stehen. Der Rest wird vom System selbst benötigt (WiFi-Stack, Buffer, RTOS usw.).
Umso wichtiger ist es, große Datenmengen – wie Bilddateien – nicht im RAM, sondern im Flash-Speicher abzulegen.
Auf dem ESP32-C6 funktioniert das ganz einfach:
- const uint8_t bild = {...};
→ Array wird automatisch im Flash gespeichert (ideal für Bilder)
- uint8_t bild = {...};
→ Array landet im RAM und verbraucht dort sehr viel Speicher
Das SchlĂĽsselwort PROGMEM wird zwar unterstĂĽtzt, ist auf diesem Mikrocontroller aber nicht entscheidend.
Der eigentliche Unterschied entsteht durch const.
Ein kurzer Vergleich zeigt das deutlich:
Bild im Flash (mit const)
- Globale Variablen: 18.200 Bytes
- RAM bleibt fast komplett frei
Der Sketch verwendet 591870 Bytes (45%) des Programmspeicherplatzes. Das Maximum sind 1310720 Bytes.
Globale Variablen verwenden 18200 Bytes (5%) des dynamischen Speichers, 309480 Bytes fĂĽr lokale Variablen verbleiben. Das Maximum sind 327680 Bytes.
Bild im RAM (ohne const)
- Globale Variablen: 165.744 Bytes
- RAM fast zur Hälfte belegt
Der Sketch verwendet 592642 Bytes (45%) des Programmspeicherplatzes. Das Maximum sind 1310720 Bytes.
Globale Variablen verwenden 165744 Bytes (50%) des dynamischen Speichers, 161936 Bytes fĂĽr lokale Variablen verbleiben. Das Maximum sind 327680 Bytes.
Der Unterschied ist enorm. Gerade bei mehreren Bildern wäre der RAM sehr schnell erschöpft – und das Programm würde instabil laufen oder gar nicht mehr starten.
- Bilder immer als const-Arrays definieren.
- Sie landen dann automatisch im Flash und belasten den RAM nicht.
Dieser Punkt ist wichtig, bevor wir im nächsten Beispiel mehrere Bilder einbinden und per Tastendruck durchblättern. Genau dort zeigt sich der Vorteil besonders deutlich.
Arduino Nesso N1 Bilder per Tastendruck wechseln (JPG/PNG/BMP)
Nachdem wir ein einzelnes Bild erfolgreich anzeigen konnten, wollen wir nun einen Schritt weitergehen und die Bilder aktiv steuern. DafĂĽr habe ich ein kleines Beispielprogramm geschrieben, das gleich drei verschiedene Bildformate unterstĂĽtzt:
- JPG
- PNG
- BMP (Bitmap)
Alle Bilder liegen wie zuvor in separaten Header-Dateien (bild1.h, bild2.h, bild3.h).
Mit den beiden Hardware-Tasten am Arduino Nesso N1 können wir dann ganz einfach vor- und zurückblättern:
- KEY1 / BtnA (grüne Taste) → nächstes Bild
- KEY2 / BtnB (obere Taste) → vorheriges Bild
Damit verhält sich das Display wie eine kleine, interaktive Bildergalerie.
Der Vorteil: Du kannst jedes beliebige Bildformat testen und sofort sehen, wie es auf dem Display dargestellt wird.
Das Grundprinzip ist schnell erklärt:
- Beim Start wird das erste Bild geladen.
- In der loop()-Funktion prĂĽfen wir, ob eine der beiden Tasten gedrĂĽckt wurde.
- Je nach Tasteneingabe erhöhen oder verringern wir einen Zähler (counter).
- AnschlieĂźend wird das passende Bild ĂĽber drawJpg(), drawPng() oder drawBmp() neu geladen.
Arduino Nesso N1 - Bildwechsel mit Tasten
Auf diese Weise bleibt das Programm sehr kompakt, aber extrem flexibel. Du kannst beliebig viele weitere Bilder ergänzen – jeweils in einer eigenen Header-Datei – und die Navigation bleibt identisch.
Programm: Anzeigen von verschiedenen Bilder auf dem Arduino Nesso N1, wechsel mit den TastenHerunterladen
Im folgenden Codeblock findest du das vollständige Beispiel (die Dateien mit den Bildern oben in der ZIP-Datei zum Download) :
/**
* Titel: Arduino Nesso N1 – Bilder per Tastendruck durchblättern
*
* Beschreibung:
* Dieses Beispiel zeigt, wie du auf dem Arduino Nesso N1 (M5Stack Nesso, ESP32-C6)
* mehrere Bilder auf dem Display anzeigen und mit den Hardware-Tasten KEY1 (BtnA)
* und KEY2 (BtnB) vor- und zurückblättern kannst.
*
* Verwendet werden drei Bildformate:
* - JPG (bild1.h, Array: jpg)
* - PNG (bild2.h, Array: png)
* - Bitmap/BMP (bild3.h, Array: bmp)
*
* Autor: Stefan Draeger
* Blogbeitrag: https://draeger-it.blog/arduino-nesso-n1-so-einfach-zeigst-du-eigene-bilder-auf-dem-display-an/
*/
#include
#include
// Bilddaten auslagern, damit der Sketch ĂĽbersichtlich bleibt
#include "bild1.h" // Bild als JPG → Array: jpg
#include "bild2.h" // Bild als PNG → Array: png
#include "bild3.h" // Bild als Bitmap/BMP → Array: bmp
// Anzahl der verfĂĽgbaren Bilder
const int NUM_BILDER = 3;
// Zähler, welches Bild aktuell angezeigt wird (1-basiert)
int counter = 1;
void setup() {
// Konfiguration fĂĽr das M5-Framework holen
auto cfg = M5.config();
cfg.clear_display = true; // Display beim Start automatisch löschen
// Initialisiert Display, Taster, ggf. Touch, I2C-Expander usw.
M5.begin(cfg);
// Display in Landscape-Ausrichtung (quer) setzen
M5.Display.setRotation(1);
// Startbild anzeigen (JPG aus bild1.h)
M5.Display.drawJpg(jpg, sizeof(jpg), 0, 0);
}
void loop() {
// Zustände von Tasten, Touch etc. aktualisieren
M5.update();
bool btnPress = false; // Merker, ob eine der Tasten gedrĂĽckt wurde
// KEY1 (Button A) gedrückt → zur nächsten Bildposition wechseln
if (M5.BtnA.wasPressed()) {
btnPress = true;
if (counter 1) {
btnPress = true;
counter--;
}
}
// Nur neu zeichnen, wenn tatsächlich eine Taste gedrückt wurde
if (btnPress) {
// Bildschirm leeren (schwarz fĂĽllen)
M5.Display.fillScreen(TFT_BLACK);
// Sicherheitshalber wieder Landscape setzen
M5.Display.setRotation(1);
// Bild je nach Zählerstand auswählen und anzeigen
switch (counter) {
case 1:
// JPG aus bild1.h
M5.Display.drawJpg(jpg, sizeof(jpg), 0, 0);
break;
case 2:
// PNG aus bild2.h
M5.Display.drawPng(png, sizeof(png), 0, 0);
break;
case 3:
// Bitmap/BMP aus bild3.h
M5.Display.drawBmp(bmp, sizeof(bmp), 0, 0);
break;
}
}
// Kleine Entlastung fĂĽr die CPU (optional)
delay(10);
}
Bonus: Bild mit zufälligem Block-Effekt einblenden
Nachdem wir nun wissen, wie sich ein Bild ganz normal auf dem Display des Arduino Nesso N1 darstellen lässt, wollen wir das Ganze etwas aufpeppen.
Statt das Bild direkt komplett zu zeichnen, kann man einen kleinen visuellen Effekt einbauen, der das Bild in zufälligen Segmenten erscheinen lässt – ähnlich wie ein „Puzzle“, das sich nach und nach zusammensetzt.
Arduino Nesso N1 - Reveal Effekt
Wie funktioniert der Effekt?
- Das Display wird in ein Raster aus kleinen Kacheln eingeteilt
– in unserem Beispiel 8 Spalten × 5 Zeilen, also insgesamt 40 Blöcke.
- Diese Kacheln werden anschließend in zufälliger Reihenfolge freigegeben.
Dazu nutzen wir den bekannten Fisher-Yates-Shuffle, der alle Blöcke gleich wahrscheinlich mischt.
- FĂĽr jeden Block setzen wir eine sogenannte Clip-Region:
Das bedeutet, dass das Bild nur innerhalb dieses kleinen Rechtecks sichtbar ist.
- Anschließend wird immer wieder das komplette Bild gezeichnet –
aber durch die Clip-Region erscheint jedes Mal nur der aktuelle Block.
So entsteht ein dynamischer „Reveal“-Effekt, bei dem das Bild nach und nach sichtbar wird – jedes Mal anders, weil die Reihenfolge zufällig bestimmt wird.
Der vollständige Beispielcode sieht so aus:
/************************************************************
* Titel: Arduino Nesso N1 – Bild mit zufälligem Block-Effekt einblenden
* ----------------------------------------------------------
* Beschreibung:
* Dieses Beispiel zeigt, wie ein Bild auf dem Arduino Nesso N1
* (ESP32-C6) nicht einfach komplett angezeigt wird, sondern
* in zufälligen kleinen Blocksegmenten erscheint.
*
* DafĂĽr wird das Display in ein Raster aus Kacheln (Tiles)
* unterteilt. Jede dieser Kacheln wird per Clip-Region einzeln
* freigegeben und das Bild abschnittsweise gezeichnet.