int nEvents; int n; // Send UDP packet to wifi box, // This function expect a code and a parameter // The function tells the box what to do (Change color, on, off ...) // The param tells gives the function some params int SendUDP(int function, int param) { int i = 0; // Send every UDP command 3 times with an interval of 100ms // This way we are sure that the command reaches the wifi box do { STREAM* Socket = stream_create("/dev/udp/[URL="http://192.168.0.27/8899"]192.168.XXX.XXX/[/URL][PORT]",0,0); if (Socket == NULL) { printf("Creating UDP socket failed"); stream_close(Socket); } // Build the binary string to send char command[3]={function, param, 0x55 }; stream_write(Socket,command,sizeof(command)); stream_flush(Socket); stream_close(Socket); i = i + 1; sleep(100); } while (i < 3); return 1; } // Gets called with the group ID // This function will parse the RGB values received from the input // Using the RGB values we convert them to Hue and Brightness, saturation is not needed // Since our MiLight LEDS only accept a hue value and a brightness int SetGroup(int group, float f1) { char buffer[4]; char sR[4]; char sG[4]; char sB[4]; float red; float green; float blue; float bri; float r,g,b; float X, Y, Z, cx, cy; char input_color[10]; float hue; float sat; float milightColorNo; sprintf(input_color, "%d", (int)f1); printf("group: %d \n",group); // The following code parses the RGB color if (strlen(input_color) == 9) { sB[0] = input_color[0]; sB[1] = input_color[1]; sB[2] = input_color[2]; sB[3] = '\0'; sG[0] = input_color[3]; sG[1] = input_color[4]; sG[2] = input_color[5]; sG[3] = '\0'; sR[0] = input_color[6]; sR[1] = input_color[7]; sR[2] = input_color[8]; sR[3] = '\0'; } else if (strlen(input_color) == 8) { sB[0] = '0'; sB[1] = input_color[0]; sB[2] = input_color[1]; sB[3] = '\0'; sG[0] = input_color[2]; sG[1] = input_color[3]; sG[2] = input_color[4]; sG[3] = '\0'; sR[0] = input_color[5]; sR[1] = input_color[6]; sR[2] = input_color[7]; sR[3] = '\0'; } else if (strlen(input_color) == 7) { sB[0] = '0'; sB[1] = '0'; sB[2] = input_color[0]; sB[3] = '\0'; sG[0] = input_color[1]; sG[1] = input_color[2]; sG[2] = input_color[3]; sG[3] = '\0'; sR[0] = input_color[4]; sR[1] = input_color[5]; sR[2] = input_color[6]; sR[3] = '\0'; } else if (strlen(input_color) == 6) { sB[0] = '0'; sB[1] = '0'; sB[2] = '0'; sB[3] = '\0'; sG[0] = input_color[0]; sG[1] = input_color[1]; sG[2] = input_color[2]; sG[3] = '\0'; sR[0] = input_color[3]; sR[1] = input_color[4]; sR[2] = input_color[5]; sR[3] = '\0'; } else if (strlen(input_color) == 5) { sB[0] = '0'; sB[1] = '0'; sB[2] = '0'; sB[3] = '\0'; sG[0] = '0'; sG[1] = input_color[0]; sG[2] = input_color[1]; sG[3] = '\0'; sR[0] = input_color[2]; sR[1] = input_color[3]; sR[2] = input_color[4]; sR[3] = '\0'; } else if (strlen(input_color) == 4) { sB[0] = '0'; sB[1] = '0'; sB[2] = '0'; sB[3] = '\0'; sG[0] = '0'; sG[1] = '0'; sG[2] = input_color[0]; sG[3] = '\0'; sR[0] = input_color[1]; sR[1] = input_color[2]; sR[2] = input_color[3]; sR[3] = '\0'; } else if (strlen(input_color) == 3) { sB[0] = '0'; sB[1] = '0'; sB[2] = '0'; sB[3] = '\0'; sG[0] = '0'; sG[1] = '0'; sG[2] = '0'; sG[3] = '\0'; sR[0] = input_color[0]; sR[1] = input_color[1]; sR[2] = input_color[2]; sR[3] = '\0'; } else if (strlen(input_color) == 2) { sB[0] = '0'; sB[1] = '0'; sB[2] = '0'; sB[3] = '\0'; sG[0] = '0'; sG[1] = '0'; sG[2] = '0'; sG[3] = '\0'; sR[0] = '0'; sR[1] = input_color[0]; sR[2] = input_color[1]; sR[3] = '\0'; } else if (strlen(input_color) == 1) { sB[0] = '0'; sB[1] = '0'; sB[2] = '0'; sB[3] = '\0'; sG[0] = '0'; sG[1] = '0'; sG[2] = '0'; sG[3] = '\0'; sR[0] = '0'; sR[1] = '0'; sR[2] = input_color[0]; sR[3] = '\0'; } // Convert the strings back to int red = atoi(sR); green = atoi(sG); blue = atoi(sB); printf("red: %d \n",red); printf("green: %d \n",green); printf("blue: %d \n",blue); // Clear older hue and sat values hue = 0; sat = 0; // Convert based on RGB levels to HUE and Saturation if ((red >= green) && (green >= blue)) { hue = 60*(green-blue)/(red-blue); sat = (red - blue) / red; } else if ((green > red) && (red >= blue)) { hue = 60*(2 - (red-blue)/(green-blue)); sat = (green - blue) / green; } else if ((green >= blue) && (blue > red)) { hue = 60*(2 + (blue-red)/(green-red)); sat = (green - red) / green; } else if ((blue > green) && (green > red)) { hue = 60*(4 - (green-red)/(blue-red)); sat = (blue - red) / blue; } else if ((blue > red) && (red >= green)) { hue = 60*(4 + (red-green)/(blue-green)); sat = (blue - green) / blue; } else if ((red >= blue) && (blue > green)) { hue = 60*(6 - (blue-green)/(red-green)); sat = (red - green) / red; } sat = sat * 255; // set for safety again saturated at white if (blue == 0 && green == 0 && red == 0) { sat = 0; } // First map the 360 degrees value to a value of 0-255 milightColorNo =(176-(hue/360.0*255.0)); if ( milightColorNo < 0 ) { milightColorNo = 256+ milightColorNo; } // Convert the saturation to the brightness bri = sqrt(pow(red, 2) + pow(green, 2) + pow(blue, 2)); bri = bri * 2; if (bri > 255) { bri = 255; } // Falls nur 1 Farbe ein Thema, Helligkeit=Farbe if (red == 0 && green == 0) { bri = (blue * 255)/100; } if (blue == 0 && green == 0) bri = (red * 255)/100; if (red == 0 && blue == 0) bri = (green * 255)/100; // Milight only supports brightness levels from 2-27, so scale 0-255 to 0-27 bri=bri/255.0*27.0; if ( bri < 3) { bri=2; } // If all colors are the same level we get white, so set de RGB strip into white mode if (red > 0 || green > 0 || blue > 0 ) { if (red == green && green == blue && blue == red ) { if (group == 1) { // Set white mode for group 1 SendUDP( 0xC5, 0x00 ); } if (group == 2) { // Set white mode for group 2 SendUDP( 0xC7, 0x00 ); } if (group == 3) { // Set white mode for group 3 SendUDP( 0xC9, 0x00 ); } if (group == 4) { // Set white mode for group 4 SendUDP( 0xCB, 0x00 ); } // Set brightness (Will be executed only for the group selected above) SendUDP( 0x4E, (int) bri ); } else { if (group == 1) { // Group 1 on and if already on, select it SendUDP( 0x45, 0x00 ); } if (group == 2) { // Group 2 on and if already on, select it SendUDP( 0x47, 0x00 ); } if (group == 3) { // Group 3 on and if already on, select it SendUDP( 0x49, 0x00 ); } if (group == 4) { // Group 4 on and if already on, select it SendUDP( 0x4B, 0x00 ); } // Set hue color (Will be executed only for the group selected above) SendUDP( 0x40, milightColorNo ); // Set brightness (Will be executed only for the group selected above) SendUDP( 0x4E, (int) bri ); } } else { if (group == 1) { // Set group 1 off SendUDP( 0x46, 0x00 ); } if (group == 2) { // Set group 2 off SendUDP( 0x48, 0x00 ); } if (group == 3) { // Set group 3 off SendUDP( 0x4A, 0x00 ); } if (group == 4) { // Set group 4 off SendUDP( 0x4C, 0x00 ); } } return 1; } // Main Loop while (1==1) { nEvents = getinputevent(); //printf("this event: %d", nEvents); // Test bitwise if input 4 is changed (00001000) if (nEvents & 8) { SetGroup(1, getinput(0)); } // Test bitwise if input 5 is changed (00010000) if (nEvents & 16) { SetGroup(2, getinput(1)); } // Test bitwise if input AI3 is changed (0x20) = 32 if (nEvents & 32) { SetGroup(3, getinput(2)); } // Test bitwise if input AI3 is changed (0x20) = 32 if (nEvents & 64) { SetGroup(4, getinput(3)); } sleep(500); }
HOWTO: Günstige W-Lan RGB Controller Lösung (<35€) - Magic-UFO Wifi controller LD382
Einklappen
X
-
habe im Netz ein PicoC Skript gefunden, mit dem ich die RGB und Helligkeit steuern kann. Jedoch nicht die weissen LEDs, von meinem RGBW strip. Vielleicht kann jemand mir auf die Sprünge helfen, ich kann absolut nicht programmieren. Vorab Danke. Hier das Skript.
Code: -
Guten Tag,
habe hier im Forum über den Magic_UFO Wifi Controller LD382 gelesen da bin ich auf verschiedene Technische Daten gestoßen, auf der Seite
http://xcsource.com/xcsource-magic-l...y-modes-ld382/
Technical parameter :
Input voltage: DC12V-24V
- Power: Max 96W (DC 12V), Max 96W (DC 24V) (If more than 96W strips, please add power amplifier, thanks)
Output current: 2A*4CH
auf der Seite www.led-konzept.de stehen diese Technische Daten, das ist doch der selbe Controller oder sehe ich das falsch?
Stromstärke max.: 4A pro Kanal
- Leistung max. einfarbige LED Streifen: 48W (12V) - 96W (24V)
- Leistung max. RGB LED Streifen: 144W (12V) – 288W (24V)
- Leistung max. RGBW LED Streifen: 192W (12V) – 384W (24V)
Gruß
Bobo
Kommentar
-
Ich habe das Script mal überarbeitet.
* Man kann nun mit einem Baustein zwei Module ansprechen (AI1-AI5 sowie AI6-AI10).
* Die RGBW können entweder individuell angesteuert werden - z.B. 4 (nicht RGB) LED Streifen anhängen und diese individuell dimmen. (AI1-AI4 bzw. AI6-AI9)
Oder auch ein RGB LED Steifen anhängen - und über (AI5 bzw. A10) steuern.
* Zusätzlich kann man auswählen, welches Model man steuern will (CTRLTYPE 1 = LD382 oder CTRLTYPE 2 = LD382A).
* Die entsprechenden IP Adresse(n) müssen im Sript noch eingestellt werden.
Viel Spaß
Den Aktuellen Code findet man weiter unten.Kommentar
-
Vielen Dank für deine Mühe.
Ich habe das Skript soeben ausprobiert.
Die Farbauswahl funktioniert.
Die Regulierung der Helligkeit funktioniert auch.
Allerdings ist der LED-Streifen wesentlich dunkler als er bei der Ansteuerung beispielsweise aus FHEM heraus ist.
Irgendwo ist da noch ein BUG drin oder ich hab was falsch gemacht.1 BildKommentar
-
Hast du ein RGB oder ein RGBW-Streifen? ... bei RGBW musst vermutlich noch AI4 (also Weiß bzw. Helligkeit) anhängen. Bzw. den Wert 255 (das ist der Maximalwert) auf AI4 reinschicken.
Ich habe leider kein RGB Streifen sondern, nur ein 08/15 Warmweiß Streifen. Kann daher nur "theoretisch" testen
Vielen Dank für deine Mühe.
Ich habe das Skript soeben ausprobiert.
Die Farbauswahl funktioniert.
Die Regulierung der Helligkeit funktioniert auch.
Allerdings ist der LED-Streifen wesentlich dunkler als er bei der Ansteuerung beispielsweise aus FHEM heraus ist.
Irgendwo ist da noch ein BUG drin oder ich hab was falsch gemacht.Zuletzt geändert von Gast; 27.08.2017, 14:22.Kommentar
-
Zum Debuggen folgende Zeile (ca Position 102) einfügen...
NACH <state[7] = state[1] + ...>
printf("RGBW: %d %d %d %d",state[1], state[2], state[3], state[4]);
VOR <sendCmd(stream,state,8);>
Damit werden die Farbwerte im Log angezeigt, wenn diese zum Modul geschickt werden ... Wäre interessant, was da angezeigt wird.
Kommentar
-
Hallo,
Nope ... da sollte 255 stehen ...
Irgendwas stimmt da nicht ...
Im Script wird der Loxone Prozentwert (0%-100%) mit 2.55 multipliziert ...
for (base=0;base<4;base++) {
if (nEvents & (0x8 << (offset+base))) {
unsigned char V = (int) (getinput(base+offset)*2.55);
state[1+base]=V;
}
}
state[1] = (int) (rgb%1000)*2.55; // RED
state[2] = (int) (floor(rgb/1000)%1000)*2.55; // GREEN
state[3] = (int) (floor(rgb/1000000)%1000)*2.55; // BLUE
Auch wenn ich nicht verstehe warum ... einfach statt mit 2.55 - mit 25.5 multiplizieren.
Kommentar
-
TOP! Es läuft!
Jetzt stehen 255 bei den einzelnen Farben.
Oben kann man die 2.55 stehen lassen
und weiter unten dann die 25.5
state[1] = (int) (rgb%1000)*25.5; // RED
state[2] = (int) (floor(rgb/1000)%1000)*25.5; // GREEN
state[3] = (int) (floor(rgb/1000000)%1000)*25.5; // BLUEKommentar
-
Trotzdem stimmt irgendwas nicht ...
"Open" ist der Code für die Eingänge AI1 bis AI4. - jede Farbe auf einem dedizierten Kanal
"Unten" kümmert sich um AI5 ... Alle drei Farben (RGB) über ein Input
Laut deinem Screenshot, steuerst du dein LED Streifen aber über AI1-AI3 ... da sollte der "Untere" Code gar nicht zum Zug kommen.
Mit AI5 brauchst du auch das RGB-Licht-Scenen Programbaustein nicht ...
Kommentar
-
Hallo Gast,
vielen Dank für die Ergänzung des Programms!
Der RGB Lichtszenen Baustein liefert bei mir nur Werte von maximal 10 und nicht 100 auf den Ausgängen AQr, -g und -b, vielleicht ist es das, was da nicht stimmt?
Wenn der Ausgang AQa, des RGB Lichtszenen Baustein, mit dem AI5 des Programmbausteins verbunden ist, passiert bei mir nichts, auch nicht mit dem Baustein Lichtsteuerung (Ausgang auf RGB konfiguriert) und wenn ich die Werte wieder von 25.5 auf 2.55 zurück ändere. Es funktioniert bei mir nur in der Variante, wie oben auf dem Screenshot von raul999, gezeigt wird (AQr,g,b).
Gruß Red.Zuletzt geändert von ThatRed; 04.09.2017, 20:55.Kommentar
-
#58.1Gast kommentierte04.09.2017, 21:37Kommentar bearbeitenHallo,
Ja das stimmt - Lichtbaustein liefert auf den Einzelkanäle tatsächlich Werte zwischen 0 und 10 (mit einer Nachkomma-Stelle) ... auf den Kombinierten Ausgängen sind es aber 0-100 ...
Ich schau mir das ganze mal genauer an.
Eigentlich kannst du direkt über die Lichtsteuerung auf AI5 oder AI10 gehen - ohne "Umweg" über RGB Lichtszene - dazu einfach in der Lichtsteuerung den Ausgang als RGB definieren.
Weil ... Dimmer liefert 0-100 ... Lichtsteuerung 0-10 ... Hmmm ... da muß ich mir was kreatives einfallen lassen, damit beides funktioniert.
Außerdem haben wir da noch den "W" Kanal am LD382A ... von dem weiß das Loxone überhaupt nichts.
Ich schau mal, ob ich heute noch eine Angepasste Version poste.
Grüße
Kianusch
-
-
Hallo,
Diese Version kommt mit dem "RGB Lichtszene (AQr, AQg, AQb)" bzw. und dem Dimmer 0-10V klar. Dazu für
(Für AI1-AI4) char TYPE1=10;
(Für AI6-AI9) char TYPE2=10;
setzten.
Für DIMMER 0-100% entsprechend TYPE1=100; bzw TYPE2=100;
Der Kombinierte RGB Eingang (AI5/AI10) liefert auf alle Kanäle 0-100. Hier kann man direkt RGB Lichtszene AQa oder Lichtsteuerung-RGB andocken. Sofern man ein WHITE Channel hat, den man mit RGB kombinieren möchte, kann man die Variable AI5/AI10 setzen. Der Wert 1 bedeutet, dass der vierte Kanal über RGB errechnet wird (der Maximalwert von den dreien) oder separat über Eingang AI4/AI9 (z.B. über einen Dimmer Ausgang).
Hoffe es ist nicht zu verwirrend...
Viel Spaß
Code://RGBW Lichtsteuerung mit Magic-UFO Wifi controller //Version 0.1 by N1ghth4wk //Version 0.2 by RL //Version 0.3 by Iksi //Version 0.4 by Freeride24, Mod for new version of Magic-UFO Wifi controller -> LD382A ab FW1.0.6 //Version 0.5.1 by Kianusch //Version 0.5.2 by Kianusch // AI1/AI6 ... (0-10V|100%) RED Channel | DIMMER // AI2/AI7 ... (0-10V|100%) GREEN Channel | DIMMER // AI3/AI8 ... (0-10V|100%) BLUE Channel | DIMMER // AI4/AI9 ... (0-10V|100%) WHITE Channel | DIMMER // AI5/AI10 ... Combined RGB char* IP_ADDRESS_1 = "x.x.x.x"; char* IP_ADDRESS_2 = ""; // AI5 / AI10 RGB Type ... state[8] // 0=RGB + W (WHITE Value is used from AI4/AI9) // 1=RGB (WHITE Value is calculated from RGB | Ignored if no WHITE CHANNEL) char AI5=0; char AI10=0; // INPUT TYPE 0-10V ..... TYPEx=10 (RGB Lichtszene or Dimmer 0-10V) // 0-100% .... TYPEx=100 (Dimmer 0-100%) char TYPE1=100; char TYPE2=100; // CTRLTYPE - LD382 ............... 1 // LD382A ab FW1.0.6 ... 2 char CTRLTYPE=2; int PORT=5577; char dev1[64]; sprintf(dev1,"/dev/tcp/%s/%d",IP_ADDRESS_1,PORT); char dev2[64]; sprintf(dev2,"/dev/tcp/%s/%d",IP_ADDRESS_2,PORT); int nEvents; unsigned char state1[16]; unsigned char state2[16]; char lightOn[8]; char lightOff[8]; int cmdLen=0; void sendCmd(STREAM* stream, char *cmd, int len) { stream_write(stream,cmd,len); stream_flush(stream); sleep(100); } void parseInput(char* dev, char *state, int offset) { char ON=0; int base=0; // A1 = 8 0x8 | R // A2 = 16 0x10 | G // A3 = 32 0x20 | B // A4 = 64 0x40 | W // A5 = 128 0x80 | Combined RGB for (base=0;base<4;base++) { if (nEvents & (0x8 << (offset+base))) { unsigned char V = (int) ((getinput(base+offset)*255)/state[10]); state[1+base]=V; } } if (nEvents & (0x8 << (offset+base))) { int rgb = (int) getinput(offset+base); state[1] = ((rgb%1000)*255)/100; // RED state[2] = (((rgb/1000)%1000)*255)/100; // GREEN state[3] = (((rgb/1000000)%1000)*255)/100; // BLUE // WHITE (set to brightes Value from RGB) if (state[8]) { state[4]=state[1]; if (state[2]>state[4]) { state[4]=state[2]; } if (state[3]>state[4]) { state[4]=state[3]; } } } STREAM* stream = stream_create(dev,0,0); if (( state[1] + state[2] + state[3] + state[4] )>0) { ON = 1; // intro + R + G + B + W + 0 + termCmd state[7] = (state[0] + state[1] + state[2] + state[3] + state[4] + state[5] + state[6])%256; sendCmd(stream,state,8); // printf("RGB: %d %d %d %d",state[1], state[2], state[3], state[4]); } else { ON = 0; } // state[9] ... ON|OFF if (ON != state[9]) { state[9]=ON; if (ON) { sendCmd(stream,lightOn,cmdLen); } else { sendCmd(stream,lightOff,cmdLen); } } stream_close(stream); } // state[0] ... intro ... 0x31 // state[1] ... red // state[2] .... green // state[3] .... blue // state[4] .... white // state[5] .... 0x0 // state[6] .... 0x0 (LD382) | 0x0F (LD382A) // state[7] .... cs // // state[8] .... RGB/RGBW // state[9] .... on|off (1|0) ... state // state[10] ... TYPE 0-100%|0-10V (100|10) sprintf(state1,"%c%c%c%c%c%c%c%c%c%c%c", 0x31, 0, 0, 0, 0, 0, 0, 0, AI5, 0, TYPE1); sprintf(state2,"%c%c%c%c%c%c%c%c%c%c%c", 0x31, 0, 0, 0, 0, 0, 0, 0, AI10, 0, TYPE2); if (CTRLTYPE==1) { sprintf(lightOn,"%c%c%c", 0x71, 0x23, 0x94); sprintf(lightOff,"%c%c%c", 0x71, 0x24, 0x95); //state1[6]=0; //state1[6]=0; cmdLen=3; } else { sprintf(lightOn,"%c%c%c%c", 0x71, 0x23, 0x0F, 0xA3); sprintf(lightOff,"%c%c%c%c", 0x71, 0x24, 0x0F, 0xA4); state1[6]=0x0F; state2[6]=0x0F; cmdLen=4; } // Main loop while(TRUE) { nEvents = getinputevent(); if (nEvents & 0x00F8) { parseInput(dev1, state1, 0); } else if (nEvents & 0x1F00) { parseInput(dev2, state2, 5); } else { sleep (100); } }
Zuletzt geändert von Gast; 04.09.2017, 23:20.Kommentar
-
Hallo Gast,
jetzt funktioniert es, soweit es mir möglich war zu testen, allerdings habe ich "nur" IKEA Dioder RGB Leisten, keine RGBW LED Streifen. Mit dem RGB-Lichtszenen Baustein funktioniert es mit den Ausgängen AQr, g, b wenn TYPEx auf "10" steht und mit dem Ausgang AQa, wenn AI5 auf "1" und TYPEx auf "100" gesetzt wird. Andere Kombinationen habe ich jetzt nicht getestet.
Danke für die Fehlerkorrektur.
Gruß Red.Kommentar
-
Danke für's Testen.
Ja - für "RGB-Lichtszenen" ist TYPEx=10 die korrekte Einstellung.
Bei der zweiten Variante ...
TYPEx hat keinen Einfluß auf den Ausgang AQa ... das greift nur AQr/AQg/AQb ... also sollte es bei dem Ausgang egal sein ob 10 oder 100 ...
Und die Einstellung AI5 ist nur für RGBW relevant ... RGB Streifen (ohne W) funktionieren egal ob AI5 auf "1" oder "0" gesetzt ist.
Kianusch
-
Kommentar