Skip to content
  • MySensors
  • OpenHardware.io
  • Categories
  • Recent
  • Tags
  • Popular
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Brand Logo
  1. Home
  2. Announcements
  3. 💬 Dimmable LED Actuator

💬 Dimmable LED Actuator

Scheduled Pinned Locked Moved Announcements
59 Posts 27 Posters 13.7k Views 27 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • J joschre

    hi, i used the example sketch. i also changed from "delay" to "wait" in fade section. The problem: i can change the percentage for example 8 times and then the gateway crashes and reboots. In a other case it works 12 times and then the gateway crashes. All other nodes (Temp, Hum) works fine all the time.

    mfalkviddM Offline
    mfalkviddM Offline
    mfalkvidd
    Mod
    wrote on last edited by
    #33

    @joschre could you post the debug output from the node?

    1 Reply Last reply
    0
    • J Offline
      J Offline
      joschre
      wrote on last edited by
      #34

      Problem solved! The 3.3v Form arduino nano was too Bad for the nrf24l01j pa lna with PA_LEVEL MAX. NOW i usw an external regulator an everything is fine :-) sorry for this newbie fault :-D

      mfalkviddM 1 Reply Last reply
      1
      • J joschre

        Problem solved! The 3.3v Form arduino nano was too Bad for the nrf24l01j pa lna with PA_LEVEL MAX. NOW i usw an external regulator an everything is fine :-) sorry for this newbie fault :-D

        mfalkviddM Offline
        mfalkviddM Offline
        mfalkvidd
        Mod
        wrote on last edited by
        #35

        @joschre great that you found a solution. Thank for reporting back.

        1 Reply Last reply
        0
        • U Offline
          U Offline
          user2684
          Contest Winner
          wrote on last edited by
          #36

          Hi, I've noticed the V_DIMMER of the example is not (anymore?) available in https://www.mysensors.org/download/serial_api_20, am I wrong? Thanks

          mfalkviddM 1 Reply Last reply
          0
          • U user2684

            Hi, I've noticed the V_DIMMER of the example is not (anymore?) available in https://www.mysensors.org/download/serial_api_20, am I wrong? Thanks

            mfalkviddM Offline
            mfalkviddM Offline
            mfalkvidd
            Mod
            wrote on last edited by mfalkvidd
            #37

            @user2684 you're right. I think it is supposed to be S_DIMMER (S_ is used for presentation)

            1 Reply Last reply
            0
            • LacesL Offline
              LacesL Offline
              Laces
              wrote on last edited by
              #38

              Dear Guys,

              How can I control an RGB ledstrip with this config may I add more MOSFAT or how ?
              Thank you very much.

              L

              korttomaK 1 Reply Last reply
              0
              • LacesL Laces

                Dear Guys,

                How can I control an RGB ledstrip with this config may I add more MOSFAT or how ?
                Thank you very much.

                L

                korttomaK Offline
                korttomaK Offline
                korttoma
                Hero Member
                wrote on last edited by
                #39

                @Laces yes you can. The principal is the same, just one mosfet per channel.
                Search the forum for RGB or RGBW and you sould be able to find some examples.

                • Tomas
                1 Reply Last reply
                1
                • PlantexP Offline
                  PlantexP Offline
                  Plantex
                  wrote on last edited by
                  #40
                  This post is deleted!
                  1 Reply Last reply
                  0
                  • J jeti

                    so this works now like a charm:

                    // Enable debug prints to serial monitor
                    #define MY_DEBUG 
                    
                    // Enable and select radio type attached
                    #define MY_RADIO_NRF24
                    //#define MY_RADIO_RFM69
                    
                    #define MY_NODE_ID 153 
                    
                    #include <SPI.h>
                    #include <MySensors.h> 
                    
                    #define SN "MultiDimmableLED"
                    #define SV "1.1"
                    
                    #define noLEDs 3
                    const int LED_Pin[] = {3, 5, 6}; 
                    
                    #define FADE_DELAY 25  // Delay in ms for each percentage fade up/down (10ms = 1s full-range dim)
                    
                    static int currentLevel = 0;  // Current dim level...
                    MyMessage dimmerMsg(noLEDs, V_DIMMER);
                    MyMessage lightMsg(noLEDs, V_LIGHT);
                    
                    
                    
                    /***
                     * Dimmable LED initialization method
                     */
                    void setup()  
                    { 
                      // not sure this works
                      // Pull the gateway's current dim level - restore light level upon sendor node power-up
                    for (int sensor=1; sensor<=noLEDs; sensor++){
                      request( sensor, V_DIMMER );
                     }
                    }
                    
                    void presentation() {
                      // Register the LED Dimmable Light with the gateway
                     for (int sensor=1; sensor<=noLEDs; sensor++){
                     present(sensor, S_DIMMER);
                     wait(2);
                     }
                      sendSketchInfo(SN, SV);
                    }
                    
                    /***
                     *  Dimmable LED main processing loop 
                     */
                    void loop() 
                    {
                    }
                    
                    
                    
                    void receive(const MyMessage &message) {
                      if (message.type == V_LIGHT || message.type == V_DIMMER) {
                        
                        //  Retrieve the power or dim level from the incoming request message
                        int requestedLevel = atoi( message.data );
                        
                        // Adjust incoming level if this is a V_LIGHT variable update [0 == off, 1 == on]
                        requestedLevel *= ( message.type == V_LIGHT ? 100 : 1 );
                        
                        // Clip incoming level to valid range of 0 to 100
                        requestedLevel = requestedLevel > 100 ? 100 : requestedLevel;
                        requestedLevel = requestedLevel < 0   ? 0   : requestedLevel;
                        
                        Serial.print( "Changing LED " );
                        Serial.print(message.sensor);
                        Serial.print(", PIN " );
                        Serial.print( LED_Pin[message.sensor] );
                        Serial.print(" level to " );
                        Serial.print( requestedLevel );
                        Serial.print( ", from " ); 
                        Serial.println( currentLevel );
                    
                        
                        fadeToLevel( requestedLevel, message.sensor );
                        
                        // Inform the gateway of the current DimmableLED's SwitchPower1 and LoadLevelStatus value...
                        send(lightMsg.set(currentLevel > 0 ? 1 : 0));
                    
                        // hek comment: Is this really nessesary?
                        send( dimmerMsg.set(currentLevel) );
                    
                        
                        }
                    }
                    
                    /***
                     *  This method provides a graceful fade up/down effect
                     */
                    void fadeToLevel( int toLevel, int ledid ) {
                    
                      int delta = ( toLevel - currentLevel ) < 0 ? -1 : 1;
                      
                      while ( currentLevel != toLevel ) {
                        currentLevel += delta;
                        analogWrite(LED_Pin[ledid-1], (int)(currentLevel / 100. * 255) );
                        wait( FADE_DELAY );
                      }
                    }```
                    
                    thank you :thumbsup:
                    PlantexP Offline
                    PlantexP Offline
                    Plantex
                    wrote on last edited by Plantex
                    #41
                    This post is deleted!
                    1 Reply Last reply
                    0
                    • I Offline
                      I Offline
                      itbeyond
                      wrote on last edited by
                      #42

                      Ah I have just built a test bed with this setup however it appears the circuit diagram in the Fritizing is actually not 100% correct. The red wire from the protoboard is connected to the GND of the Pro Mini - this confused me as I was using the GND/RAW pins to identify the cable color. If you flip the red/blue connections on the Pro Mini it will be right. Small issue I know but I had to reference another image to get the circuit to work.

                      1 Reply Last reply
                      0
                      • K Offline
                        K Offline
                        KoenP
                        wrote on last edited by
                        #43

                        Hi Folks,

                        I have build this in combination with a ethernet gateway. Works perfect, however, when for whatever reason the network fails, I cannot control my lights anymore.

                        Is there a possibilty toi have it working also "stand alone" when the network fails?

                        Grtz.

                        KoenP

                        1 Reply Last reply
                        0
                        • vladimirV Offline
                          vladimirV Offline
                          vladimir
                          wrote on last edited by
                          #44

                          Hi all!

                          I'm using OpenHAB 2, and I have some problems with the sketch code "DimmableLightWithRotaryEncoderButton".

                          1. When the encoder button is pressed, the switch in OpenHAB does not respond.
                          2. When you turn the encoder knob one step, the value changes in two steps.

                          Maybe you have encountered such a problem? Or maybe you can share a more modern sketch?

                          mfalkviddM 1 Reply Last reply
                          0
                          • vladimirV vladimir

                            Hi all!

                            I'm using OpenHAB 2, and I have some problems with the sketch code "DimmableLightWithRotaryEncoderButton".

                            1. When the encoder button is pressed, the switch in OpenHAB does not respond.
                            2. When you turn the encoder knob one step, the value changes in two steps.

                            Maybe you have encountered such a problem? Or maybe you can share a more modern sketch?

                            mfalkviddM Offline
                            mfalkviddM Offline
                            mfalkvidd
                            Mod
                            wrote on last edited by
                            #45

                            In case anyone can help @vladimir, please post in https://forum.mysensors.org/post/93111 so we keep the discussion focused in one place.

                            1 Reply Last reply
                            1
                            • vladimirV Offline
                              vladimirV Offline
                              vladimir
                              wrote on last edited by
                              #46

                              Does anyone use this sketch "DimmableLightWithRotaryEncoderButton"? I take it from the site (https://www.mysensors.org/build/dimmer) and it does not work with OpenHAB 2.

                              1 Reply Last reply
                              0
                              • M Offline
                                M Offline
                                mateos78
                                wrote on last edited by
                                #47

                                does anyone have working sketch -> DimmableLightWithRotaryEncoderButton.ino with Mysensor USB under DOMOTICZ + Arduino ? unfortunatelly phisical button dosn't work (no switch on / off) and there is no feedbeck from domoticz to Arduino to set level of dim. I have been straggling with the sketch for weeks, but haven't figured out , how to fix it. Mybe something has changed since lat update od sketch... and sorry for my english I'm not a native speaker:)

                                H 1 Reply Last reply
                                0
                                • M mateos78

                                  does anyone have working sketch -> DimmableLightWithRotaryEncoderButton.ino with Mysensor USB under DOMOTICZ + Arduino ? unfortunatelly phisical button dosn't work (no switch on / off) and there is no feedbeck from domoticz to Arduino to set level of dim. I have been straggling with the sketch for weeks, but haven't figured out , how to fix it. Mybe something has changed since lat update od sketch... and sorry for my english I'm not a native speaker:)

                                  H Offline
                                  H Offline
                                  hard-shovel
                                  wrote on last edited by
                                  #48

                                  @mateos78 See https://forum.mysensors.org/topic/9670/problem-with-dimmable-led-actuator-with-encoder/11

                                  1 Reply Last reply
                                  0
                                  • M Offline
                                    M Offline
                                    mateos78
                                    wrote on last edited by
                                    #49

                                    @hard-shovel I've already used this sketch, but still no feedback from domoticz to arduino (it does not dim) and the physical button doesn't work :( ehh...

                                    1 Reply Last reply
                                    0
                                    • M Offline
                                      M Offline
                                      mateos78
                                      wrote on last edited by mateos78
                                      #50

                                      here is what I use now->
                                      As I can see When I change the dim level or click the switch in domoticz the yellow led on arduino blink but it changes nothing..

                                      
                                      /**
                                       * The MySensors Arduino library handles the wireless radio link and protocol
                                       * between your home built sensors/actuators and HA controller of choice.
                                       * The sensors forms a self healing radio network with optional repeaters. Each
                                       * repeater and gateway builds a routing tables in EEPROM which keeps track of the
                                       * network topology allowing messages to be routed to nodes.
                                       *
                                       * Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
                                       * Copyright (C) 2013-2015 Sensnology AB
                                       * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
                                       *
                                       * Documentation: http://www.mysensors.org
                                       * Support Forum: http://forum.mysensors.org
                                       *
                                       * 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.
                                       *
                                       *******************************
                                       *
                                       * REVISION HISTORY
                                       * Version 1.0 - Developed by Bruce Lacey and GizMoCuz (Domoticz)
                                       * Version 1.1 - Modified by hek to incorporate a rotary encode to adjust 
                                       *                                light level locally at node
                                       * 
                                       * DESCRIPTION
                                       * This sketch provides an example how to implement a dimmable led light node with a rotary 
                                       * encoder connected for adjusting light level. 
                                       * The encoder has a click button which turns on/off the light (and remembers last dim-level) 
                                       * The sketch fades the light (non-blocking) to the desired level. 
                                       *
                                       * Default MOSFET pin is 3
                                       * 
                                       *  Arduino      Encoder module
                                       *  ---------------------------
                                       *  5V           5V (+)  
                                       *  GND          GND (-)
                                       *  4            CLK (or putput 1) 
                                       *  5            DT  (or output 1) 
                                       *  6            SW (Switch/Click) 
                                       */
                                      // Enable and select radio type attached
                                      //#define MY_RADIO_NRF24
                                      //#define MY_RADIO_RFM69
                                      
                                      // Enable debug prints
                                      #define MY_DEBUG
                                      #define MY_GATEWAY_SERIAL
                                      #define MY_INCLUSION_MODE_FEATURE
                                      #define MY_INCLUSION_BUTTON_FEATURE
                                      #define MY_INCLUSION_MODE_DURATION 60
                                      #define MY_INCLUSION_MODE_BUTTON_PIN 8
                                      
                                      #include <SPI.h>
                                      #include <MySensors.h>  
                                      #include <Bounce2.h>
                                      #include <Encoder.h>
                                      
                                      #define LED_PIN 3           // Arduino pin attached to MOSFET Gate pin
                                      #define KNOB_ENC_PIN_1 4    // Rotary encoder input pin 1
                                      #define KNOB_ENC_PIN_2 5    // Rotary encoder input pin 2
                                      #define KNOB_BUTTON_PIN 6   // Rotary encoder button pin 
                                      #define FADE_DELAY 10       // Delay in ms for each percentage fade up/down (10ms = 1s full-range dim)
                                      #define SEND_THROTTLE_DELAY 400 // Number of milliseconds before sending after user stops turning knob
                                      #define SN "DimmableLED /w button"
                                      #define SV "1.3"
                                      
                                      #define CHILD_ID_LIGHT 1
                                      
                                      #define EEPROM_DIM_LEVEL_LAST 1
                                      #define EEPROM_DIM_LEVEL_SAVE 2
                                      
                                      #define LIGHT_OFF 0
                                      #define LIGHT_ON 1
                                      
                                      int dimValue;
                                      int fadeTo;
                                      int fadeDelta;
                                      byte oldButtonVal;
                                      bool changedByKnob=false;
                                      bool sendDimValue=false;
                                      unsigned long lastFadeStep;
                                      unsigned long sendDimTimeout;
                                      char convBuffer[10];
                                      
                                      MyMessage dimmerMsg(CHILD_ID_LIGHT, V_DIMMER);
                                      MyMessage statusMsg(CHILD_ID_LIGHT, V_STATUS);    // Addition for Status update to OpenHAB Controller
                                      Encoder knob(KNOB_ENC_PIN_1, KNOB_ENC_PIN_2);  
                                      Bounce debouncer = Bounce(); 
                                      
                                      void setup()  
                                      { 
                                        // Set knob button pin as input (with debounce)
                                        pinMode(KNOB_BUTTON_PIN, INPUT);
                                        digitalWrite(KNOB_BUTTON_PIN, HIGH);
                                        debouncer.attach(KNOB_BUTTON_PIN);
                                        debouncer.interval(5);
                                        oldButtonVal = debouncer.read();
                                      
                                        // Set analog led pin to off
                                        analogWrite( LED_PIN, 0);
                                      
                                        // Retreive our last dim levels from the eprom
                                        fadeTo = dimValue = 0;
                                        byte oldLevel = loadLevelState(EEPROM_DIM_LEVEL_LAST);
                                        Serial.print("Sending in last known light level to controller: ");
                                        Serial.println(oldLevel);  
                                        send(dimmerMsg.set(oldLevel), true);
                                        Serial.println("Ready to receive messages...");  
                                      }
                                      
                                      void presentation() {
                                        // Send the Sketch Version Information to the Gateway
                                        present(CHILD_ID_LIGHT, S_DIMMER);
                                        sendSketchInfo(SN, SV);
                                      }
                                      
                                      void loop()      
                                      {
                                        // Check if someone turned the rotary encode
                                        checkRotaryEncoder();
                                        
                                        // Check if someone has pressed the knob button
                                        checkButtonClick();
                                        
                                        // Fade light to new dim value
                                        fadeStep();
                                      }
                                      
                                      void receive(const MyMessage &message)
                                      {
                                        if (message.type == V_STATUS) {
                                          // Incoming on/off command sent from controller ("1" or "0")
                                          int lightState = message.getString()[0] == '1';
                                          int newLevel = 0;
                                          if (lightState==LIGHT_ON) {
                                            // Pick up last saved dimmer level from the eeprom
                                            newLevel = loadLevelState(EEPROM_DIM_LEVEL_SAVE);
                                          } 
                                          // Send dimmer level back to controller with ack enabled
                                          send(dimmerMsg.set(newLevel), true);
                                          // We do not change any levels here until ack comes back from gateway 
                                          return;
                                        } else if (message.type == V_PERCENTAGE) {
                                          // Incoming dim-level command sent from controller (or ack message)
                                          fadeTo = atoi(message.getString(convBuffer));
                                          // Save received dim value to eeprom (unless turned off). Will be
                                          // retreived when a on command comes in
                                          if (fadeTo != 0)
                                            saveLevelState(EEPROM_DIM_LEVEL_SAVE, fadeTo);
                                        }
                                        saveLevelState(EEPROM_DIM_LEVEL_LAST, fadeTo);
                                        
                                        Serial.print("New light level received: ");
                                        Serial.println(fadeTo);
                                      
                                        if (!changedByKnob) 
                                          knob.write(fadeTo<<1);             //### need to multiply by two (using Shift left)
                                          
                                        // Cancel send if user turns knob while message comes in
                                        changedByKnob = false;
                                        sendDimValue = false;
                                      
                                        // Stard fading to new light level
                                        startFade();
                                      }
                                      
                                      
                                      
                                      void checkRotaryEncoder() {
                                        long encoderValue = knob.read()>>1 ;      //### Divide by 2 (using shift right) 
                                      
                                        if (encoderValue > 100) {   
                                          encoderValue = 100;       
                                          knob.write(200);                        //### max value now 200 due to divide by 2
                                        } else if (encoderValue < 0) {
                                          encoderValue = 0;
                                          knob.write(0);
                                        }
                                      
                                        if (encoderValue != fadeTo) {    
                                          fadeTo = encoderValue;                   
                                          changedByKnob = true;
                                          startFade();
                                        }
                                      }
                                      
                                      void checkButtonClick() {
                                        debouncer.update();
                                        byte buttonVal = debouncer.read();
                                        byte newLevel = 0;
                                        if (buttonVal != oldButtonVal && buttonVal == LOW) {
                                          if (dimValue==0) {
                                            // Turn on light. Set the level to last saved dim value
                                            int saved = loadLevelState(EEPROM_DIM_LEVEL_SAVE);
                                            newLevel = saved > 1 ? saved : 100;           // newLevel = saved > 0 ? saved : 100;     
                                          } 
                                          send(dimmerMsg.set(newLevel),true);
                                          send(statusMsg.set(newLevel>0 ? "1" : "0")); // Addition for Status update to OpenHAB Controller,   No Echo
                                        }
                                        oldButtonVal = buttonVal;
                                      }
                                      
                                      void startFade() {
                                        fadeDelta = ( fadeTo - dimValue ) < 0 ? -1 : 1;
                                        lastFadeStep = millis();
                                      }
                                      
                                      // This method provides a graceful none-blocking fade up/down effect
                                      void fadeStep() {
                                        unsigned long currentTime  = millis();
                                        if ( dimValue != fadeTo && currentTime > lastFadeStep + FADE_DELAY) {
                                          dimValue += fadeDelta;
                                          analogWrite( LED_PIN, (int)(dimValue / 100. * 255) );
                                          lastFadeStep = currentTime;
                                          
                                          Serial.print("Fading level: ");
                                          Serial.println(dimValue);
                                      
                                          if (fadeTo == dimValue && changedByKnob) {
                                            sendDimValue = true;
                                            sendDimTimeout = currentTime;
                                          }
                                        } 
                                        // Wait a few millisecs before sending in new value (if user still turns the knob)
                                        if (sendDimValue && currentTime > sendDimTimeout + SEND_THROTTLE_DELAY)  {
                                           // We're done fading.. send in new dim-value to controller.
                                           // Send in new dim value with ack (will be picked up in incomingMessage) 
                                          send(dimmerMsg.set(dimValue), true); // Send new dimmer value and request ack back
                                          sendDimValue = false;
                                        }
                                      }
                                      
                                      // Make sure only to store/fetch values in the range 0-100 from eeprom
                                      int loadLevelState(byte pos) {
                                        return min(max(loadState(pos),0),100);
                                      }
                                      void saveLevelState(byte pos, byte data) {
                                        saveState(pos,min(max(data,0),100));
                                      }
                                      H 1 Reply Last reply
                                      0
                                      • M mateos78

                                        here is what I use now->
                                        As I can see When I change the dim level or click the switch in domoticz the yellow led on arduino blink but it changes nothing..

                                        
                                        /**
                                         * The MySensors Arduino library handles the wireless radio link and protocol
                                         * between your home built sensors/actuators and HA controller of choice.
                                         * The sensors forms a self healing radio network with optional repeaters. Each
                                         * repeater and gateway builds a routing tables in EEPROM which keeps track of the
                                         * network topology allowing messages to be routed to nodes.
                                         *
                                         * Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
                                         * Copyright (C) 2013-2015 Sensnology AB
                                         * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
                                         *
                                         * Documentation: http://www.mysensors.org
                                         * Support Forum: http://forum.mysensors.org
                                         *
                                         * 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.
                                         *
                                         *******************************
                                         *
                                         * REVISION HISTORY
                                         * Version 1.0 - Developed by Bruce Lacey and GizMoCuz (Domoticz)
                                         * Version 1.1 - Modified by hek to incorporate a rotary encode to adjust 
                                         *                                light level locally at node
                                         * 
                                         * DESCRIPTION
                                         * This sketch provides an example how to implement a dimmable led light node with a rotary 
                                         * encoder connected for adjusting light level. 
                                         * The encoder has a click button which turns on/off the light (and remembers last dim-level) 
                                         * The sketch fades the light (non-blocking) to the desired level. 
                                         *
                                         * Default MOSFET pin is 3
                                         * 
                                         *  Arduino      Encoder module
                                         *  ---------------------------
                                         *  5V           5V (+)  
                                         *  GND          GND (-)
                                         *  4            CLK (or putput 1) 
                                         *  5            DT  (or output 1) 
                                         *  6            SW (Switch/Click) 
                                         */
                                        // Enable and select radio type attached
                                        //#define MY_RADIO_NRF24
                                        //#define MY_RADIO_RFM69
                                        
                                        // Enable debug prints
                                        #define MY_DEBUG
                                        #define MY_GATEWAY_SERIAL
                                        #define MY_INCLUSION_MODE_FEATURE
                                        #define MY_INCLUSION_BUTTON_FEATURE
                                        #define MY_INCLUSION_MODE_DURATION 60
                                        #define MY_INCLUSION_MODE_BUTTON_PIN 8
                                        
                                        #include <SPI.h>
                                        #include <MySensors.h>  
                                        #include <Bounce2.h>
                                        #include <Encoder.h>
                                        
                                        #define LED_PIN 3           // Arduino pin attached to MOSFET Gate pin
                                        #define KNOB_ENC_PIN_1 4    // Rotary encoder input pin 1
                                        #define KNOB_ENC_PIN_2 5    // Rotary encoder input pin 2
                                        #define KNOB_BUTTON_PIN 6   // Rotary encoder button pin 
                                        #define FADE_DELAY 10       // Delay in ms for each percentage fade up/down (10ms = 1s full-range dim)
                                        #define SEND_THROTTLE_DELAY 400 // Number of milliseconds before sending after user stops turning knob
                                        #define SN "DimmableLED /w button"
                                        #define SV "1.3"
                                        
                                        #define CHILD_ID_LIGHT 1
                                        
                                        #define EEPROM_DIM_LEVEL_LAST 1
                                        #define EEPROM_DIM_LEVEL_SAVE 2
                                        
                                        #define LIGHT_OFF 0
                                        #define LIGHT_ON 1
                                        
                                        int dimValue;
                                        int fadeTo;
                                        int fadeDelta;
                                        byte oldButtonVal;
                                        bool changedByKnob=false;
                                        bool sendDimValue=false;
                                        unsigned long lastFadeStep;
                                        unsigned long sendDimTimeout;
                                        char convBuffer[10];
                                        
                                        MyMessage dimmerMsg(CHILD_ID_LIGHT, V_DIMMER);
                                        MyMessage statusMsg(CHILD_ID_LIGHT, V_STATUS);    // Addition for Status update to OpenHAB Controller
                                        Encoder knob(KNOB_ENC_PIN_1, KNOB_ENC_PIN_2);  
                                        Bounce debouncer = Bounce(); 
                                        
                                        void setup()  
                                        { 
                                          // Set knob button pin as input (with debounce)
                                          pinMode(KNOB_BUTTON_PIN, INPUT);
                                          digitalWrite(KNOB_BUTTON_PIN, HIGH);
                                          debouncer.attach(KNOB_BUTTON_PIN);
                                          debouncer.interval(5);
                                          oldButtonVal = debouncer.read();
                                        
                                          // Set analog led pin to off
                                          analogWrite( LED_PIN, 0);
                                        
                                          // Retreive our last dim levels from the eprom
                                          fadeTo = dimValue = 0;
                                          byte oldLevel = loadLevelState(EEPROM_DIM_LEVEL_LAST);
                                          Serial.print("Sending in last known light level to controller: ");
                                          Serial.println(oldLevel);  
                                          send(dimmerMsg.set(oldLevel), true);
                                          Serial.println("Ready to receive messages...");  
                                        }
                                        
                                        void presentation() {
                                          // Send the Sketch Version Information to the Gateway
                                          present(CHILD_ID_LIGHT, S_DIMMER);
                                          sendSketchInfo(SN, SV);
                                        }
                                        
                                        void loop()      
                                        {
                                          // Check if someone turned the rotary encode
                                          checkRotaryEncoder();
                                          
                                          // Check if someone has pressed the knob button
                                          checkButtonClick();
                                          
                                          // Fade light to new dim value
                                          fadeStep();
                                        }
                                        
                                        void receive(const MyMessage &message)
                                        {
                                          if (message.type == V_STATUS) {
                                            // Incoming on/off command sent from controller ("1" or "0")
                                            int lightState = message.getString()[0] == '1';
                                            int newLevel = 0;
                                            if (lightState==LIGHT_ON) {
                                              // Pick up last saved dimmer level from the eeprom
                                              newLevel = loadLevelState(EEPROM_DIM_LEVEL_SAVE);
                                            } 
                                            // Send dimmer level back to controller with ack enabled
                                            send(dimmerMsg.set(newLevel), true);
                                            // We do not change any levels here until ack comes back from gateway 
                                            return;
                                          } else if (message.type == V_PERCENTAGE) {
                                            // Incoming dim-level command sent from controller (or ack message)
                                            fadeTo = atoi(message.getString(convBuffer));
                                            // Save received dim value to eeprom (unless turned off). Will be
                                            // retreived when a on command comes in
                                            if (fadeTo != 0)
                                              saveLevelState(EEPROM_DIM_LEVEL_SAVE, fadeTo);
                                          }
                                          saveLevelState(EEPROM_DIM_LEVEL_LAST, fadeTo);
                                          
                                          Serial.print("New light level received: ");
                                          Serial.println(fadeTo);
                                        
                                          if (!changedByKnob) 
                                            knob.write(fadeTo<<1);             //### need to multiply by two (using Shift left)
                                            
                                          // Cancel send if user turns knob while message comes in
                                          changedByKnob = false;
                                          sendDimValue = false;
                                        
                                          // Stard fading to new light level
                                          startFade();
                                        }
                                        
                                        
                                        
                                        void checkRotaryEncoder() {
                                          long encoderValue = knob.read()>>1 ;      //### Divide by 2 (using shift right) 
                                        
                                          if (encoderValue > 100) {   
                                            encoderValue = 100;       
                                            knob.write(200);                        //### max value now 200 due to divide by 2
                                          } else if (encoderValue < 0) {
                                            encoderValue = 0;
                                            knob.write(0);
                                          }
                                        
                                          if (encoderValue != fadeTo) {    
                                            fadeTo = encoderValue;                   
                                            changedByKnob = true;
                                            startFade();
                                          }
                                        }
                                        
                                        void checkButtonClick() {
                                          debouncer.update();
                                          byte buttonVal = debouncer.read();
                                          byte newLevel = 0;
                                          if (buttonVal != oldButtonVal && buttonVal == LOW) {
                                            if (dimValue==0) {
                                              // Turn on light. Set the level to last saved dim value
                                              int saved = loadLevelState(EEPROM_DIM_LEVEL_SAVE);
                                              newLevel = saved > 1 ? saved : 100;           // newLevel = saved > 0 ? saved : 100;     
                                            } 
                                            send(dimmerMsg.set(newLevel),true);
                                            send(statusMsg.set(newLevel>0 ? "1" : "0")); // Addition for Status update to OpenHAB Controller,   No Echo
                                          }
                                          oldButtonVal = buttonVal;
                                        }
                                        
                                        void startFade() {
                                          fadeDelta = ( fadeTo - dimValue ) < 0 ? -1 : 1;
                                          lastFadeStep = millis();
                                        }
                                        
                                        // This method provides a graceful none-blocking fade up/down effect
                                        void fadeStep() {
                                          unsigned long currentTime  = millis();
                                          if ( dimValue != fadeTo && currentTime > lastFadeStep + FADE_DELAY) {
                                            dimValue += fadeDelta;
                                            analogWrite( LED_PIN, (int)(dimValue / 100. * 255) );
                                            lastFadeStep = currentTime;
                                            
                                            Serial.print("Fading level: ");
                                            Serial.println(dimValue);
                                        
                                            if (fadeTo == dimValue && changedByKnob) {
                                              sendDimValue = true;
                                              sendDimTimeout = currentTime;
                                            }
                                          } 
                                          // Wait a few millisecs before sending in new value (if user still turns the knob)
                                          if (sendDimValue && currentTime > sendDimTimeout + SEND_THROTTLE_DELAY)  {
                                             // We're done fading.. send in new dim-value to controller.
                                             // Send in new dim value with ack (will be picked up in incomingMessage) 
                                            send(dimmerMsg.set(dimValue), true); // Send new dimmer value and request ack back
                                            sendDimValue = false;
                                          }
                                        }
                                        
                                        // Make sure only to store/fetch values in the range 0-100 from eeprom
                                        int loadLevelState(byte pos) {
                                          return min(max(loadState(pos),0),100);
                                        }
                                        void saveLevelState(byte pos, byte data) {
                                          saveState(pos,min(max(data,0),100));
                                        }
                                        H Offline
                                        H Offline
                                        hard-shovel
                                        wrote on last edited by hard-shovel
                                        #51

                                        @mateos78
                                        Attached is a sketch that i have just tried with domoticz (running on a windows test machine) It works fine when used as a node with a gateway. Encoder/ Switch and webpage slider/switch operating.

                                        However when set up as a single gateway node as your sketch, only the encoder function works, you can vary the lamp level from the slider or the encoder, but the domaticz on/off or the button does not operate correctly. it seems to be the way the messages are acknowledged

                                        I also find that when i change the led dimmer from the encoder the led changes quickly, but it take about ten seconds before the dormoticz web page updates to show each new slider position.

                                        The following Sketch needs the #define OPENHAB2 defined for use with openhab and undefined for Dormoticz

                                        /**
                                         * The MySensors Arduino library handles the wireless radio link and protocol
                                         * between your home built sensors/actuators and HA controller of choice.
                                         * The sensors forms a self healing radio network with optional repeaters. Each
                                         * repeater and gateway builds a routing tables in EEPROM which keeps track of the
                                         * network topology allowing messages to be routed to nodes.
                                         *
                                         * Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
                                         * Copyright (C) 2013-2015 Sensnology AB
                                         * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
                                         *
                                         * Documentation: http://www.mysensors.org
                                         * Support Forum: http://forum.mysensors.org
                                         *
                                         * 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.
                                         *
                                         *******************************
                                         * DESCRIPTION
                                         * This sketch provides an example how to implement a dimmable led light node with a rotary 
                                         * encoder connected for adjusting light level. 
                                         * The encoder has a click button which turns on/off the light (and remembers last dim-level) 
                                         * The sketch fades the light (non-blocking) to the desired level. 
                                         *
                                         * Default MOSFET pin is 3
                                         * 
                                         *  Arduino      Encoder module
                                         *  ---------------------------
                                         *  5V           5V (+)  
                                         *  GND          GND (-)
                                         *  4            CLK (or putput 1)
                                         *  5            DT  (or output 1) 
                                         *  6            SW (Switch/Click)  
                                         *
                                         *  For OpenHAB2  enable @define OPENHAB2
                                         *  
                                         *  NOTE
                                         *  PROBLEM: 
                                         *  Using as a Gateway Node With Dormoticz the SWITCH ON/OFF DOES not work correcly either from the controller or by the Encoder 
                                         *  Using as a normal node all functions operate correctly.
                                         *  
                                          */
                                         /
                                        
                                         
                                        // Enable debug prints
                                        //#define MY_DEBUG
                                        
                                        
                                        
                                        // --- Enable Serial Gateway Transport
                                        #define MY_GATEWAY_SERIAL
                                        //#define MY_INCLUSION_MODE_FEATURE
                                        //#define MY_INCLUSION_BUTTON_FEATURE
                                        //#define MY_INCLUSION_MODE_DURATION 60
                                        //#define MY_INCLUSION_MODE_BUTTON_PIN 8
                                        
                                        
                                        // --- Enable RS485 transport layer
                                        //#define MY_RS485
                                        // Define this to enables DE-pin management on defined pin
                                        //#define MY_RS485_DE_PIN 12
                                        // Set RS485 baud rate to use
                                        //#define MY_RS485_BAUD_RATE 9600
                                        
                                        
                                        
                                        // Enable and select radio type attached
                                        //#define MY_RADIO_NRF24
                                        //#define MY_RADIO_RFM69
                                        
                                        #include <SPI.h>
                                        #include <MySensors.h>  
                                        #include <Bounce2.h>
                                        #include <Encoder.h>
                                        
                                        #define LED_PIN 3           // Arduino pin attached to MOSFET Gate pin
                                        #define KNOB_ENC_PIN_1 4    // Rotary encoder input pin 1
                                        #define KNOB_ENC_PIN_2 5    // Rotary encoder input pin 2
                                        #define KNOB_BUTTON_PIN 6   // Rotary encoder button pin 
                                        #define FADE_DELAY 10       // Delay in ms for each percentage fade up/down (10ms = 1s full-range dim)
                                        #define SEND_THROTTLE_DELAY 400 // Number of milliseconds before sending after user stops turning knob
                                        #define SN "DimmableLED /w button"
                                        #define SV "1.3a"
                                        
                                        #define CHILD_ID_LIGHT 1
                                        
                                        #define EEPROM_DIM_LEVEL_LAST 1
                                        #define EEPROM_DIM_LEVEL_SAVE 2
                                        // #define OPENHAB2                      // Use Define if using OPENHAB2 
                                        
                                        #define LIGHT_OFF 0
                                        #define LIGHT_ON 1
                                        
                                        int dimValue;
                                        int fadeTo;
                                        int fadeDelta;
                                        byte oldButtonVal;
                                        bool changedByKnob=false;
                                        bool sendDimValue=false;
                                        unsigned long lastFadeStep;
                                        unsigned long sendDimTimeout;
                                        char convBuffer[10];
                                        
                                        MyMessage dimmerMsg(CHILD_ID_LIGHT, V_DIMMER);
                                        MyMessage statusMsg(CHILD_ID_LIGHT, V_STATUS);    // Addition for Status update to OpenHAB Controller
                                        Encoder knob(KNOB_ENC_PIN_1, KNOB_ENC_PIN_2);  
                                        Bounce debouncer = Bounce(); 
                                        
                                        void setup()  
                                        { 
                                          // Set knob button pin as input (with debounce)
                                          pinMode(KNOB_BUTTON_PIN, INPUT);
                                          digitalWrite(KNOB_BUTTON_PIN, HIGH);
                                          debouncer.attach(KNOB_BUTTON_PIN);
                                          debouncer.interval(5);
                                          oldButtonVal = debouncer.read();
                                        
                                          // Set analog led pin to off
                                          analogWrite( LED_PIN, 0);
                                        
                                          // Retreive our last dim levels from the eprom
                                          fadeTo = dimValue = 0;
                                          byte oldLevel = loadLevelState(EEPROM_DIM_LEVEL_LAST);
                                          Serial.print("Sending in last known light level to controller: ");
                                          Serial.println(oldLevel);  
                                          send(dimmerMsg.set(oldLevel), true);
                                          Serial.println("Ready to receive messages...");  
                                        }
                                        
                                        void presentation() {
                                          // Send the Sketch Version Information to the Gateway
                                          present(CHILD_ID_LIGHT, S_DIMMER);
                                          sendSketchInfo(SN, SV);
                                        }
                                        
                                        void loop()      
                                        {
                                          // Check if someone turned the rotary encode
                                          checkRotaryEncoder();
                                          
                                          // Check if someone has pressed the knob button
                                          checkButtonClick();
                                          
                                          // Fade light to new dim value
                                          fadeStep();
                                        }
                                        
                                        void receive(const MyMessage &message)
                                        {
                                            #ifdef MY_DEBUG
                                            // This is called when a message is received 
                                            Serial.print("Message: "); Serial.print(message.sensor); Serial.print(", type: "); Serial.print(message.type); Serial.print(", Message: ");
                                            #endif
                                            
                                          if (message.type == V_STATUS) {
                                            // Incoming on/off command sent from controller ("1" or "0")
                                            int lightState = message.getString()[0] == '1';
                                            int newLevel = 0;
                                            if (lightState==LIGHT_ON) {
                                              // Pick up last saved dimmer level from the eeprom
                                              newLevel = loadLevelState(EEPROM_DIM_LEVEL_SAVE);
                                            } else {
                                              
                                            }
                                            // Send dimmer level back to controller with ack enabled
                                            send(dimmerMsg.set(newLevel), true);
                                            // We do not change any levels here until ack comes back from gateway 
                                            return;
                                          } else if (message.type == V_PERCENTAGE) {
                                            // Incoming dim-level command sent from controller (or ack message)
                                            fadeTo = atoi(message.getString(convBuffer));
                                            // Save received dim value to eeprom (unless turned off). Will be
                                            // retreived when a on command comes in
                                            if (fadeTo != 0)
                                              saveLevelState(EEPROM_DIM_LEVEL_SAVE, fadeTo);
                                          }
                                          saveLevelState(EEPROM_DIM_LEVEL_LAST, fadeTo);
                                          #ifdef MY_DEBUG
                                          Serial.print("New light level received: ");
                                          Serial.println(fadeTo);
                                          #endif
                                          
                                          if (!changedByKnob) 
                                            knob.write(fadeTo<<1);             //### need to multiply by two (using Shift left)
                                            
                                          // Cancel send if user turns knob while message comes in
                                          changedByKnob = false;
                                          sendDimValue = false;
                                        
                                          // Stard fading to new light level
                                          startFade();
                                        }
                                        
                                        
                                        
                                        void checkRotaryEncoder() {
                                          long encoderValue = knob.read()>>1 ;      //### Divide by 2 (using shift right) 
                                        
                                          if (encoderValue > 100) {   
                                            encoderValue = 100;       
                                            knob.write(200);                        //### max value now 200 due to divide by 2
                                          } else if (encoderValue < 0) {
                                            encoderValue = 0;
                                            knob.write(0);
                                          }
                                        
                                          if (encoderValue != fadeTo) {    
                                            fadeTo = encoderValue;                   
                                            changedByKnob = true;
                                            startFade();
                                          }
                                        }
                                        
                                        void checkButtonClick() {
                                          debouncer.update();
                                          byte buttonVal = debouncer.read();
                                          byte newLevel = 0;
                                          if (buttonVal != oldButtonVal && buttonVal == LOW) {
                                            if (dimValue==0) {
                                              // Turn on light. Set the level to last saved dim value
                                              int saved = loadLevelState(EEPROM_DIM_LEVEL_SAVE);
                                              newLevel = saved > 1 ? saved : 100;           // newLevel = saved > 0 ? saved : 100;     
                                            } 
                                            send(dimmerMsg.set(newLevel),true);
                                            #ifdef OPENHAB2
                                            send(statusMsg.set(newLevel>0 ? "1" : "0")); // Addition for Status update to OpenHAB Controller,   No Echo
                                            #endif
                                          }
                                          oldButtonVal = buttonVal;
                                        }
                                        
                                        void startFade() {
                                          fadeDelta = ( fadeTo - dimValue ) < 0 ? -1 : 1;
                                          lastFadeStep = millis();
                                        }
                                        
                                        // This method provides a graceful none-blocking fade up/down effect
                                        void fadeStep() {
                                          unsigned long currentTime  = millis();
                                        
                                          if ( dimValue != fadeTo && currentTime > lastFadeStep + FADE_DELAY) {
                                            dimValue += fadeDelta;
                                            analogWrite( LED_PIN, (int)(dimValue / 100. * 255) );
                                            lastFadeStep = currentTime;
                                            #ifdef MY_DEBUG
                                            Serial.print("Fading level: ");
                                            Serial.println(dimValue);
                                            #endif
                                            
                                            if (fadeTo == dimValue && changedByKnob) {
                                              sendDimValue = true;
                                              sendDimTimeout = currentTime;
                                            }
                                          } 
                                          // Wait a few millisecs before sending in new value (if user still turns the knob)
                                          if (sendDimValue && currentTime > sendDimTimeout + SEND_THROTTLE_DELAY)  {
                                             // We're done fading.. send in new dim-value to controller.
                                             // Send in new dim value with ack (will be picked up in incomingMessage) 
                                            send(dimmerMsg.set(dimValue), true); // Send new dimmer value and request ack back
                                            sendDimValue = false;
                                          }
                                        }
                                        
                                        // Make sure only to store/fetch values in the range 0-100 from eeprom
                                        int loadLevelState(byte pos) {
                                          return min(max(loadState(pos),0),100);
                                        }
                                        void saveLevelState(byte pos, byte data) {
                                          saveState(pos,min(max(data,0),100));
                                        }
                                        

                                        I maybe overlooking something obvious as i only have a couple of hours experience with domoticz.

                                        1 Reply Last reply
                                        1
                                        • M Offline
                                          M Offline
                                          mateos78
                                          wrote on last edited by mateos78
                                          #52

                                          @hard-shovel thanks a lot for you post and effort to test it!, I've tested also the version of sketch without rotary encoder and this one works fine.

                                          1 Reply Last reply
                                          1
                                          Reply
                                          • Reply as topic
                                          Log in to reply
                                          • Oldest to Newest
                                          • Newest to Oldest
                                          • Most Votes


                                          11

                                          Online

                                          11.7k

                                          Users

                                          11.2k

                                          Topics

                                          113.1k

                                          Posts


                                          Copyright 2025 TBD   |   Forum Guidelines   |   Privacy Policy   |   Terms of Service
                                          • Login

                                          • Don't have an account? Register

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • MySensors
                                          • OpenHardware.io
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular