RGBW-Lampe mit IR-Fernbedienung (Farbtemperatur steuern)

Hallo,

ich bastle gerade an einer LED-Lampe (im Moment noch RGB NeoPixel-Stick), welche ich mit einer IR-Fernbedienung steuere.
Ansteuerung und Dimmen funktionieren bereits.

Ich möchte jetzt noch zusätzlich die Farbtemperatur steuern.
Leider fehlt mir da der richtige Ansatz...

VG Demo

PS: Falls jemand noch Anregungen zur Code-Optimierung/Übersichtlichkeit hat... :wink:

Code (Alles):

#include <IRremote.h> // !!! bearbeitet (Nur NEC empfang)
#include "FastLED.h"

// IRremote
const int PIN_IR = 2; // IR PIN
IRrecv irrecv(PIN_IR); // create a new instance of PIN_IR
decode_results IRresults;
unsigned long LastValue; // letzter IR Code (bei gedrückt halten)
String Button = "";
unsigned long ButtonHold; // Knopf gedrückt

// FastLED
#define LED_TYPE NEOPIXEL
#define LED_PIN 10
#define NUM_LEDS 8
CRGB leds[NUM_LEDS];

// Loop
unsigned char Mode = 0; // 0 = Aus | 3 = Lampe

// Lampe
unsigned char LampVal = 255; // Helligkeit MAX bei Start
unsigned char LampValInt = 16; // Intervall für heller/dunkler (256/16 = 16 Stufen)



void setup() {
  // Start Konsole
  Serial.begin(115200);
  Serial.println("");
  Serial.println("Hallo Welt!");

  // Start IRremote (receiver)
  irrecv.enableIRIn();

  // Start FastLED
  FastLED.addLeds<LED_TYPE, LED_PIN>(leds, NUM_LEDS);
  FastLED.show();
}



void loop() {
  Remote(); // IR-Fernbedienung einlesen, "Knopf" ausgeben

  SelectMode(); // Modus wechseln
}



void Remote() {
  Button = ""; // Button zurücksetzen

  // IR-Signal empfangen
  if (irrecv.decode(&IRresults)) { // IR-Signal decodieren
    irrecv.resume(); // next value

    //    // IR-Signal ausgeben
    //    Serial.print("FB-Empfangen: ");
    //    Serial.println (IRresults.value, HEX);

    // Gedrückt Halten erkennung -> ButtonHold
    if (IRresults.value != 0xFFFFFFFF) { // Neues Signal
      LastValue = IRresults.value;
      ButtonHold = 0;
    }
    if (IRresults.value == 0xFFFFFFFF) { // Wiederholung
      IRresults.value = LastValue;
      ButtonHold = 1;
    }


    // Zuordnung FB-IR-Code -> Button
    switch (IRresults.value) {
      case 0xFF629D:
        Button = "HOCH";
        break;
      case 0xFFA857:
        Button = "RUNTER";
        break;
      case 0xFF22DD:
        Button = "LINKS";
        break;
      case 0xFFC23D:
        Button = "RECHTS";
        break;
      case 0xFF4AB5:
        Button = "0";
        break;
      case 0xFFB04F:
        Button = "3";
        break;
      case 0xFFFFFFFF:                // Eigentlich unnütz
        Button = "REPEAT";
        break;
    }


    //    // Ausgabe
    //    if (ButtonHold == 1) {
    //      Serial.print("Taste: ");
    //      Serial.print(Button);
    //      Serial.println(" (wdh.)");
    //    }
    //    else {
    //      Serial.print("Taste: ");
    //      Serial.println(Button);
    //    }
  }

}



void SelectMode() {

  // Alles: AUS
  if (Button == "0" && Mode != 0) {
    Mode = 0;

    fill_solid(leds, NUM_LEDS, CRGB::Black);
    FastLED.show();

    Serial.println("Alles: AUS");
  }

  // Lampe: EIN
  else if (Button == "3" && ButtonHold != 1 && Mode != 3) {
    Mode = 3;

    FastLED.setBrightness(LampVal);
    fill_solid(leds, NUM_LEDS, CRGB::White);
    FastLED.show();

    Serial.print("Lampe: EIN ");
    Serial.println(LampVal);
  }

  // Lampe: AUS
  else if (Button == "3" && ButtonHold != 1 && Mode == 3) {
    Mode = 0;

    fill_solid(leds, NUM_LEDS, CRGB::Black);
    FastLED.show();

    Serial.println("Lampe: AUS");
  }

  // Lampe: HELLER
  else if (Mode == 3 && Button == "HOCH") {
    if (LampVal <= 255 - LampValInt) {
      LampVal = LampVal + LampValInt;

      FastLED.setBrightness(LampVal);
      FastLED.show();

      Serial.print("Lampe: HELLER ");
      Serial.println(LampVal);
    }
    else {
      Serial.print("Lampe: MAX ");
      Serial.println(LampVal);
    }
  }

  // Lampe: DUNKLER
  else if (Mode == 3 && Button == "RUNTER") {
    if (LampVal >= 0 + LampValInt) {
      LampVal = LampVal - LampValInt;

      FastLED.setBrightness(LampVal);
      FastLED.show();

      Serial.print("Lampe: DUNKLER ");
      Serial.println(LampVal);
    }
    else {
      Serial.print("Lampe: MIN ");
      Serial.println(LampVal);
    }
  }

  // Lampe: WÄRMER
  else if (Mode == 3 && Button == "LINKS") {
    // ToDo
    
    FastLED.show();

    Serial.println("Lampe: WÄRMER ?");
  }

  // Lampe: KÄLTER
    else if (Mode == 3 && Button == "RECHTS") {
    // ToDo
    
    FastLED.show();

    Serial.println("Lampe: KÄLTER ?");
  }
}

demokan:
PS: Falls jemand noch Anregungen zur Code-Optimierung/Übersichtlichkeit hat... :wink:

Wirf alles auskommentierte, das Du nicht mehr brauchst, raus. Und stelle dann nur den gekürzten Sketch ins Forum. Dermaßen „unaufgeräumte“ Sketches lesen ich höchstens quer. Auf einen Lösungsvorschlag von mir muss jemand, der sowas zum Lesen zur Verfügung stellt, verzichten.

Gruß

Gregor

Alles klar.
Gekürzt, Remote & Seriell entfernt.

#include "FastLED.h"
CRGB leds[8];

unsigned char Mode = 0; // 0 = Aus | 3 = Lampe
unsigned char LampVal = 255; // Helligkeit MAX bei Start
unsigned char LampValInt = 16; // Intervall für heller/dunkler (256/16 = 16 Stufen)

void setup() {
  FastLED.addLeds< NEOPIXEL, 10 >(leds, 8); FastLED.show();
}


void loop() {

// Lampe: EIN
FastLED.setBrightness(LampVal);
fill_solid(leds, NUM_LEDS, CRGB::White); FastLED.show();

// Lampe: AUS
fill_solid(leds, NUM_LEDS, CRGB::Black); FastLED.show();

// Lampe: HELLER
if (LampVal <= 255 - LampValInt) {
      LampVal = LampVal + LampValInt;

      FastLED.setBrightness(LampVal);
      FastLED.show();
}

// Lampe: DUNKLER ---gekürzt---

// Lampe: WÄRMER
// ---ToDo---
    
FastLED.show();
}

// Lampe: KÄLTER
// ---ToDo---
    
FastLED.show();
}

}

Ich bin da kein Fachmann aber kälter heißt doch mehr Blau- und weniger Rotanteil - wärmer umgekehrt.
Evtl. ließe sich das auch im HSV-Farbmodell besser umsetzen, als in RGB. Die FastLED-Lib kann das.
Du müsstest also erst mal definieren (oder jemanden finden, der das für Dich definiert) wie wärmer und kälter sein sollen.

Gruß Tommy

Tommy56:
Evtl. ließe sich das auch im HSV-Farbmodell besser umsetzen, als in RGB. Die FastLED-Lib kann das.
Du müsstest also erst mal definieren (oder jemanden finden, der das für Dich definiert) wie wärmer und kälter sein sollen.

Ich würde für etwas derart Simples auf keinen Fall eine fremdprogrammierte Bibliothek nehmen.

@OP: Wichtig ist, dass Du weißt, wie Du einzelne Farben bzw. Teil-LEDs dimmen kannst. Dann überlegst Du, wie der Farbverlauf von „ganz kalt“ bis „heiß wie d'Sau“ aussehen soll. Ein Freund wollte mal ein derartiges Spektrum für ein Weltraumspiel umsetzen. Im Wesentlichen gibt es da Vier Punkte/Farben, die jeweils „reine“ Farben sind. Dazwischen sind es „Rampen“, die zu programmieren sind.

Für jemand, der das nicht nachvollziehen kann, ist es am besten, das Spektrum mal aufzuzeichen und zu überlegen, wie sich die drei Grundfarben zwischen den „Ankerpunkten“ verhalten sollen. Anfangen tust Du, indem Du die vier Punkte festlegst, die den vollständigen Farbverlauf in „Bereiche“ aufteilen (blau->grün->gelb->rot).

Wenn Du das hast, ist der Rest nur noch Fleißarbeit.

Gruß

Gregor

Tommy56:
... HSV-Farbmodell ...

Du guckst zu viel Fußball :slight_smile:

Ich habe tatsächlich eine Zigarettenlänge gebraucht, um zu merken, dass das V ein B sein muss (Brightness). Aber ich bin ja nun kein so doller Fußballgucker.

Gruß

Gregor

FastLED HSV Colors

HSV = Hue-Saturation-Value color model

gregorss:
Du guckst zu viel Fußball :slight_smile:

Ich habe tatsächlich eine Zigarettenlänge gebraucht, um zu merken, dass das V ein B sein muss (Brightness). Aber ich bin ja nun kein so doller Fußballgucker.

Gruß

Gregor

Ich schaue überhaupt keinen Fußball.
Deinen anderen Irrtum hat agmue schon korrigiert.

Gruß Tommy