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.
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.
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.
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.
Das bedeutet:
- Beispielsketch herunterladen
bild.hgegen 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 <Arduino.h>
#include <M5GFX.h>
#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 wiebild2.h,bild3.husw. 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.
Darum gilt:
- 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()oderdrawBmp()neu geladen.
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.
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 <Arduino.h>
#include <M5Unified.h>
// 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 < NUM_BILDER) {
counter++;
} else {
// Wenn oberes Ende erreicht, wieder bei 1 anfangen
counter = 1;
}
}
// KEY2 (Button B) gedrückt → zur vorherigen Bildposition wechseln
else if (M5.BtnB.wasPressed()) {
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.
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.
*
* Die Reihenfolge wird dabei mit dem Fisher-Yates-Shuffle
* vollständig zufällig durchmischt – so entsteht ein
* eindrucksvoller „Random Reveal“-Effekt.
*
* 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)
* - 240×135 SPI-Display (ST7789)
*
* Benötigte Libraries:
* - M5Unified (für Display, Buttons, Systeminitialisierung)
*
* Hinweis:
* Das Bild liegt in der Datei "bild.h" als `const uint8_t jpg[]`
* und wird direkt aus dem Flash-Speicher angezeigt.
************************************************************/
#include <Arduino.h>
#include <M5Unified.h>
#include "bild.h" // enthält: const uint8_t jpg[] (240x135)
// Raster-Einstellungen
const int TILE_COLS = 8; // Anzahl Spalten
const int TILE_ROWS = 5; // Anzahl Zeilen
const int TILE_WIDTH = 240 / TILE_COLS; // Breite einer Kachel
const int TILE_HEIGHT = 135 / TILE_ROWS; // Höhe einer Kachel
struct Tile {
int row;
int col;
};
const int NUM_TILES = TILE_COLS * TILE_ROWS;
Tile tiles[NUM_TILES];
// Kacheln initialisieren
void initTiles() {
int index = 0;
for (int row = 0; row < TILE_ROWS; row++) {
for (int col = 0; col < TILE_COLS; col++) {
tiles[index].row = row;
tiles[index].col = col;
index++;
}
}
}
// Zufällige Reihenfolge erzeugen (Fisher-Yates-Shuffle)
void shuffleTiles() {
for (int i = NUM_TILES - 1; i > 0; i--) {
int j = random(i + 1); // 0..i
Tile tmp = tiles[i];
tiles[i] = tiles[j];
tiles[j] = tmp;
}
}
// Bild in zufälligen Blöcken erscheinen lassen
void revealImageBlocks(int delayMs = 50) {
// Display vorher schwarz machen
M5.Display.fillScreen(TFT_BLACK);
for (int i = 0; i < NUM_TILES; i++) {
int x = tiles[i].col * TILE_WIDTH;
int y = tiles[i].row * TILE_HEIGHT;
// Clip-Region auf aktuelle Kachel setzen
M5.Display.setClipRect(x, y, TILE_WIDTH, TILE_HEIGHT);
// Komplettes Bild zeichnen – sichtbar ist nur die gesetzte Kachel
M5.Display.drawJpg(jpg, sizeof(jpg), 0, 0);
// Clip-Region wieder aufheben
M5.Display.clearClipRect();
delay(delayMs);
}
}
void setup() {
auto cfg = M5.config();
cfg.clear_display = true;
M5.begin(cfg);
M5.Display.setRotation(1); // Querformat
initTiles(); // Kachelraster aufbauen
shuffleTiles(); // zufällige Reihenfolge erzeugen
// Bild mit Random-Block-Effekt erscheinen lassen
revealImageBlocks(40); // 40 ms pro Block
}
void loop() {
// Nichts – Bild bleibt stehen
}
Der Effekt lässt sich über zwei Parameter leicht anpassen:
- Rastergröße → größere oder kleinere Blöcke
- delayMs → Geschwindigkeit des Effekts
Je größer die Anzahl der Blöcke, desto „feiner“ wirkt das Bild beim Zusammensetzen.
Fazit
In diesem ersten Beitrag habe ich dir die scheinbar einfachste und schnellste Möglichkeit gezeigt, eigene Bilder auf dem Display des Arduino Nesso N1 darzustellen. Mit einem vorbereiteten PROGMEM-Array und wenigen Zeilen Code lässt sich bereits ein erstaunlich gutes Ergebnis erzielen – ganz ohne Dateisystem, SD-Karte oder zusätzliche Hardware. Diese Methode eignet sich ideal, um schnell erste Erfolge zu erzielen, Startbildschirme zu bauen oder grafische Elemente in ein Projekt einzubinden.
Im nächsten Beitrag gehen wir einen Schritt weiter: Dann zeige ich dir, wie du deine Bilder direkt auf dem Mikrocontroller ablegen, verwalten und dynamisch wieder laden kannst. Dadurch wird das Ganze etwas anspruchsvoller, aber auch deutlich flexibler – perfekt für Slideshows, Galerien oder komplexere Benutzeroberflächen.
Bleib also dran, es wird spannend!
Letzte Aktualisierung am: 06. Dezember 2025


1 thought on “Arduino Nesso N1: So einfach zeigst du eigene Bilder auf dem Display an”