Leon – RGB 3D Druck Lampe


Individuell entwickelte LED-Lampe aus dem 3D-Drucker

Die „Leon“ Lampe ist eine selbst entwickelte RGB-LED-Lampe auf Basis eines Wemos D1 Mini und 11x WS2812 LEDs.
Das Gehäuse wurde vollständig für den 3D-Druck konstruiert und besteht aus PETG in Rot, Weiß und Schwarz.

Die Steuerung erfolgt über einen einzelnen Drucktaster mit mehreren Funktionen wie Programmwechsel und Helligkeitssteuerung.


Bilder

Vorderseite


Rückseite CAD


Eingebaute Elektronik

Die zwei kleinen Abdeckungen für die Wandmontage werden mit etwas Sekundenkleber aufgeklebt.

Den Wemos D1 mini habe ich an den Ecken mit UV Epoxidharz fixiert. (Hat für so einfach Projekte immer gut funktioniert.)


Funktionen

  • 9 programmierte Lichtmodi
  • Statische Farben
  • Farbwechsel
  • Sanfte RGB-Übergänge
  • Dynamische Animationen
  • 5 Dimmstufen
  • Speicherung der letzten Einstellungen
  • Steuerung über einen einzelnen Taster

Bedienung

AktionFunktion
Kurz drückenLichtprogramm wechseln
Lange drückenHelligkeit dimmen

Die zuletzt verwendete Programmnummer sowie die eingestellte Helligkeit werden automatisch gespeichert und nach dem Einschalten wieder geladen.


Elektronik

Die Lampe verwendet:

  • Wemos D1 Mini
  • 11x WS2812 RGB LEDs
  • Drucktaster
  • 10kΩ Widerstand

Der Drucktaster ist als Pullup-Schaltung aufgebaut:

  • GPIO5 → 10kΩ → 3,3V
  • GPIO5 → Taster → GND

Die Tasterplatine besitzt die Abmessungen 25x25mm.


Materialien

BauteilMaterial
GehäusePETG Rot
DiffusorPETG Weiß
LogoPETG Schwarz

3D-Druck Einstellungen

Meine 3D-Drucke werden standardmäßig mit folgenden Grundeinstellungen gefertigt:

  • Düse: 0,4 mm
  • Schichthöhe: 0,2 mm

Diese Kombination bietet einen guten Kompromiss aus Detailgenauigkeit, Stabilität und Druckzeit und eignet sich ideal für technische Bauteile sowie dekorative Drucke.


Schrauben

MengeTypVerwendung
2xM2 x 5mmTasterplatine
4xM3 x 12mmGehäusedeckel

Stückliste

MengeBauteil
1xWemos D1 Mini
11xWS2812 RGB LED
1xDrucktaster
1x10kΩ Widerstand
2xM2 x 5mm Schrauben
4xM3 x 12mm Schrauben

Fazit

Die Lampe funktioniert technisch sehr gut und erfüllt alle Funktionen wie geplant. Optisch wirkt das rote Gehäuse im Betrieb grundsätzlich stimmig.

Im Test zeigte sich jedoch, dass bei 2 mm Wandstärke in rotem PETG zu viel unerwünschtes Licht durchscheint und die Lichtwirkung dadurch etwas an Kontrast verliert.

Für eine bessere Lichtführung gibt es zwei sinnvolle Optionen:

  • dickere Wandstärke (einfach, aber materialintensiver)
  • zweifarbiges Gehäuse mit schwarzer Innenschicht (empfohlen)

Durch den Mehrfarbdruck ist die zweifarbige Variante die sauberste Lösung und wird für die nächste Iteration bevorzugt.

Downloads

Arduino Quellcode anzeigen

#include <FastLED.h>
#include <EEPROM.h>

// by DL4KER www.dl4ker.de 
#define LED_PIN     2       // GPIO2 / D4
#define BUTTON_PIN  5       // GPIO5 / D1
#define NUM_LEDS    11
#define LED_TYPE    WS2812B
#define COLOR_ORDER GRB

CRGB leds[NUM_LEDS];

// ------------------------------------------------
// Helligkeitsstufen
// ------------------------------------------------
const uint8_t brightnessLevels[5] = {40, 80, 130, 190, 255};
uint8_t brightnessIndex = 2;

// ------------------------------------------------
// Programme
// ------------------------------------------------
uint8_t currentProgram = 0;
const uint8_t totalPrograms = 9;

// ------------------------------------------------
// Taster
// ------------------------------------------------
bool lastButtonState = HIGH;
unsigned long pressStart = 0;
bool longPressHandled = false;

const unsigned long longPressTime = 700;

// ------------------------------------------------
// Timing
// ------------------------------------------------
unsigned long lastUpdate = 0;

// ------------------------------------------------
// EEPROM
// ------------------------------------------------
#define EEPROM_PROGRAM_ADDR   0
#define EEPROM_BRIGHT_ADDR    1

// ================================================================
// Einstellungen speichern
// ================================================================
void saveSettings() {
  EEPROM.write(EEPROM_PROGRAM_ADDR, currentProgram);
  EEPROM.write(EEPROM_BRIGHT_ADDR, brightnessIndex);
  EEPROM.commit();
}

// ================================================================
// Einstellungen laden
// ================================================================
void loadSettings() {

  currentProgram = EEPROM.read(EEPROM_PROGRAM_ADDR);
  brightnessIndex = EEPROM.read(EEPROM_BRIGHT_ADDR);

  if (currentProgram >= totalPrograms)
    currentProgram = 0;

  if (brightnessIndex >= 5)
    brightnessIndex = 2;
}

// ================================================================
// Setup
// ================================================================
void setup() {

  pinMode(BUTTON_PIN, INPUT_PULLUP);

  EEPROM.begin(10);

  loadSettings();

  FastLED.addLeds(leds, NUM_LEDS);

  FastLED.setBrightness(brightnessLevels[brightnessIndex]);

  FastLED.clear();
  FastLED.show();

  randomSeed(analogRead(A0));
}

// ================================================================
// Hauptloop
// ================================================================
void loop() {

  handleButton();

  runProgram();
}

// ================================================================
// Taster auswerten
// ================================================================
void handleButton() {

  bool buttonState = digitalRead(BUTTON_PIN);

  // Taste gedrückt
  if (lastButtonState == HIGH && buttonState == LOW) {
    pressStart = millis();
    longPressHandled = false;
  }

  // Lange gedrückt
  if (buttonState == LOW &&
      !longPressHandled &&
      millis() - pressStart > longPressTime) {

    longPressHandled = true;

    brightnessIndex++;

    if (brightnessIndex >= 5)
      brightnessIndex = 0;

    FastLED.setBrightness(brightnessLevels[brightnessIndex]);

    saveSettings();
  }

  // Taste losgelassen
  if (lastButtonState == LOW && buttonState == HIGH) {

    // kurzer Druck
    if (!longPressHandled) {

      currentProgram++;

      if (currentProgram >= totalPrograms)
        currentProgram = 0;

      saveSettings();
    }
  }

  lastButtonState = buttonState;
}

// ================================================================
// Programme
// ================================================================
void runProgram() {

  switch (currentProgram) {

    // ------------------------------------------------
    // Programm 1 - Blau
    // ------------------------------------------------
    case 0:
      fill_solid(leds, NUM_LEDS, CRGB::Blue);
      FastLED.show();
      delay(20);
      break;

    // ------------------------------------------------
    // Programm 2 - Zufällige Farben
    // ------------------------------------------------
    case 1:

      if (millis() - lastUpdate > 1500) {

        lastUpdate = millis();

        for (int i = 0; i < NUM_LEDS; i++) {
          leds[i] = CHSV(random8(), 255, 255);
        }

        FastLED.show();
      }

      break;

    // ------------------------------------------------
    // Programm 3 - Regenbogen
    // ------------------------------------------------
    case 2: {

      static uint8_t hue = 0;

      fill_rainbow(leds, NUM_LEDS, hue, 10);

      FastLED.show();

      hue++;

      delay(30);

      break;
    }

    // ------------------------------------------------
    // Programm 4 - Weicher Farbwechsel
    // ------------------------------------------------
    case 3: {

      static uint8_t fadeHue = 0;

      fill_solid(leds, NUM_LEDS, CHSV(fadeHue, 255, 255));

      FastLED.show();

      fadeHue++;

      delay(40);

      break;
    }

    // ------------------------------------------------
    // Programm 5 - Grün
    // ------------------------------------------------
    case 4:
      fill_solid(leds, NUM_LEDS, CRGB::Green);
      FastLED.show();
      delay(20);
      break;

    // ------------------------------------------------
    // Programm 6 - Orange
    // ------------------------------------------------
    case 5:
      fill_solid(leds, NUM_LEDS, CRGB::Orange);
      FastLED.show();
      delay(20);
      break;

    // ------------------------------------------------
    // Programm 7 - Rot
    // ------------------------------------------------
    case 6:
      fill_solid(leds, NUM_LEDS, CRGB::Red);
      FastLED.show();
      delay(20);
      break;

    // ------------------------------------------------
    // Programm 8 - Lila
    // ------------------------------------------------
    case 7:
      fill_solid(leds, NUM_LEDS, CRGB::Purple);
      FastLED.show();
      delay(20);
      break;

    // ------------------------------------------------
    // Programm 9 - Gelb
    // ------------------------------------------------
    case 8:
      fill_solid(leds, NUM_LEDS, CRGB::Yellow);
      FastLED.show();
      delay(20);
      break;
  }
}