Fire pit RGB striplight controller


  • Hero Member

    I built a fire pit in our back yard using an old crusher mantle.

    0_1474105410511_pit2.jpg

    I wanted the area to look nice so added some led strip lighting to the underside of the railings

    0_1474105518826_DSCN0590.jpg

    There are some clear led garden lights as well. Together the make a very inviting place to entertain friends.

    0_1474105718510_combo.jpg

    and a very comfy place to relax on the cooler nights

    0_1474105787319_pit.jpg

    So now it is time to bring the lighting under Mysensors control. This is a work in progress and I will post wiring etc as I go but thought i would throw the sketch up for a start.

    This node will control the RGB strip as well as separate switch for the white garden lights. In Domoticz the RGB controller looks like this. It can be used to set the brightness and colour of the strip. I will be using mosfet's to control all of the lights.

    0_1474106133732_Screenshot (140).jpg

    The current sketch is working well on a breadboard prototype using a single RGB led . I will probably add some form of colour cycling as well as I progress.

    /*
    RGB LED Node for 12v common anode rgb strip,
    Also has a standard on/off switch to control an extra set of garden lights 
    PWM pins (3, 5, 6, 9, 10, or 11).
    */
    
    // Enable debug prints to serial monitor
    #define MY_DEBUG 
    #define MY_NODE_ID 200  // I use 200 for my test nodes I will remove this line when it is installed
    // Enable and select radio type attached
    #define MY_RADIO_NRF24
     
    #include <SPI.h>
    #include <MySensors.h>
    #define RGB_CHILD_ID 1  // the rbg device includes a dimmer and on/off switch as well
    #define CHILD_ID_LIGHT_B 2
    
     const int controlPinA = 7;  //used to turn of rgb Power pin
     const int controlPinB = 8;  //used to switch off other garden lights
     const int redPin = 3;     //pin used to switch the red mosfet
     const int greenPin = 5;  //pin used to switch the green mosfet
     const int bluePin = 6;  //pin used to switch the blue mosfet
     long RGB_values[3] = {0,0,0};  //array used to hold the three rgb colours
     int dimSet = 0;                 // holder for the current dimmer setting
    // int dimHolder = 0;             
    
     
    void setup()
    {
      pinMode(controlPinA, OUTPUT);    //|
      pinMode(controlPinB, OUTPUT);    //|
      pinMode(redPin, OUTPUT);         //| setup pins as outputs
      pinMode(greenPin, OUTPUT);       //| 
      pinMode(bluePin, OUTPUT);        //|
      setColor(0,0,0);                 // make sure lights are off when first booted
    }
    
    void presentation()  {
      // Present sketch (name, version)
      sendSketchInfo("RGB Node", "1.0");        
           
      // Register sensors (id, type, description, ack back) 
       present(RGB_CHILD_ID, S_RGB_LIGHT,"Firepit RGB Control");
       present(CHILD_ID_LIGHT_B, S_LIGHT,"Firepit Lights");
    }
     
    void loop()
    {
      //nothing needed in here
    }
    
    /*-----------------Start of functions---------------------*/
    
    
    /*----------- function to display LED colour as well as set brightness------------*/
    void setColor(int red, int green, int blue){  
    if (dimSet != 0){
     analogWrite(redPin, round(red*dimSet/100));          //|
     analogWrite(greenPin, round(green*dimSet/100));      //| change the three rgb colours and adjust brightness
     analogWrite(bluePin, round(blue*dimSet/100));        //|
    }
    else{                                                // if dimmer setting is 0 then set all colours to 0
      analogWrite(redPin, dimSet);
      analogWrite(greenPin, dimSet);
      analogWrite(bluePin, dimSet);
    }  
    #ifdef MY_DEBUG            //Print debug info if enabled
      Serial.print("RED = ");
      Serial.println(red);
      Serial.print("BLUE = ");
      Serial.println(blue);
      Serial.print("GREEN = ");
      Serial.println(green);
     #endif
    }
    
    
    
    void receive(const MyMessage &message) {
      
     if (message.type==V_RGB) {             //check for RGB message type
          /*   process the RGB hex code    */
        String rgbHexString = message.getString();                      //Load the hex color code into a string
        long number = (long) strtol( &rgbHexString[0], NULL, 16);
        RGB_values[0] = number >> 16;
        RGB_values[1] = number >> 8 & 0xFF;
        RGB_values[2] = number & 0xFF;
        setColor(RGB_values[0],RGB_values[1],RGB_values[2]);            // call the setColor function to update the LED's
      #ifdef MY_DEBUG                                                   //Print debug info if enabled
         Serial.print("HEX RGB " );
         Serial.println(rgbHexString);
         Serial.print("long number " );
         Serial.println(number);
      #endif
     }
         
     if (message.type==V_DIMMER) {                                        //check for dimmer message type
        dimSet = message.getInt();                                        // Load the dimmer setting into dimSet
        setColor(RGB_values[0],RGB_values[1],RGB_values[2]);              // call the setColor function to update the LED's. new dimmer setting
        #ifdef MY_DEBUG                                                   //Print debug info if enabled
         Serial.print("dimmer setting " );
         Serial.println(dimSet);
        #endif
     }
          
     if (message.type==V_LIGHT) {                                     //check for incoming  light switch message type
        switch (message.sensor) {
          case 1:                                                     //message is for sensor 1 (RGB switch)
            digitalWrite(controlPinA, message.getBool() ? 1 : 0);
            break;
          case 2:                                                     //message is for sensor 2 (garden lights)
            digitalWrite(controlPinB, message.getBool() ? 1 : 0);
            break;
         }
        #ifdef MY_DEBUG
          Serial.print("Incoming change for sensor:");
          Serial.println(message.sensor);
          Serial.print("Light switch setting " );
          Serial.println(message.getBool());
        #endif
        }
     }
    
    
    
    
    

  • Admin

    Beautiful!



  • wow. that looks great!!



  • Nice work, looks fantastic!


  • Hero Member

    Found a nice routine for the colour cycling, it gives a very smooth fade between colours.

    Sketch below

    /*
    RGB LED Node for 12v common anode rgb strip,
    Also has a standard on/off switch to control an extra set of garden lights 
    and a standard on/off switch to select colour cycling
    PWM pins (3, 5, 6, 9, 10, or 11).
    colour cycling routine from https://gist.github.com/jamesotron/766994
    
    */
    
    // Enable debug prints to serial monitor
    #define MY_DEBUG 
    #define MY_NODE_ID 200  // I use 200 for my test nodes I will remove this line when it is installed
    // Enable and select radio type attached
    #define MY_RADIO_NRF24
     
    #include <SPI.h>
    #include <MySensors.h>
    #define RGB_CHILD_ID 1  // the rbg device includes a dimmer and on/off switch as well
    #define CHILD_ID_LIGHT_B 2
    #define CYCLE_SWITCH_ID 3
    
     const int controlPinA = 7;  //used to turn on/off rgb Power pin
     const int controlPinB = 8;  //used to switch on/off other garden lights
     const int redPin = 3;     //pin used to switch the red mosfet
     const int greenPin = 5;  //pin used to switch the green mosfet
     const int bluePin = 6;  //pin used to switch the blue mosfet
     long RGB_values[3] = {0,0,0};  //array used to hold the three rgb colours
     int dimSet = 0;                 // holder for the current dimmer setting
     int cycleSpeed = 20;    // this sets the speed of the colour cycling 
     bool cycleState = 0;    // used to check if colour cycling is turned on
    
    // int dimHolder = 0;             
    MyMessage msg(CYCLE_SWITCH_ID, V_STATUS);    
     
    void setup()
    {
      pinMode(controlPinA, OUTPUT);    //|
      pinMode(controlPinB, OUTPUT);    //|
      pinMode(redPin, OUTPUT);         //| setup pins as outputs
      pinMode(greenPin, OUTPUT);       //| 
      pinMode(bluePin, OUTPUT);        //|
      setColor(0,0,0);                 // make sure lights are off when first booted
    }
    
    void presentation()  {
      // Present sketch (name, version)
      sendSketchInfo("RGB Node", "1.0");        
           
      // Register sensors (id, type, description, ack back) 
       present(RGB_CHILD_ID, S_RGB_LIGHT,"Firepit RGB Control");
       present(CHILD_ID_LIGHT_B, S_LIGHT,"Firepit Garden Lights");
       present(CYCLE_SWITCH_ID, S_LIGHT,"Cycle Switch");
    }
     
    void loop()
    {
      
    if (cycleState == 1){  // check to see is colour cycling is turned on
      cyclecolor();
    }
    }
    
    /*-----------------Start of functions---------------------*/
    
    
    /*----------- function to display LED colour as well as set brightness------------*/
    void setColor(int red, int green, int blue){  
    if (dimSet != 0){
     analogWrite(redPin, round(red*dimSet/100));          //|
     analogWrite(greenPin, round(green*dimSet/100));      //| change the three rgb colours and adjust brightness
     analogWrite(bluePin, round(blue*dimSet/100));        //|
    }
    else{                                                // if dimmer setting is 0 then set all colours to 0
      analogWrite(redPin, dimSet);
      analogWrite(greenPin, dimSet);
      analogWrite(bluePin, dimSet);
    }  
    #ifdef MY_DEBUG            //Print debug info if enabled
      Serial.print("RED = ");
      Serial.println(red);
      Serial.print("BLUE = ");
      Serial.println(blue);
      Serial.print("GREEN = ");
      Serial.println(green);
     #endif
    }
    
    
    /*------------------process incoming messages--------------------*/
    void receive(const MyMessage &message) {
      
     if (message.type==V_RGB) {             //check for RGB message type
          /*   process the RGB hex code    */
        String rgbHexString = message.getString();                      //Load the hex color code into a string
        long number = (long) strtol( &rgbHexString[0], NULL, 16);
        RGB_values[0] = number >> 16;
        RGB_values[1] = number >> 8 & 0xFF;
        RGB_values[2] = number & 0xFF;
        setColor(RGB_values[0],RGB_values[1],RGB_values[2]);            // call the setColor function to update the LED's
      #ifdef MY_DEBUG                                                   //Print debug info if enabled
         Serial.print("HEX RGB " );
         Serial.println(rgbHexString);
         Serial.print("long number " );
         Serial.println(number);
      #endif
     }
         
     if (message.type==V_DIMMER) {                                   //check for dimmer message type
         if(cycleState == 1){                                     // new incoming colour change, turn off cycling if it is on
         send(msg.set(false));
         cycleState = 0;
         }
        dimSet = message.getInt();                                        // Load the dimmer setting into dimSet
        setColor(RGB_values[0],RGB_values[1],RGB_values[2]);              // call the setColor function to update the LED's. new dimmer setting
        #ifdef MY_DEBUG                                                   //Print debug info if enabled
         Serial.print("dimmer setting " );
         Serial.println(dimSet);
        #endif
     }
          
     if (message.type==V_LIGHT) {                                     //check for incoming  light switch message type
        switch (message.sensor) {
          case 1:                                                     //message is for sensor 1 (RGB switch)
            digitalWrite(controlPinA, message.getBool() ? 1 : 0);
            break;
          case 2:                                                     //message is for sensor 2 (garden lights)
            digitalWrite(controlPinB, message.getBool() ? 1 : 0);
            break;
          case 3:                                                     // message is for sensor 3 (colour cycle switch)
            cycleState = message.getBool() ? 1: 0;
            break;
            
         }
        #ifdef MY_DEBUG                                            //print some degug info if enabled
          Serial.print("Incoming change for sensor:");
          Serial.println(message.sensor);
          Serial.print("Light switch setting " );
          Serial.println(message.getBool());
        #endif
        }
     }
     
    /*---------------function to cycle colours-----------------------*/
    void cyclecolor(){
    
    /*Start off with red*/
      RGB_values[0] = 255;
      RGB_values[1] = 0;
      RGB_values[2] = 0; 
      /* Choose the colours to increment and decrement.*/
      for (int decColour = 0; decColour < 3; decColour += 1) {
        int incColour = decColour == 2 ? 0 : decColour + 1;
    
      /* cross-fade the two colours*/
      for(int i = 0; i < 255; i += 1) {
       RGB_values[decColour] -= 1;
       RGB_values[incColour] += 1;
       analogWrite(redPin, RGB_values[0]);
       analogWrite(greenPin, RGB_values[1]);
       analogWrite(bluePin, RGB_values[2]);
       if (cycleState == 0){                 // If colour cycling is turned off break out to main loop
         break;
       }
       wait(cycleSpeed);   // this controls the speed of the colour cycling
      }
     }
    }
    
    


  • @Boots33
    Looks awesome!
    I have a question. I took your sketch and it works great, but is it possible not to use the separate V_LIGHT to turn it on/off? What I mean is that I don't want to put a rele or a MOSFET to control the RGB power but to start/stop dimming by using just one RGB icon in domoticz. And turn it off by either setting dimmer value to 0 or pressing the off button in domoticz RGB switch. Is it possible?


  • Hero Member

    Hi @Tigroenot The reason i used the xtra mosfet was mainly so the leds would just resume with whatever they were previously set to when the rgb switch was turned back on and also as this node is powered all the time wanted to make sure it turned off completely. I can see no reason why you could not do away with the IRF4905 and just set the three channels to 0.
    You would need to save the current state to the arduino eeprom if you wanted to have it resume with the same colour etc when the switch is turned back on.

    In fact part of the code does set all the channels to 0 already if the dim level is set to 0.

    You can see below that if dimSet = 0 then the else statement is executed , setting all the channels to 0

    void setColor(int red, int green, int blue){  
    if (dimSet != 0){
     analogWrite(redPin, round(red*dimSet/100));          //|
     analogWrite(greenPin, round(green*dimSet/100));      //| change the three rgb colours and adjust brightness
     analogWrite(bluePin, round(blue*dimSet/100));        //|
    }
    else{                                                // if dimmer setting is 0 then set all colours to 0
      analogWrite(redPin, dimSet);
      analogWrite(greenPin, dimSet);
      analogWrite(bluePin, dimSet);
    }  
    

    You would also need to change the code where it reacts to the incoming message from the RGB switch.

    Instead of

    case 1:                                                     //message is for sensor 1 (RGB switch)
            digitalWrite(controlPinA, message.getBool() ? 1 : 0);     // change state of RGB power switch
            break;
    
    

    you would need to try something like the code below. It is untested so you may need to tweak it a bit.

    case 1:                                                     //message is for sensor 1 (RGB switch)
           // digitalWrite(controlPinA, message.getBool() ? 1 : 0);     // change state of RGB power switch
            if (message.getBool()== 0){
             setColor(0,0,0);                 // turn lights off
             cycleState = 0;                  // turn off colour cycling
            }
            else{
              setColor(200,0,0);     // turn lights red when first turned on
            }
    
            break;

  • Hero Member

    I have been distracted from this project with other things but intend to finish it off soon. I am posting the current wiring diagram which I have tested with a 5m RGB strip. I can confirm the mosfets do not heat up at all, even without heatsinks so all looks good.

    I am thinking of changing the clear garden lights from a mosfet to a relay as they are powered by 12AC so will need to rectify that or switch the AC with a relay. still a work in progress

    The circuit

    0_1480590413384_firepit controller.jpg


  • Hero Member

    So I decided to leave the garden lights running on 12v AC as this may offer less voltage drop and wire corrosion than if I were to switch to DC.

    I had a double relay module on hand so have added an extra switch to the sketch. this node now controls the RGB Strip as well as the two relays. The relay modules need to be switched high to turn off so I have also modified the sketch to suit.

    I think the sketch and diagram below will be the ones I use.

    /*
    RGB LED Node for 12v common anode rgb strip,
    Also has two standard on/off switches to control  extra  garden lights 
    and a standard on/off switch to select colour cycling
    PWM pins (3, 5, 6, 9, 10, or 11).
    colour cycling routine from https://gist.github.com/jamesotron/766994
    
    */
    
    // Enable debug prints to serial monitor
    #define MY_DEBUG 
    #define MY_NODE_ID 200  // I use 200 for my test nodes I will remove this line when it is installed
    // Enable and select radio type attached
    #define MY_RADIO_NRF24
    
    #include <SPI.h>
    #include <MySensors.h>
    #define RGB_CHILD_ID 1                // the rbg device includes a dimmer and on/off switch as well
    #define CHILD_ID_LIGHT_1 2            //garden lights 1
    #define CYCLE_SWITCH_ID 3             // colour cycle switch
    #define CHILD_ID_LIGHT_2 4            // garden lights 2
    
    const int controlPinA = 7;                          //pin used to turn on/off rgb Power 
    const int controlPin1 = 8;                          //pin used to switch on/off  garden lights 1
    const int controlPin2 = 4;                          //pin used to switch on/off garden lights 2
    const int redPin = 3;                               //pin used to switch the red mosfet
    const int greenPin = 5;                             //pin used to switch the green mosfet
    const int bluePin = 6;                              //pin used to switch the blue mosfet
    long RGB_values[3] = {0,0,0};                       //array used to hold the three rgb colours
    int dimSet = 0;                                     // holder for the current dimmer setting
    int cycleSpeed = 20;                                // this sets the speed of the colour cycling 
    bool cycleState = 0;                                // used to check if colour cycling is turned on. 0 means it will be off when node starts up
    bool onceOnly = 0;                                  //used to excecute some code once at startup
               
    MyMessage msg(CYCLE_SWITCH_ID, V_STATUS);    
    MyMessage rgbmsgA(RGB_CHILD_ID, V_PERCENTAGE);
    MyMessage gardenlightmsg1(CHILD_ID_LIGHT_1, V_STATUS); 
    MyMessage gardenlightmsg2(CHILD_ID_LIGHT_2, V_STATUS);
    
    void setup()
    {
    pinMode(controlPinA, OUTPUT);    //|
    pinMode(controlPin1, OUTPUT);    //|
    pinMode(controlPin2, OUTPUT);    //|
    pinMode(redPin, OUTPUT);         //| setup pins as outputs
    pinMode(greenPin, OUTPUT);       //| 
    pinMode(bluePin, OUTPUT);        //|
    setColor(0,0,0);                 // make sure RGB lights are off at startup
    digitalWrite(controlPin1,HIGH);   // make sure garden lights are off at startup. relay module swithces High to turn off
    digitalWrite(controlPin2,HIGH);   // make sure garden lights are off at startup. relay module swithces High to turn off
    }
    
    void presentation()  {
    // Present sketch (name, version)
    sendSketchInfo("RGB Node", "0.1");        
         
    // Register sensors (id, type, description, ack back) 
     present(RGB_CHILD_ID, S_RGB_LIGHT,"Firepit RGB Control");
     present(CHILD_ID_LIGHT_1, S_LIGHT," Garden Lights 1");
     present(CYCLE_SWITCH_ID, S_LIGHT,"RGB Cycle Switch");
     present(CHILD_ID_LIGHT_2, S_LIGHT," Garden Lights 2");
    }
    
    void loop()
    {
    if (onceOnly == 0){                     // this code only exectutes once at startup to make sure controller knows switch settings are off
     send(msg.set(false));                // send message to switch off colour cycling
     send(rgbmsgA.set(0));                // send message to switch off RGB lights
     send(gardenlightmsg1.set(false));    // send message to switch off garden lights relay 1
     send(gardenlightmsg2.set(false));    // send message to switch off garden lights relay 2
     onceOnly = 1; 
    }
    if (cycleState == 1){  // check to see is colour cycling is turned on
    cyclecolor();
    }
    }
    
    /*-----------------Start of functions---------------------*/
    
    
    /*----------- function to display LED colour as well as set brightness------------*/
    void setColor(int red, int green, int blue){  
    if (dimSet != 0){
    analogWrite(redPin, round(red*dimSet/100));          //|
    analogWrite(greenPin, round(green*dimSet/100));      //| change the three rgb colours and adjust brightness
    analogWrite(bluePin, round(blue*dimSet/100));        //|
    }
    else{                                                // if dimmer setting is 0 then set all colours to 0
    analogWrite(redPin, dimSet);
    analogWrite(greenPin, dimSet);
    analogWrite(bluePin, dimSet);
    }  
    #ifdef MY_DEBUG            //Print debug info if enabled
    Serial.print("RED = ");
    Serial.println(red);
    Serial.print("BLUE = ");
    Serial.println(blue);
    Serial.print("GREEN = ");
    Serial.println(green);
    #endif
    }
    
    
    /*------------------process incoming messages--------------------*/
    void receive(const MyMessage &message) {
    switch (message.type) {
    case V_LIGHT:                                                //message is for a light switch (2)
      #ifdef MY_DEBUG                                            //print some degug info if enabled
        Serial.print("Incoming change for sensor:");
        Serial.println(message.sensor);
        Serial.print("Light switch setting " );
        Serial.println(message.getBool());
      #endif
       switch (message.sensor) {
        case 1:                                                     //message is for sensor 1 (RGB switch)
          digitalWrite(controlPinA, message.getBool() ? 1 : 0);     // change state of RGB power switch
          break;
        case 2:                                                     //message is for sensor 2 (garden lights switch 1)
          digitalWrite(controlPin1, message.getBool() ? 0 : 1);     //change state of garden light switch 
          break;
        case 3:                                                     // message is for sensor 3 (colour cycle switch)
          cycleState = message.getBool() ? 1: 0;                    // change state of colour cycle 
          break;
        case 4:                                                     //message is for sensor 4 (garden lights switch 2)
          digitalWrite(controlPin2, message.getBool() ? 0 : 1);     //change state of garden light switch 
          break;
       }
       break;
    case V_PERCENTAGE:                                                  //check for dimmer message type (3)
       if(cycleState == 1){                                         // new incoming colour change, turn off cycling if it is on
       send(msg.set(false));
       cycleState = 0;
       }
      dimSet = message.getInt();                                        // Load the dimmer setting into dimSet
      setColor(RGB_values[0],RGB_values[1],RGB_values[2]);              // call the setColor function to update the LED's. new dimmer setting
      #ifdef MY_DEBUG                                                   //Print debug info if enabled
       Serial.print("dimmer setting " );
       Serial.println(dimSet);
      #endif
      break;
    case V_RGB:                                                       //check for RGB message type (40)
        /*   process the RGB hex code    */
      String rgbHexString = message.getString();                      //Load the hex color code into a string
      long number = (long) strtol( &rgbHexString[0], NULL, 16);
      RGB_values[0] = number >> 16;
      RGB_values[1] = number >> 8 & 0xFF;
      RGB_values[2] = number & 0xFF;
      setColor(RGB_values[0],RGB_values[1],RGB_values[2]);            // call the setColor function to update the LED's
    #ifdef MY_DEBUG                                                   //Print debug info if enabled
       Serial.print("HEX RGB " );
       Serial.println(rgbHexString);
       Serial.print("long number " );
       Serial.println(number);
    #endif
    }
    }
    
    /*---------------function to cycle colours-----------------------*/
    void cyclecolor(){
    
    /*Start off with red*/
    RGB_values[0] = 255;
    RGB_values[1] = 0;
    RGB_values[2] = 0; 
    /* Choose the colours to increment and decrement.*/
    for (int decColour = 0; decColour < 3; decColour += 1) {
      int incColour = decColour == 2 ? 0 : decColour + 1;
    
    /* cross-fade the two colours*/
    for(int i = 0; i < 255; i += 1) {
     RGB_values[decColour] -= 1;
     RGB_values[incColour] += 1;
     analogWrite(redPin, RGB_values[0]);
     analogWrite(greenPin, RGB_values[1]);
     analogWrite(bluePin, RGB_values[2]);
     if (cycleState == 0){                 // If colour cycling is turned off break out to main loop
       break;
     }
     wait(cycleSpeed);   // this controls the speed of the colour cycling
    }
    }
    }
    
    
    
    

    0_1480641324831_firepit controller with relays.jpg



  • Be careful powering the Nano from 12V - there are reports elsewhere on this forum of some versions getting fried at this voltage!


  • Hero Member

    Thanks @MikeF as you say they can get quite hot when run at the higher end of their voltage tolerance. .
    I have never had a nano fail on me at 12v though and as this is an outside node located where it can do no harm if it fails I am happy to avoid the extra voltage regulator.

    If it was a node to be situated inside the house then I always try and keep to 9v or less just to make sure it all runs cool.



  • @Boots33

    I've fried a couple pro mini's and a nano running 12v to the vin/raw... actually in one case it might have been up to 15v .... oops.

    But I've since learned my lesson.... I now use a Linear Voltage Regulator between the source and the arduino for all my builds that have a higher voltage power source (i.e.: builds that run lights). Typically a L7805CV or L7809CV or L7810CV (or other) depending on the voltage of my source and what I want to send to the arduino.

    Here is an example L7809CV from AliExpress


Log in to reply
 

Looks like your connection to MySensors Forum was lost, please wait while we try to reconnect.