RGB Leds Light - Mood Light
-
I think most people have already seen that 15 dollars multisensor build by Ben from BruhAutomation.
Here is the link: https://www.youtube.com/watch?v=jpjfVc-9IrQUnfortunately (at least for this community) he uses a NomeMCU board instead of using a MySensors connection.
It would be awesome porting that whole sketch and project to a MySensors battery powered node... sorry if I am missing somebody´s work that already did that.
All the sensors together are relatively easy to build on mysensor, but what I can´t figure out is that awesome RGB LED wich turns into a complete Light Component, with fade, color changing and transitions.
Could someone share a mysensors node or help porting that Bruh Sketch, specially the RGB Led part?
It would be something like a Mood Light!
Here is original code:
https://github.com/bruhautomation/ESP-MQTT-JSON-Multisensor
-
@OliverDog here is a link to such a sketch (https://forum.mysensors.org/topic/2160/my-mysensors-rgbw-plug-in-has-an-init-problem)
-
Thanks @BartE !
Three more questions:
- Will it work with a single 4 pin RGB LED common cathode instead of a LED strip?
- Will it work with Home Assistant Controller like a ordinary RGB Light?
- Could it run on batteries?
Thanks again.
-
Hi @OliverDog , yes this should work
-
Will it work with a single 4 pin RGB LED common cathode instead of a LED strip?
--> Uncomment this line "#define RGBW 1" to make it three color (RGB) in stead of four (RGBW). -
Will it work with Home Assistant Controller like a ordinary RGB Light?
--> Should work with HAC since it presents it self as a RGB module -
Could it run on batteries?
--> Yes why not, but please do read some forum posts about what to think about when running mysensors on batteries, there are several of them
-
-
Finally I tried this weekend but no success...
First I have updated your sketch to 2.0 version (I think I made everything right)
Didn't work on Home Assistant because the sketch don't send an initial value for each configuration of the Leds, such as Dimmer, RGB, Light, Fade, etc.I did not figure out how to create an initial value loop because there are no MyMessage msg(Child_, V_) on the sketch...
Could you help me again?
Thanks very much...Here is the updated sketch:
// RBG led strip plug in. // by Bart Eversdijk (c) 2015. #define MY_DEBUG #define MY_RADIO_NRF24 #define MY_NODE_ID 3 #include <MySensors.h> #include <SPI.h> #define SUBID 1 // sensor number needed in the custom devices set up #define RED 6 // Arduino PWM pin for Red #define GREEN 5 // Arduino PWM pin for Green #define BLUE 3 // Arduino PWM pin for Blue #define NODENAME "RGB Led2" enum ANIMATIOMODES {RAINBOW=0,RANDONMIZE,FADERGB,FADEMULTICOLR,FLASHCOLOR,LAST_PROGRAM}; byte FADE_RGB_COLOR_MODES[] = {0b0010,0b0011,0b0100,0b0101,0b1000,0b1001, 0xFF}; byte FADE_MULTI_COLOR_MODES[] = {0b0010,0b0011,0b0110,0b0111,0b0100,0b0101,0b1100,0b1101,0b1000,0b1001,0b1010,0b1011,0xFF}; static bool first_message_sent = false; byte rgb_pins[] = {RED, GREEN, BLUE}; byte ledOffValues[] = {0, 0, 0, 0}; byte rgb_values[] = {0, 0, 0, 0}; void incomingMessage(const MyMessage &message); #define NUM_OF_COLORS sizeof(rgb_pins) int speedtable[] = { 0, 100, 50, 2 }; #define NUM_OF_SPEEDS sizeof(speedtable) struct { byte values[4]; byte speedsetting; byte mode; bool status; } rgb = { {0,0,0,0}, 0, RAINBOW, false}; bool flashOn = true; int syscounter = 0; int lastUpdate = 0; bool newSetting = false; void before() { // Set the rgb(w) pins in output mode for (int i = 0; i < NUM_OF_COLORS; i++) { pinMode(rgb_pins[i], OUTPUT); } recallEeprom(); setLedValues(rgb.values, true); Serial.println("Init done"); } void presentation() { sendSketchInfo(NODENAME, "1.0"); present(SUBID, S_RGB_LIGHT); } void loop() { // Alway process incoming messages whenever possible if (speedtable[rgb.speedsetting] > 0) { if ((syscounter % speedtable[rgb.speedsetting]) == 0) { switch (rgb.mode) { case RAINBOW: animateRainbowStep(); break; case FADERGB: animateFadeColorStep(FADE_RGB_COLOR_MODES); break; case FADEMULTICOLR: animateFadeColorStep(FADE_MULTI_COLOR_MODES); break; case FLASHCOLOR: setLedValues(flashOn ? ledOffValues : rgb.values, false); flashOn = !flashOn; break; case RANDONMIZE: long number = random(0, 0xFFFFFF); rgb_values[0] = number >> 16 & 0xFF ; rgb_values[1] = number >> 8 & 0xFF ; rgb_values[2] = number & 0xFF; setLedValues(rgb_values, false); break; } } delay(rgb.mode == RANDONMIZE || rgb.mode == FLASHCOLOR ? 50 : 1); } if (newSetting && (lastUpdate + 30000 < syscounter)) { // Wait for a couple of seconds be fore actual storing the current setting in to EEPROM // This will save the EEPROM's life time, when playing around with colors Serial.println(" Store EERPOM"); storeEeprom(); newSetting = false; } delay(1); syscounter++; } void animateRainbowStep() { static float counter = 0; float pi = 3.14159; counter++; rgb_values[0] = map(sin(counter/100 )*1000,-1000,1000,0,255); rgb_values[1] = map(sin(counter/100 + pi*2/3)*1000,-1000,1000,0,255); rgb_values[2] = map(sin(counter/100 + pi*4/3)*1000,-1000,1000,0,255); setLedValues(rgb_values, false); } void animateFadeColorStep(byte *modes) { static int modecnt = 0; if (updateRGBValues(modes[modecnt] >> 1, (modes[modecnt] & 0x1) == 0x1)) { modecnt = (modes[modecnt+1] == 0xFF ? 0 : modecnt + 1); } } bool updateRGBValues(byte mode, bool down) { bool endReached = false; for (byte i = 0; i < 3; i++) { if (((mode >> i) & 0x1) == 0x1) { rgb_values[i] += (down ? -1 : 1); endReached |= (down && (rgb_values[i] == 0x00)) || (!down && (rgb_values[i] == 0xFF)); } } setLedValues(rgb_values, false); return endReached; } void incomingMessage(const MyMessage &message) { if (message.type == V_RGB || message.type == V_RGBW) { // starting to process the hex code String hexstring = message.getString(); long number; #ifdef RGBW char white[3]; white[0] = hexstring[6]; white[1] = hexstring[7]; white[2] = 0; number = (long) strtol( &white[0], NULL, 16); rgb.values[3] = number & 0xFF; #endif hexstring[6] = 0; number = (long) strtol( &hexstring[0], NULL, 16); rgb.values[0] = number >> 16 & 0xFF ; rgb.values[1] = number >> 8 & 0xFF ; rgb.values[2] = number & 0xFF; rgb.speedsetting = 0; setLedValues(rgb.values, true); lastUpdate = syscounter; newSetting = true; } if (message.type == V_STATUS) { if (message.getBool()) { Serial.println("ON: Switch to last known color values"); setLedValues(rgb_values, true); } else { Serial.println("OFF: Switch colors off"); setLedValues(ledOffValues, true); } rgb.speedsetting = 0; rgb.status = message.getBool(); lastUpdate = syscounter; newSetting = true; } if (message.type == V_VAR1) { Serial.println("Set speed and program value"); byte newsetting = message.getByte(); rgb.speedsetting = (newsetting >> 4) & 0x0F; byte newmode = newsetting & 0x0F; if (newmode != rgb.mode) { for (byte i = 0; i < NUM_OF_COLORS; i++) { rgb_values[i] = 0; } rgb.mode = newmode; } if (rgb.speedsetting > 0) { rgb.status = true; } lastUpdate = syscounter; newSetting = true; Serial.print("Data 0x"); Serial.print(newsetting, HEX); Serial.print(" speed:"); Serial.print(rgb.speedsetting); Serial.print(" mode:"); Serial.println(rgb.mode); } } void setLedValues(byte *rgb, bool show) { for (int i = 0; i < NUM_OF_COLORS; i++) { analogWrite(rgb_pins[i], rgb[i]); } if (show) { Serial.print("Red: " ); Serial.print(rgb[0], HEX); Serial.print(" Green: " ); Serial.print(rgb[1], HEX); Serial.print(" Blue: " ); Serial.print(rgb[2], HEX); #ifdef RGBW Serial.print(" White is " ); Serial.print(rgb[3], HEX); #endif Serial.println(); } } void storeEeprom() { byte address = 0; byte *p = (byte *)&(rgb); for (byte i = 0; i < sizeof(rgb); i++) { saveState(address++, p[i]); } } void recallEeprom() { byte address = 0; byte *p = (byte *)&(rgb); for (byte i = 0; i < sizeof(rgb); i++) { p[i] = loadState(address++); } }
-
I tried another sketch from
https://forum.mysensors.org/topic/6765/rgb-led-stripIt worked with HASS but there is no response based on transitions time.
/** * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. * * LED STRIP sketch for Mysensors ******************************* * * REVISION HISTORY * 1.0 * Based on the example sketch in mysensors * 1.1 * fadespeed parameter (send as V_VAR1 message) * HomeAssistant compatible (send status to ack) */ #define MY_NODE_ID AUTO #define MY_DEBUG #define MY_RADIO_NRF24 #include <MySensors.h> #define CHILD_ID_LIGHT 1 #define SN "LED Strip" #define SV "1.1" MyMessage lightMsg(CHILD_ID_LIGHT, V_LIGHT); MyMessage rgbMsg(CHILD_ID_LIGHT, V_RGB); MyMessage dimmerMsg(CHILD_ID_LIGHT, V_DIMMER); byte red = 255; byte green = 255; byte blue = 255; byte r0 = 255; byte g0 = 255; byte b0 = 255; char rgbstring[] = "ffffff"; int on_off_status = 0; int dimmerlevel = 100; int fadespeed = 0; #define REDPIN 6 #define GREENPIN 5 #define BLUEPIN 3 void setup() { // Fix the PWM timer. Without this the LEDs will flicker. TCCR0A = _BV(COM0A1) | _BV(COM0B1) | _BV(WGM00); // Output pins pinMode(REDPIN, OUTPUT); pinMode(GREENPIN, OUTPUT); pinMode(BLUEPIN, OUTPUT); } void presentation() { // Send the Sketch Version Information to the Gateway sendSketchInfo(SN, SV); present(CHILD_ID_LIGHT, S_RGB_LIGHT); } void loop() { static bool first_message_sent = false; if ( first_message_sent == false ) { Serial.println( "Sending initial state..." ); set_hw_status(); send_status(); first_message_sent = true; } } void receive(const MyMessage &message) { int val; if (message.type == V_RGB) { Serial.println( "V_RGB command: " ); Serial.println(message.data); long number = (long) strtol( message.data, NULL, 16); // Save old value strcpy(rgbstring, message.data); // Split it up into r, g, b values red = number >> 16; green = number >> 8 & 0xFF; blue = number & 0xFF; send_status(); set_hw_status(); } else if (message.type == V_LIGHT || message.type == V_STATUS) { Serial.println( "V_LIGHT command: " ); Serial.println(message.data); val = atoi(message.data); if (val == 0 or val == 1) { on_off_status = val; send_status(); set_hw_status(); } } else if (message.type == V_DIMMER || message.type == V_PERCENTAGE) { Serial.print( "V_DIMMER command: " ); Serial.println(message.data); val = atoi(message.data); if (val >= 0 and val <=100) { dimmerlevel = val; send_status(); set_hw_status(); } } else if (message.type == V_VAR1 ) { Serial.print( "V_VAR1 command: " ); Serial.println(message.data); val = atoi(message.data); if (val >= 0 and val <= 2000) { fadespeed = val; } } else { Serial.println( "Invalid command received..." ); return; } } void set_rgb(int r, int g, int b) { analogWrite(REDPIN, r); analogWrite(GREENPIN, g); analogWrite(BLUEPIN, b); } void set_hw_status() { int r = on_off_status * (int)(red * dimmerlevel/100.0); int g = on_off_status * (int)(green * dimmerlevel/100.0); int b = on_off_status * (int)(blue * dimmerlevel/100.0); if (fadespeed >0) { float dr = (r - r0) / float(fadespeed); float db = (b - b0) / float(fadespeed); float dg = (g - g0) / float(fadespeed); for (int x = 0; x < fadespeed; x++) { set_rgb(r0 + dr*x, g0 + dg*x, b0 + db*x); delay(100); } } set_rgb(r, g, b); r0 = r; b0 = b; g0 = g; } void send_status() { send(rgbMsg.set(rgbstring)); send(lightMsg.set(on_off_status)); send(dimmerMsg.set(dimmerlevel)); }