Formel für Farb-/Lichtwechsler/Leuchtkreis für RGB LED

Einklappen
X
 
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge
  • Gast

    Formel für Farb-/Lichtwechsler/Leuchtkreis für RGB LED

    Hallo Freunde des Lichtkreises,

    hier mal eine Lösung mit Formelbaustein zur HSV -> RGB Umwandlung:

    i1: 0 ≤ H < 360 Farbwert
    i2: 0 ≤ S ≤ 100 Sättigung
    i3: 0 ≤ V ≤ 100 Hellwert

    Ausgang: RGB Wert für RGB-Lichtszene

    Viel Spass

    Code:
    int(i3*(i2*((1-ABS(i1/60-int(i1/120)*2-1))*(2-ABS(sign(int(i1/60)-1))-ABS(sign(int(i1/60)-4)))+(2-ABS(sign(int(i1/60)-0))-ABS(sign(int(i1/60)-5))))+100-i2)/100)+int(i3*(i2*((1-ABS(i1/60-int(i1/120)*2-1))*(2-ABS(sign(int(i1/60)-0))-ABS(sign(int(i1/60)-3)))+(2-ABS(sign(int(i1/60)-1))-ABS(sign(int(i1/60)-2))))+100-i2)/100)*1000+int(i3*(i2*((1-ABS(i1/60-int(i1/120)*2-1))*(2-ABS(sign(int(i1/60)-2))-ABS(sign(int(i1/60)-5)))+(2-ABS(sign(int(i1/60)-3))-ABS(sign(int(i1/60)-4))))+100-i2)/100)*1000000
    Zuletzt geändert von Gast; 13.04.2016, 12:24.
  • Gast

    #2
    Hier noch eine schnellere Variante, bei der auch Farbwerte >360° problemlos funktionieren.
    Somit kann einfach ein Stepper auf i1 gelegt werden.

    Code:
    i3*10^((int((i1/60+1)/2)-int(int((i1/60+1)/2)/3)*3)*3)+int(i3*(i2*((1-ABS(i1/60-int(i1/120)*2-1)))+100-i2)/100)*10^((int((int(i1/60)+4)/3)*3-int(i1/60)-2)*3)+int(i3*(100-i2)/100)*10^((int(i1/120)+2-int((int(i1/120)+2)/3)*3)*3)
    Klicke auf die Grafik für eine vergrößerte Ansicht

Name: Farbverlauf.jpg
Ansichten: 5167
Größe: 90,7 KB
ID: 38261
    Zuletzt geändert von Gast; 17.04.2016, 22:08.

    Kommentar

    • Special
      LoxBus Spammer
      • 27.08.2015
      • 435

      #3
      Danke, funktioniert super

      Kommentar

      • LoxFFB
        Extension Master
        • 29.08.2015
        • 197

        #4
        Sehr interessant
        Wie habt ihr das ganze in ein Programm verpackt ?
        Könnt ihr mal bitte einen Screenshot von eurer Config Posten?

        Vielen Dank

        Kommentar

        • Special
          LoxBus Spammer
          • 27.08.2015
          • 435

          #5
          Das anbinden an der Lichtsteuerung ist immer der bescheidenste Teil . Durch diesen sehr beschränkten Lichtsteuerungsbaustein wird es ein nur unnötig schwer gemacht.
          Ich habe den Farbverlauf vorerst Komplet in den Baustein eingebunden, dafür gehen dir natürlich drei Ausgänge flöten.
          Ich würde dir empfehlen für den Farbverlauf eine neue Seite anzulegen und mit Merkern zu arbeiten.
          Angehängte Dateien

          Kommentar

          • Riemen
            Smart Home'r
            • 01.10.2016
            • 40

            #6
            Hallo zusammen,

            erst mal vielen Dank an Till69 für deine Formel. Mit dieser konnte ich die HUE-RGB-Lampen über meine MDT-Glastaster ansteuern.
            Es gibt jetzt also 3 Tasten, die jeweils einen Dimmer für Helligkeit, Sättigung und Farbwert triggern. Deren Werte werden wiederum mittels eines Formelbausteins in RGB umgewandelt und steuern einen RGB-Lichtszenenbaustein.

            Das Problem dabei ist, dass ich an den Tastern keine Rückkopplung bekomme, wenn die Einstellungen über die Loxone-Visualisierung geändert wurden.

            Daher meine Bitte: Könnte jemand eine umgekehrte Version des der Formel zur Verfügung stellen, für einen Baustein, der einen Loxone-RGB-Wert reinbekommt und an drei Ausgängen die Werte für Sättigung, Helligkeit und Farbe herausliefert? Ich scheitere leider kläglich am Umstellen der Formel.

            Schon mal vielen Dank für die Mühe.

            Kommentar


            • Gast
              Gast kommentierte
              Kommentar bearbeiten
              Moin,

              hast Du an dem MDT Glastaster den Farbbalken benutzt?
          • Gast

            #7
            Ok, bitte schön

            Klicke auf die Grafik für eine vergrößerte Ansicht  Name: RGBtoHSV.jpg Ansichten: 1 Größe: 30,8 KB ID: 141180
            Inputs: RGB (0-255) (0-1 oder 0-10 geht ebenfalls, dann den Faktor in Formel V anpassen)

            Formel H: (0-360°)
            Code:
            (arctan(sqrt(3)*(i2-i3)/((2*i1-i3-i2)+1-sign(abs(2*i1-i3-i2))))*sign(abs((2*i1-i3-i2)))/pi+((sign((2*i1-i3-i2))-1)/2*sign(i3-i2-0,001)+(1-sign(sign(i2-i3)+1))*2)*sign(abs(2*i1-i3-i2)+abs(i2-i3)))*180
            Formel S: (0-100%)
            Code:
            (i2-i1)/i2*100
            Formel V: (0-100%)
            Code:
            i1/2,55
            Zuletzt geändert von Gast; 03.02.2018, 13:25.

            Kommentar

            • Riemen
              Smart Home'r
              • 01.10.2016
              • 40

              #8
              Hallo,

              erstmal Danke für die Formel. Den Min/Max-Baustein kannte ich nicht. Rein mit der Formel kann man ja leider keine if-Unterscheidungen umsetzen. Wäre also ein hässliches Konstrukt mit vielen Größer/kleiner-Bausteinen geblieben.

              Allerdings habe ich das Ganze jetzt anders umgesetzt. Das Ergebnis wollte ich sowieso noch hier posten:

              Ich liefere die HSV-Werte direkt aus dem PicoC-Baustein heraus, der sie auch an den Lampen setzt. Dort werden sie ja sowieso berechnet. Damit ich mit den Ausgängen hinkomme, habe ich die Werte aneinanderkonkateniert, ähnlich wie das mit den RGB-Werten auch passiert, also HHHSSSVVV.

              Anschließend schneide ich sie mit 3 Formelbausteinen wieder auseinander:

              Das Ganze sieht dann so aus:
              Klicke auf die Grafik für eine vergrößerte Ansicht  Name: 2018-02-03_12h37_07.png Ansichten: 1 Größe: 33,4 KB ID: 141281

              Hier der Code des modifizierten PicoC-Bausteins:
              Code:
              // Philips HUE Steuerung
              // Eingang des Programmbausteins wird mit dem Ausgang der Lichtsteuerung (RGB, Dimmer, Ein/Aus) verbunden
              //
              // (c) 2013 by Romy Glauser
              // FÜR LIVING COLORS GEN 2 - MIT HUE!
              //
              // (c) 2015 Erweiterung durch Andreas Lackner-Werner um LUMITECH (rgbw) & Gruppenfunktionen sowei generelles Cleanup des Codes
              //
              // (c) 2015 Erweiterung durch Sven Thierfelder um cx/cy Farbsteuerung für hue-bulbs sowie Glühlampensimulation
              //
              // überarbeitet TB 29.01.2018, HSV-Wert wird jetzt an allen Ausgängen ausgegeben
              
              
              int DEBUG_LEVEL=0;
              int DIMMER_MIN=15;  
              int DIMMER_MAX=100;
              int DIMMER_SIMMIN=154; //154 = 6400k
              int DIMMER_SIMMAX=500; //370 = 2700k
              
              // Übergangszeit von einem Dimmwert zum nächsten (10 = 1 Sekunde)
              int TRANSITION_TIME=10;
              
              // Bitte folgende Website:
              // http://www.developers.meethue.com/documentation/getting-started
              // beachten um einen gültigen User-Namen zu generieren!
              char* IP_ADDRESS = "192.168.0.11";
              char* PORT = "80";
              char* USERNAME = "ieppC7FumKLvIfb4Dib6YRXurzbyxe9-qSf0T1Ze";
              
              
              
              int inputType[12];
              
              // Hier die Funktion des Eingangs definieren:
              // 0 = RGB-Eingang (Eingang LoxoneFormat, 9-stellige Zahl die RGB codiert mit 100100100 für weiß. Ansteuerung der Lampe via Hue/Sat/Bri
              // 1 = Dimmereingang. Eingangswert muss im Bereich DIMMER_MIN / DIMMER_MAX sein. Ansteuerung der Lampe via Bri.
              // 2 = ON/OF - Eingang (z.B. für Steckdosen-Adapter)
              // 4 = RGB-Eingang (wie '0', aber ansteuerung der Lampe via X/Y/Bri)
              // 5 = Dimmereingang (wie '1', Ansteuerung der Lampe via Bri/Ct, Glühlampensimulation)
              
              // Wenn Lampengruppen bestehen, dann diese Typen verwenden:
              // 3 = RGB-Eingang (wie '0', aber steuert Lampengruppe via Hue/Sat/Bri)
              // 6 = RGB-Eingang (wie '0', aber steuert Lampengruppe via X/Y/Bri)
              // 7 = Dimmereingang, wie 1, aber für Gruppe
              
              inputType[0] = 0;  
              inputType[1] = 0;
              inputType[2] = 0;  
              inputType[3] = 0;
              inputType[4] = 0;
              inputType[5] = -1;
              inputType[6] = -1;
              inputType[7] = -1;
              inputType[8] = -1;
              inputType[9] = -1;
              inputType[10] = -1;
              inputType[11] = -1;
              
              int lightOrGroupID[12];  
              
              // Zuweisung der Lampen- oder GruppenIDs.
              // Definiert welcher Eingang des Bausteins welche Lampe bzw. Gruppe ansteuert:
              lightOrGroupID[0] = 1;  
              lightOrGroupID[1] = 2;
              lightOrGroupID[2] = 3;
              lightOrGroupID[3] = 4;
              lightOrGroupID[4] = 5;
              lightOrGroupID[5] = 6;
              lightOrGroupID[6] = 7;
              lightOrGroupID[7] = 8;
              lightOrGroupID[8] = 9;
              lightOrGroupID[9] = 10;
              lightOrGroupID[10] = 11;
              lightOrGroupID[11] = 12;
              
              
              // Ende der Konfiguration...
              
              
              char streamname[100];
              sprintf(streamname, "/dev/tcp/%s/%s/", IP_ADDRESS, PORT);
              
              int nEvents;
              
              int LIGHT = 1;
              int GROUP = 2;
              
              //INSERT TB 29.01.2018, zusätzliche globale Indexvariable, damit sie nicht überall hin durchgereicht werden muss -> nicht schön, aber funktioniert
              int idx;
              
              void updateLamp(int idx, float value) {
                  if (inputType[idx] == -1) {
                      //ignorieren
                  } else if (inputType[idx] == 0 || inputType[idx] == 4) {   // Lampe Bri/Hue/Sat or X/Y/Bri
                      if (value < 200000000) { // RGB
                          if (inputType[idx] == 0) {
                              setColorBHS(lightOrGroupID[idx], value, LIGHT);
                          } else if (inputType[idx] == 4) {
                              setColorXYB(lightOrGroupID[idx], value, LIGHT);
                          }
                      } else { // LUMITECH
                          setCtBri(lightOrGroupID[idx], value, LIGHT);
                      }
                  } else if (inputType[idx] == 1) {
                      setBrightness(lightOrGroupID[idx], value, LIGHT);
                  } else if (inputType[idx] == 7) {
                      setBrightness(lightOrGroupID[idx], value, GROUP);
                  } else if (inputType[idx] == 2) {
                      setOnOff(lightOrGroupID[idx], value);
                  } else if (inputType[idx] == 3 || inputType[idx] == 6) {  // Gruppe Bri/Hue/Sat or X/Y/Bri
                      if (value < 200000000) { // RGB
                          if (inputType[idx] == 3) {
                              setColorBHS(lightOrGroupID[idx], value, GROUP);
                          } else if (inputType[idx] == 6) {
                              setColorXYB(lightOrGroupID[idx], value, GROUP);
                          }
                      } else { // LUMITECH
                          setCtBri(lightOrGroupID[idx], value, GROUP);
                      }
                  } else if (inputType[idx] == 5) {
                      setBrightnessAsBulb(lightOrGroupID[idx], value);
                  }
              }
              
              void setBrightness(int lightID, float bri, int type) {
                  char command[100];
                  char selector[20];
                  // Normieren von 35-100 -> 1-255
                  if (bri > 0) {
                      bri = (bri- DIMMER_MIN )/( DIMMER_MAX - DIMMER_MIN )*254+1;
                  }
              
                  if (type==LIGHT) {
                         sprintf(selector,"lights/%d/state", lightID);
                  } else if (type==GROUP) {
                         sprintf(selector,"groups/%d/action", lightID);
                  }
              
                  if (bri == 0) {
                      sprintf(command, "{\"on\": false}");
                      if (DEBUG_LEVEL > 0) printf("Light %d OFF", lightID);
                  } else {
                      sprintf(command, "{\"on\": true, \"bri\": %d, \"transitiontime\": %d}", (int) (bri), TRANSITION_TIME);
                      if (DEBUG_LEVEL > 0) printf("Light %d ON %d%%", lightID, (int) ((bri-1)/2.55)+1);
                  }
              
                  sendCommand(selector, command);
              }
              
              void setBrightnessAsBulb(int lightID, float bri) {
                  char command[100];
                  char selector[20];
                  float ct,cl;
              
                  // Normieren von 35-100 -> 1-255
                  if (bri > 0) {
                          bri = (bri- DIMMER_MIN )/( DIMMER_MAX - DIMMER_MIN )*254+1;
                      cl = (DIMMER_SIMMAX - DIMMER_SIMMIN);
                      ct = DIMMER_SIMMAX - (cl * log10(1+((bri-1)/254)*9));
                  }
              
                  sprintf(selector,"lights/%d/state", lightID);
              
                  if (bri == 0) {
                          sprintf(command, "{\"on\": false}");
                          if (DEBUG_LEVEL > 0) printf("Light %d OFF", lightID);
                  } else {
                      sprintf(command, "{\"on\": true, \"bri\": %d, \"ct\": %d, \"transitiontime\": %d}", (int) (bri), (int) (ct), TRANSITION_TIME);
                      if (DEBUG_LEVEL > 0) printf("Light %d ON %d%% with %d", lightID, (int) ((bri-1)/2.55)+1, (int) (ct));
                  }
              
                  sendCommand(selector, command);
              }
              
              void setCtBri(int lightID, float ctbrivalue, int type) {
                  char command[100];
                  char selector[20];
                  float bri, ct;
                  int briNorm, miredNorm;
              
                  bri = floor((ctbrivalue-200000000) / 10000); // 0-100
                  ct = floor((ctbrivalue-200000000) - (bri * 10000)); // Wert in Kelvin, von 2700 - 6500
              
              
                  briNorm = (int) round(bri*2.55); // 0-255
                  miredNorm = (int) round(1000000/ct); // Wert von 154 - 370
              
              
              
                  if (type==LIGHT) {
                         sprintf(selector,"lights/%d/state", lightID);
                  } else if (type==GROUP) {
                         sprintf(selector,"groups/%d/action", lightID);
                  }
              
                  if (bri == 0) {
                      sprintf(command, "{\"on\": false}");
                      if (DEBUG_LEVEL > 0) printf("Light %d OFF", lightID);
                  } else {
                      sprintf(command, "{\"on\": true, \"bri\": %d, \"ct\": %d, \"transitiontime\": %d}", briNorm, miredNorm, TRANSITION_TIME);
                      if (DEBUG_LEVEL > 0) printf("Light %d ON %d%% %dK", lightID, (int) bri, (int) ct);
                  }
              
                  sendCommand(selector, command);
              }
              
              
              void setOnOff(int lightID, float bri) {
                  char command[100];
                  char selector[20];
              
                  sprintf(selector,"lights/%d/state", lightID);
              
                  if (bri == 0) {
                      sprintf(command, "{\"on\": false}");
                      if (DEBUG_LEVEL > 0) printf("Light %d OFF", lightID);
                  } else {
                      sprintf(command, "{\"on\": true}");    
                      if (DEBUG_LEVEL > 0) printf("Light %d ON", lightID);
                  }
              
                  sendCommand(selector, command);
              
              }
              
              void setColorXYB(int lightOrGroupID, float rgbvalue, int type) {
                  char buffer[256];
                  float red,green,blue;
                  float cx,cy, bri;
                  float X,Y,Z;
                  char command[100];
                  char selector[50];
              
                  blue = floor(rgbvalue/1000000);
                  green = floor((rgbvalue-blue*1000000)/1000);
                  red = rgbvalue-blue*1000000-green*1000;
              
                  bri = blue;
                  if (bri < green) bri = green;
                  if (bri < red) bri = red;
                  bri = bri * 2.55;
              
                  blue = blue / 100;
                  green = green / 100;
                  red = red / 100;
              
                  // Apply gamma correction
                  if (red > 0.04055) {
                      red = pow((red + 0.055) / 1.055, 2.4);
                  } else {
                      red = red / 12.92;
                  }
                  if (green > 0.04055) {
                      green = pow((green + 0.055) / 1.055, 2.4);
                  } else {
                      green = green / 12.92;
                  }
                  if (blue > 0.04055) {
                      blue = pow((blue + 0.055) / 1.055, 2.4);
                  } else {
                      blue = blue / 12.92;
                  }
                  // Convert to XYZ
                  X = red * 0.649926 + green * 0.103455 + blue * 0.197109;
                  Y = red * 0.234327 + green * 0.743075 + blue * 0.022598;
                  Z = red * 0.013932 + green * 0.053077 + blue * 1.035763;
                  // Calculate xy and bri
                  if ((X+Y+Z) == 0){
                      cx = 0;
                      cy = 0;
                  } else { // round to 4 decimal max (=api max size)
                      cx = X / (X + Y + Z);    
                      cy = Y / (X + Y + Z);
                  }
              
                  if (type==LIGHT) {
                         sprintf(selector,"lights/%d/state", lightOrGroupID);
                  } else if (type==GROUP) {
                         sprintf(selector,"groups/%d/action", lightOrGroupID);
                  }
              
                  if (bri == 0) {
                      sprintf(command, "{\"on\": false}");
                  } else {
                      sprintf(command, "{\"xy\": [%f,%f],\"bri\": %d,\"on\":true, \"transitiontime\": %d}", cx, cy, bri, TRANSITION_TIME);
                  }
              
                  if (DEBUG_LEVEL > 1) printf(command);
              
                  sendCommand(selector,command);
              
              }
              
              void setColorBHS(int lightOrGroupID, float rgbvalue, int type) {
                  char buffer[256];
                  float red,green,blue;
                  float hue,sat,bri;
                  char command[100];
                  char selector[50];
              
                  // Hinweis: rgbvalue ist red + green*1000 + blue*1000000
                  blue = floor(rgbvalue/1000000);
                  green = floor((rgbvalue-blue*1000000)/1000);
                  red = rgbvalue-blue*1000000-green*1000;
              
                  // nochmal umrechnen nach hue irgendwie, weil die Living Colors Gen2 irgendwie nich gehen mit xy
                  hue = 0;
                  sat = 0;
                  bri = 0;
              
                  if (blue > 0 || green > 0 || red > 0) {
              
                      if ((red >= green) && (green >= blue)) {
                          if (red == blue) {
                               hue = 0;
                          } else {
                               hue = 60*(green-blue)/(red-blue);
                          }
                          sat = (red - blue) / red;
                          bri = red;
                      } else if ((green > red) && (red >= blue)) {
                          hue = 60*(2 - (red-blue)/(green-blue));
                          sat = (green - blue) / green;
                          bri = green;
                      } else if ((green >= blue) && (blue > red)) {
                          hue = 60*(2 + (blue-red)/(green-red));
                          sat = (green - red) / green;
                          bri = green;
                      } else if ((blue > green) && (green > red)) {
                          hue = 60*(4 - (green-red)/(blue-red));
                          sat = (blue - red) / blue;
                          bri = blue;
                      } else if ((blue > red) && (red >= green)) {
                          hue = 60*(4 + (red-green)/(blue-green));
                          sat = (blue - green) / blue;
                          bri = blue;
                      } else if ((red >= blue) && (blue > green)) {
                          hue = 60*(6 - (blue-green)/(red-green));
                          sat = (red - green) / red;
                          bri = red;
                      }
              
                      // Werte für HUE normieren (hue = 0-65535, sat 0-255, bri 0-255)
                      hue = hue / 360 * 65535;
                      sat = sat * 255;    
                      bri = bri * 2.55;
                  }
              
                  //INSERT TB 29.01.2018, Jetzt wird der Wert noch an passenden Ausgang ausgegeben
                  setOutputHSV(hue,sat,bri);
              
                  // Ausgeben ins Log
                  if (DEBUG_LEVEL > 1) printf("value:%09d, b:%d, g:%d, r: %d, hue:%d, sat: %d, bri: %d\n", rgbvalue, blue, green, red, (int)hue, (int)sat, (int)bri);
              
                  if (bri == 0) {
                      sprintf(command, "{\"on\": false}");
                      if (DEBUG_LEVEL > 0 && type==LIGHT ) printf("Light %d OFF", lightOrGroupID);
                      if (DEBUG_LEVEL > 0 && type==GROUP ) printf("Group %d OFF", lightOrGroupID);
                  } else {
                      sprintf(command, "{\"bri\": %d, \"hue\": %d, \"sat\": %d, \"on\": true, \"transitiontime\": %d}", (int)bri, (int)hue, (int)sat, TRANSITION_TIME);
                      if (DEBUG_LEVEL > 0 && type==LIGHT ) printf("Light %d ON %d%%, %d° %d%%", lightOrGroupID, (int) ((bri-1)/2.55)+1, (int) (hue / 65535 * 360), (int)(sat/2.55));
                      if (DEBUG_LEVEL > 0 && type==GROUP ) printf("Group %d ON %d%%, %d° %d%%", lightOrGroupID, (int) ((bri-1)/2.55)+1, (int) (hue / 65535 * 360), (int)(sat/2.55));
                  }
              
                  if (type==LIGHT) {
                         sprintf(selector,"lights/%d/state", lightOrGroupID);
                  } else if (type==GROUP) {
                         sprintf(selector,"groups/%d/action", lightOrGroupID);
                  }
              
                  sendCommand(selector, command);
              
              }
              
              void sendCommand(char* selector, char* command) {
              
                  STREAM* TcpStream = stream_create(streamname,0,0);
                  if (TcpStream == NULL) {
                      printf("Creating Stream failed");
                      stream_close(TcpStream);
                      return;
                  }
              
                  char buffer[1024];
                  sprintf(buffer, "PUT /api/%s/%s HTTP/1.1\r\nHost: %s\r\nConnection: keep-alive\r\nContent-Length: %d\r\n\r\n%s",
                          USERNAME, selector, IP_ADDRESS, strlen(command), command);
                  if (DEBUG_LEVEL > 1) printf(buffer);
                  stream_write(TcpStream,buffer,sizeof(buffer));
                  stream_flush(TcpStream);
                  stream_close(TcpStream);
              }
              
              //INSERT TB 29.01.2018, die HSV-Werte werden "aneinanderkonkateniert", analog zu den RGB-Werten an den zu den Eingängen passenden Ausgängen ausgegeben
              void setOutputHSV(float hue, float sat, float bri) {
                  float hsvValue;
              
                  // Auf 0-100% normieren, wird für Glastaster gebraucht
                  hue = round(hue / 655.35);
                  sat = round(sat / 2.55);
                  bri = round(bri / 2.55);
              
                  hsvValue = hue * 1000000 + sat * 1000 + bri;
                  setoutput(idx,hsvValue);
              }
              
              while (1==1) {
                  nEvents = getinputevent();
              
                  // Sonderfunkion: AI12 löst ein "ALLES AUSSCHALTEN"-Signal an die HUE-Bridge aus
                  if (nEvents & 0x8 << 12 && getinput(12)==1) {
                      if (DEBUG_LEVEL > 0) printf("All Lights OFF");
                      sendCommand( "groups/0/action", "{\"on\":false}");
                  // Alle anderen Eingänge werden an die HUE laut Konfiguration weitergegeben:
                  } else {
                      int i;
                      for (i = 0; i < 12; i++) {
                          if (nEvents & 0x8 << i) {
                              //INSERT TB 29.01.2018, zusätzliche globale Indexvariable gesetzt
                              idx = i;
                              updateLamp(i, getinput(i));
                              sleep(150);
                          }
                      }
                  }
              
                  sleep(100);
              }
              Formel für den Farbwert:
              Code:
              INT(i1/1000000)
              Formel für die Sättigung:
              Code:
              INT((i1-INT(i1/1000000)*1000000)/1000)
              und die Formel für die Helligkeit:
              Code:
              i1-INT(i1/1000)*1000
              Das Ganze klappt mittlerweile reibungslos. Vorteil ist, egal von welcher Quelle die RGB-Werte in den PicoC-Baustein gesetzt werden, sie werden immer an den Glastastern synchron gehalten und dass hässliche Springen der Farben beim ersten Bedienen der Glastaster fällt weg.

              Zusammen mit https://www.loxforum.com/forum/germa...C3%BCr-rgb-led haben wir jetzt diverse Möglichkeiten der Umwandlung von HSV in RGB-Werte und umgekehrt.

              Kommentar


              • romildo
                romildo kommentierte
                Kommentar bearbeiten
                Gibt es einen Grund dafür, die berechneten Werte nicht direkt an den Ausgängen des Programmbausteins auszugeben?
                Beispiel:
                Farbwert an AQ1
                Sättigung an AQ2
                Helligkeit an AQ3

              • Riemen
                Riemen kommentierte
                Kommentar bearbeiten
                @romildo:
                Der Baustein kann ja 12 (theoretisch 13) Lampen gleichzeitig ansteuern. Für 13 Eingangswerte brauche ich also 13x die Farbwerte am Ausgang. natürlich könnte ich immer die Werte der zuletzt gesetzten Lampe ausgeben und beispielsweise mit getriggerten Analogspeichern arbeiten. Wie mache ich aber die Zuordnung am Ausgang, wenn 2 Lampen in unterschiedlichen Räumen gleichzeitig geändert werden, also wie kann ich dann erkennen, ob der ausgegebene Wert zu Lampe 1 oder 2 gehört?
                Um das zu umgehen habe ich mich für die Lösung mit den zusammenhängenden Werten entschieden.

                EDIT: Übrigens kommen später ja noch andere Lampen dazu. Also nur Farbtemperatur oder nur DImmen. (Derzeit habe ich nur RGB). Bei diesen werden dann an den Ausgängen entspreched andere Werte herausgeliefert (Derzeit mangels Testlampen noch nicht implementiert).
                Zuletzt geändert von Riemen; 03.02.2018, 14:22.

              • romildo
                romildo kommentierte
                Kommentar bearbeiten
                Ich muss zugeben, ich habe das vorher zu wenig gelesen und war der Meinung dass dies nur einmal benötigt wird.
                Wenn Du dies natürlich bis zu 13 mal brauchst, dann wird es wohl so am einfachsten sein.

                Wenn Du aber noch weitere Ausgänge frei haben möchtest müsste dies schon auch mit Analogspeichern möglich sein.
                Die Daten von 2 Lampen werden ja nicht gleichzeitig verarbeitet sondern hintereinander.
                Du könntest also Beispielsweise die Lampennnummer an AQ1, den Farbwert an AQ2, die Sättigung an AQ3 und die Helligkeit an AQ4 ausgeben.
                An AQ1 hängst Du dann AIs eines Radiotastenbausteins.
                Ausgang1 des Radiotastenbausteins verbindest Du mit den Tr Eingängen der Analogbausteine für Lampe 1, Ausgang 2 mit Tr für Lampe 2 usw..
            • Gast

              #9
              Zitat von Riemen
              Rein mit der Formel kann man ja leider keine if-Unterscheidungen umsetzen.
              Doch, das Geheimnis heißt "sign".

              Klar geht PicoC, aber da ist meine Lösung doch etwas eleganter.

              Kommentar


              • Riemen
                Riemen kommentierte
                Kommentar bearbeiten
                Wieso eleganter? Der PicoC-Baustein ist sowieso da, denn er setzt ja die Werte an die Lampen. Intern werden die HSV-Werte ja sowieso berechnet. Klar ist die Lösung mit den aneinanderkonkatenierten Werten nicht optimal, aber der begrenzten Anzahl von Ausgängen geschuldet.

                Deine Logik setzt übrigens auch getrennte RGB-Eingangswerte vorraus. Die sind aber nicht überall vorhanden. Die Lichtsteuerung liefert z.B. nur die zusammenkonkatenierten RGB-Werte. Also müsste man hier noch zusätzlich meine Logik zum Auseinanderschneiden davor packen, bräuchte also nochmal 3 Extraformeln.
                Ich will jetzt auch gar keine Diskussion über Systemlasten der beiden Varianten anfangen.

                Ich denke es sind beides praktikable Wege. Für welchen man sich letztlich entscheidet, hängt vom konkreten Anwendungsfall ab: Wer nur RGB-Werte, am besten in 3 getrennten Quellen vorliegen hat, kann deine Lösung verwenden. Wer hingegen sowieso HUE-Lampen ansteuert sollte evtl. über meine Lösung nachdenken.
            • Gast

              #10
              Hallo,

              hat schon jemand versucht das ganze über den MDT Glastaster II zu steuern?
              Welcher EIS Typ in Loxone waäre der passende?

              Kommentar


              • Riemen
                Riemen kommentierte
                Kommentar bearbeiten
                Genau die habe ich auch.

                Um den gesamten Farbraum deiner Lampen abdecken zu können, wirst Du aber min. 3 Tasten brauchen. Eben für Farbwert (Hue), Sättigung (Saturation) und Helligkeit (Value). Ich habe aus diesem Grund auf Eintastenbedienung umgestellt.

                Die Tasten senden bei den HSV Einstellungen aber keine Analogwerte, sondern sind als Dimmer konfiguriert, senden also nur die Infos, ob eine Taste gedrückt ist oder nicht.

                Damit die Werte in Loxone ankommen, musst Du je Taste 3 EIB Sensoren konfigurieren:

                Erweiterte Sensoren für
                Werte erhöhen:
                Ein: x/x/x:9
                Aus: x/x/x:0

                Werte senken:
                Ein: x/x/x:1
                Aus: x/x/x:0

                und je einen normalen Sensor für
                Wert ein/aus:
                x/x/y -> Achtung, die Adressen unterscheiden sich, welche es sind hängt von der gewählten Taste ab

                Die 3 Eingänge kannst Du dann je Taste mit einem Dimmer verbinden (+/- und Trigger).

                Ich habe die Dimmer so konfiguriert, dass sie Werte von 0-100 ausgeben. Das passt dann zu Glastastern. Also einfach die Ausgänge mit den Aktoren der Tasten verbinden und die Anzeige stimmt schon mal.

                Für den Hue-Baustein brauchst Du dann noch RGB-Werte. Dass bekommst Du mit folgender Formel hin:

                Code:
                i3*10^((int((i1*3.6/60+1)/2)-int(int((i1*3.6/60+1)/2)/3)*3)*3)+int(i3*(i2*((1-ABS(i1*3,6/60-int(i1*3.6/120)*2-1)))+100-i2)/100)*10^((int((int(i1*3,6/60)+4)/3)*3-int(i1*3.6/60)-2)*3)+int(i3*(100-i2)/100)*10^((int(i1*3.6/120)+2-int((int(i1*3.6/120)+2)/3)*3)*3)
                Diese einfach in einen Formelbaustein einfügen und die Ausgänge deiner 3 Dimmer für HSV mit den 3 ersten EIngängen der Formel verbinden.

                Jetzt kommt ein RGB-Wert heraus, den du an den HUE-Baustein setzen kannst.




                Bei den vorherigen Beiträgen gehts darum, dass die Anzeige der Glastaster mitbekommt, wenn der Farbwert über die Visualisierung geändert wurde. Dann wird die Schaltung aber nochmal um einiges komplizierter.

              • Gast
                Gast kommentierte
                Kommentar bearbeiten
                Danke für die Antwort,
                Kannst du mir bitte noch den Ausschnitt aus der Loxone Config zeigen?
            • Riemen
              Smart Home'r
              • 01.10.2016
              • 40

              #11
              Hier mal ein Bild der Schaltung. Damit kannst Du eine Hue-Lampe über 3 Glastaster-Tasten steuern (den Analogspeicher kannst Du ignorieren, den hab ich vergessen rauszulöschen):Klicke auf die Grafik für eine vergrößerte Ansicht  Name: 2018-02-06_13h58_09.png Ansichten: 1 Größe: 38,6 KB ID: 141651
              Klicke auf die Grafik für eine vergrößerte Ansicht  Name: DSC_4176.jpg Ansichten: 3 Größe: 1,30 MB ID: 141654
              Zuletzt geändert von Riemen; 06.02.2018, 22:40.

              Kommentar


              • Gast
                Gast kommentierte
                Kommentar bearbeiten
                Super Danke,

                klappt soweit ganz gut.
                Kann man für die Sättigung auch eine Konstante vorgeben, dass ich mir den Taster Spare?
                Kann man den Farbdurchlauf und das Dimmen schneller laufen lassen? Das läuft doch recht langsam.

                Grüße!

              • Riemen
                Riemen kommentierte
                Kommentar bearbeiten
                Klar kannst Du die Sättigung per Konstante setzen. Allerdings kannst Du die Farbe der Lampen dann nicht mehr zwischen weiß und farbig verändern, eben die Sättigung setzen. Schau dir mal an, wie der HSV-Farbraum aufgebaut ist. Um alle Achsen abzudecken brauchst Du halt 3 Variablen.
                Ich hab die Taster deswegen auf 3 Ebenen geändert. Dann hab ich 4 Tasten für die Beleuchtung.

                Du kannst in den Dimmern die Schrittzeit und die Schrittweite nach deinen Wünschen einstellen, dann wird's schneller.
                Zuletzt geändert von Riemen; 07.02.2018, 14:41.
            • Riemen
              Smart Home'r
              • 01.10.2016
              • 40

              #12
              Zitat von till69
              Ok, bitte schön

              Klicke auf die Grafik für eine vergrößerte Ansicht Name: RGBtoHSV.jpg Ansichten: 1 Größe: 30,8 KB ID: 141180
              Inputs: RGB (0-255) (0-1 oder 0-10 geht ebenfalls, dann den Faktor in Formel V anpassen)

              Formel H: (0-360°)
              Code:
              (arctan(sqrt(3)*(i2-i3)/((2*i1-i3-i2)+1-sign(abs(2*i1-i3-i2))))*sign(abs((2*i1-i3-i2)))/pi+((sign((2*i1-i3-i2))-1)/2*sign(i3-i2-0,001)+(1-sign(sign(i2-i3)+1))*2)*sign(abs(2*i1-i3-i2)+abs(i2-i3)))*180
              Formel S: (0-100%)
              Code:
              (i2-i1)/i2*100
              Formel V: (0-100%)
              Code:
              i1/2,55
              Hallo Till,

              da ich für eine andere Schaltung eine Umwandlung von RGB in HSV brauche, habe ich deine Formel mal ausprobiert. Dazu habe ich eine Testschaltung gebaut, die HSV in RGB und wieder zurück wandelt. Der HSV to RGB-Baustein enthält Deine Formel von oben:
              Klicke auf die Grafik für eine vergrößerte Ansicht  Name: 2018-02-10_17h16_35.png Ansichten: 1 Größe: 71,3 KB ID: 142361

              Leider bekomme ich nicht annähernd die Ausgangswerte wieder heraus. Was mache ich falsch? Im Anhang die Testschaltung.

              Vielen Dank für Deine Mühe.
              Zuletzt geändert von Riemen; 10.02.2018, 17:36.

              Kommentar

              • Labmaster
                Lox Guru
                • 20.01.2017
                • 2486

                #13
                1. kann es sein, das du die Formel für V nicht angepasst hast ?
                2. Am Min/Max fehlt zumindest im Screenshot der Roteingang ( und AI2 ist gar nicht angeschlossen, sieht zumindest so aus).
                3. Ohne mich jetzt tiefer in die Umrechnung eingearbeitet zu haben bin ich mit nicht sicher, ob die HSV zu RGB Umrechnung stimmt.
                Es gibt ja z.B. online Umrechner (z.B. https://www.rapidtables.com/convert/...sv-to-rgb.html ), wenn man da z.B. für HSV 20°, 80%, 12% eingibt, dann kommt (mit Skalierung 0 bis 255) als RGB Wert 31,14,6 raus, wenn man dies nun auf 100% runter rechnet komme ich nicht auf 12, 5 und 2 ???

                Aber wie gesagt, nur mal ein schnelles drüber schauen, eventuell hab ich da auch was grundsätzliches übersehen.

                Kommentar

                • Riemen
                  Smart Home'r
                  • 01.10.2016
                  • 40

                  #14
                  Zitat von Labmaster
                  1. kann es sein, das du die Formel für V nicht angepasst hast ?
                  Was meinst Du damit? Ich habe obige Formeln übernommen. Die V scheint in der Tat noch falsch zu sein (siehe unten)

                  2. Am Min/Max fehlt zumindest im Screenshot der Roteingang ( und AI2 ist gar nicht angeschlossen, sieht zumindest so aus).
                  Den Roteingang hab ich tatsächlich übersehen. Der andere war dran, aber ist schlecht zu erkennen auf dem Screenshot, das stimmt.

                  3. Ohne mich jetzt tiefer in die Umrechnung eingearbeitet zu haben bin ich mit nicht sicher, ob die HSV zu RGB Umrechnung stimmt.
                  Es gibt ja z.B. online Umrechner (z.B. https://www.rapidtables.com/convert/...sv-to-rgb.html ), wenn man da z.B. für HSV 20°, 80%, 12% eingibt, dann kommt (mit Skalierung 0 bis 255) als RGB Wert 31,14,6 raus, wenn man dies nun auf 100% runter rechnet komme ich nicht auf 12, 5 und 2 ???
                  Also bei mir passt das jetzt ungefähr: Wenn ich die Werte 41 52 24 (siehe unten) auf 255 normiere, komme ich schon näher dran:
                  Klicke auf die Grafik für eine vergrößerte Ansicht  Name: 2018-02-10_20h47_03.png Ansichten: 1 Größe: 26,7 KB ID: 142406

                  Ich habe die Schaltung nochmal überarbeitet: V stimmt immer noch nicht, die anderen Werte ungefähr zu passen:

                  Klicke auf die Grafik für eine vergrößerte Ansicht  Name: 2018-02-10_20h53_37.png Ansichten: 1 Größe: 65,1 KB ID: 142407
                  Allerdings gibt es anscheinend noch unschöne Rundungsfehler. Kann man die Formeln evtl so anpassen, dass wieder der Ausgangswert rauskommt?
                  Zuletzt geändert von Riemen; 10.02.2018, 21:00.

                  Kommentar


                  • Gast
                    Gast kommentierte
                    Kommentar bearbeiten
                    In diesem Fall hast Du den V Wert schon am Max Ausgang

                  • stefan.schmidhuber@sbg.at
                    stefan.schmidhuber@sbg.at kommentierte
                    Kommentar bearbeiten
                    Hallo Till - Hast du es hinbekommen ohne die unschönen Rundungsfehler? Würde mich sehr interessieren - lg. Stefan
                • Holger_kausch
                  LoxBus Spammer
                  • 27.08.2015
                  • 323

                  #15
                  Hallo ...
                  Ich möchte gerne den RGB Wert aus Loxone als kombinierten 3 Byte Wert DPT 232.600 auf meinen KNX Bus senden ..

                  Kann mir da jemand weiter helfen ?

                  Gruß Holger

                  Kommentar

                  Lädt...