Skip to content
  • 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. Development
  3. Dimmable LED With Rotary Encoder example for RGB?
  • Getting Started
  • Controller
  • Build
  • Hardware
  • Download/API
  • Forum
  • Store

Dimmable LED With Rotary Encoder example for RGB?

Scheduled Pinned Locked Moved Development
rotaryencoderrgbactuator
8 Posts 4 Posters 10.1k Views 4 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.
  • H Offline
    H Offline
    humblehacker
    wrote on last edited by humblehacker
    #1

    Hello,
    I'm trying to modify the "Dimmable LED With Rotary Encoder" example to use as an RGB LED actuator rather than a dimmer. The key for making this work however is the Illuminated RGB Rotary Encoder from Sparkfun which conveniently includes an RGB LED inside the knob itself.
    The goal is to be able to find a desired color by twisting the knob and to select it with the pushbutton. The color values will then be transmitted to a controller which in turn signals the RGB Light Bulbs (e.g HUE,LIFX, LimitlessLED) to reflect the chosen color.
    I had originally planned to use a simple trim pot with a Neopixel Ring and an ESP8266 transmitting via MQTT, but the RGB Rotary Encoder seemed to simplify matters considerably. I should've guessed that nothing ever ends up being that easy as it turns out no two people seem to agree on a standard approach to programming rotary encoders with Arduino... Some say you need to use interrupts, others insist on adding resistors or capacitors... Luckily my research led me full circle back to MySensors where the DimmableLED sketch ALMOST accomplishes my goal... But not quite...
    If others have had experience with either the DimmableLEDRotaryEncoder example and/or the RGB Encoder from Sparkfun, I would greatly appreciate suggestions.
    When I'm able to complete a proof of concept I'm planning to author a detailed tutorial on hackster.io, and I'll be sure to credit anyone who helps!MYSRGBEncoder_bb.png

    DwaltD 1 Reply Last reply
    1
    • H humblehacker

      Hello,
      I'm trying to modify the "Dimmable LED With Rotary Encoder" example to use as an RGB LED actuator rather than a dimmer. The key for making this work however is the Illuminated RGB Rotary Encoder from Sparkfun which conveniently includes an RGB LED inside the knob itself.
      The goal is to be able to find a desired color by twisting the knob and to select it with the pushbutton. The color values will then be transmitted to a controller which in turn signals the RGB Light Bulbs (e.g HUE,LIFX, LimitlessLED) to reflect the chosen color.
      I had originally planned to use a simple trim pot with a Neopixel Ring and an ESP8266 transmitting via MQTT, but the RGB Rotary Encoder seemed to simplify matters considerably. I should've guessed that nothing ever ends up being that easy as it turns out no two people seem to agree on a standard approach to programming rotary encoders with Arduino... Some say you need to use interrupts, others insist on adding resistors or capacitors... Luckily my research led me full circle back to MySensors where the DimmableLED sketch ALMOST accomplishes my goal... But not quite...
      If others have had experience with either the DimmableLEDRotaryEncoder example and/or the RGB Encoder from Sparkfun, I would greatly appreciate suggestions.
      When I'm able to complete a proof of concept I'm planning to author a detailed tutorial on hackster.io, and I'll be sure to credit anyone who helps!MYSRGBEncoder_bb.png

      DwaltD Offline
      DwaltD Offline
      Dwalt
      wrote on last edited by
      #2

      @humblehacker

      Does the rgb LED in the rotary knob react automatically to the knob turning or does it respond to software direction for color change? If the latter, could the knob be used for dimming as well as color setting? I could envision turning the knob to desired color per the rgb LED, push to set color (send to controller) which would also toggle the knob function to a dimmer control, possibly by using the LED brightness (without color change) as feedback and pushing the knob to set dim state and toggle back knob function to color control. Just thinking aloud...

      Veralite UI5 :: IBoard Ethernet GW :: MyS 1.5

      1 Reply Last reply
      0
      • H Offline
        H Offline
        humblehacker
        wrote on last edited by
        #3

        Does the rgb LED in the rotary knob react automatically to the knob turning or does it respond to software direction for color change?

        AFAIK the embedded RGB LED must be programmed like any other LED, which makes it much more complicated to augment the colors with the addition of something like a Neopixel ring. As of the present I've been able to control the embedded LED colors using this sketch but have yet to attempt any further modifications until I settle on how I want to actually handle communicating with the remote server. I'm most likely going to be using Home-Assistant to handle the overall automations so any communications will need to be a supported HASS component. As a result, I have been attempting to build the sketch around the MQTT protocol but this may prove more complicated than its worth. However, if I'm able to successfully modify the original MySensors example, then much of the hard work will have already be prepared in the MYS API...

        I could envision turning the knob to desired color per the rgb LED, push to set color (send to controller) which would also toggle the knob function to a dimmer control, possibly by using the LED brightness (without color change) as feedback and pushing the knob to set dim state and toggle back knob function to color control.

        If I am able to use the original example as my template, then your suggestion might be much easier to incorporate since the the dimmer component already exists without modification. The task therefore is to figure out which elements within the original sketch can be modified to trigger RGB events. This of course requires a certain familiarity with the MySensors framework for which I must confess a certain ignorance. So again, if others are more familiar with MYS have any suggestions while I'm catching up on the docs, please do speak up and I'll be sure to credit your participation.

        Besides writing the actual source code, much work remains on the Home-Assistant end to ensure proper integration. As of the present, MySensors support officially only extends to raw analog sensor data via the serial gateway. Additionally, as of Home-Assistant version 0.10, raw sensor data now requires the use of a new templating engine. Some progress has also been made in incorporating the experimental MQTTClientGateway to HA. Both developments are likely positive indications as I could envision MySensors support would be enhanced greatly with a community curated template and MQTT support.

        1 Reply Last reply
        0
        • martinhjelmareM Offline
          martinhjelmareM Offline
          martinhjelmare
          Plugin Developer
          wrote on last edited by
          #4

          As for the new template feature in home assistant, I don't believe this affects the mysensors integration. To my knowledge the payload sent in the mysensors protocol, either over serial or MQTT gateway is never a mix of different properties. I.e. it's not raw but already processed, so there's no need to use a template to extract a value from the payload.

          If someone knows that I'm wrong, please correct me.

          1 Reply Last reply
          0
          • H Offline
            H Offline
            humblehacker
            wrote on last edited by
            #5

            For reference- This is the code for the DIMMABLELIGHTWITHROTARYENCODER example in the MYS Library-

            /**
             * 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)  
             */
            
             
            #include <SPI.h>
            #include <Encoder.h>
            #include <MySensor.h>  
            #include <Bounce2.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.2"
            
            #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];
            
            MySensor gw;
            MyMessage dimmerMsg(CHILD_ID_LIGHT, V_DIMMER);
            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);
            
              // Init mysensors library
              gw.begin(incomingMessage, AUTO, false);
            
              // Send the Sketch Version Information to the Gateway
              gw.present(CHILD_ID_LIGHT, S_DIMMER);
              gw.sendSketchInfo(SN, SV);
            
              // 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);  
              gw.send(dimmerMsg.set(oldLevel), true);   
            
              Serial.println("Ready to receive messages...");  
            }
            
            void loop()      
            {
              // Process incoming messages (like config and light state from controller)
              gw.process();
              
              // 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 incomingMessage(const MyMessage &message)
            {
              if (message.type == V_LIGHT) {
                // 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
                gw.send(dimmerMsg.set(newLevel), true);
                // We do not change any levels here until ack comes back from gateway 
                return;
              } else if (message.type == V_DIMMER) {
                // 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); 
                
              // 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();
            
              if (encoderValue > 100) {
                encoderValue = 100;
                knob.write(100);
              } 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 > 0 ? saved : 100;
                }
                gw.send(dimmerMsg.set(newLevel),true);
              }
              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) 
                gw.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(gw.loadState(pos),0),100);
            }
            void saveLevelState(byte pos, byte data) {
              gw.saveState(pos,min(max(data,0),100));
            }
            
            
            
            1 Reply Last reply
            0
            • H Offline
              H Offline
              humblehacker
              wrote on last edited by
              #6

              There's also the following sketch for controlling an RGB LED strip from PiDome-

              // Example sketch showing how to control an RGB Led Strip.
              // This example will not remember the last rgb color set after power failure.
              
              #include <MySensor.h>
              #include <SPI.h>
              
              #define RED  3  // Arduino PWM pin for Red
              #define GREEN 5 // Arduino PWM pin for Green
              #define BLUE 6  // Arduino PWM pin for Blue
              #define node 1  // Assigning the node (this will be the address for Pidome)
              #define strip 1  // sensor number needed in the custom devices set up
              
              int RGB_pins[3] = {RED,GREEN,BLUE};
              long RGB_values[3] = {0,0,0};
              
              MySensor gw; 
              
              void setup()
              {
                  // Initialize library and add callback for incoming messages
                  gw.begin(incomingMessage, node, true);
                  
                  // Send the sketch version information to the gateway and Controller
                  gw.sendSketchInfo("RGB Node", "1.0");
                  
                  // Register the sensor to gw
                  gw.present(strip, S_CUSTOM);
                  
                  // Set the rgb pins in output mode
                  for (int i = 0; i<3; i++) {
                      pinMode(RGB_pins[i], OUTPUT);
                  }
              }
              
              
              void loop()
              {
                  // Alway process incoming messages whenever possible
                  gw.process();
              }
              
              void incomingMessage(const MyMessage &message) {
                  // We only expect one type of message from controller. But we better check anyway.
                  if (message.type==V_VAR1) {
              	// starting to process the hex code
                      String hexstring = message.getString(); //here goes the hex color code coming from Pidome through MySensors (like FF9A00)
                      long number = (long) strtol( &hexstring[0], NULL, 16);
                      RGB_values[0] = number >> 16;
                      RGB_values[1] = number >> 8 & 0xFF;
                      RGB_values[2] = number & 0xFF;
                      
                      for (int i = 0; i<3; i++) {
                          analogWrite(RGB_pins[i],RGB_values[i]);
                      }
                      
                      // Write some debug info
                      Serial.print("Red is " );
                      Serial.println(RGB_values[0]);
                      Serial.print("Green is " );
                      Serial.println(RGB_values[1]);
                      Serial.print("Blue is " );
                      Serial.println(RGB_values[2]);
              
                      //if you want to convert it again from rgb to hex
                      long rgb = 0;
                      rgb = ((long)RGB_values[0] << 16) | ((long)RGB_values[1] << 8 ) | (long)RGB_values[2];
              	Serial.print("This is the reconverted HEX value: #" );
                      Serial.println(String(rgb, HEX));
                  }
              }```
              1 Reply Last reply
              0
              • H Offline
                H Offline
                humblehacker
                wrote on last edited by
                #7

                Another MYS RGB Encoder example- http://forum.mysensors.org/topic/1626/5-channel-rgbww-led-dimmer-with-rotary-encoder/3
                I might just have enough to work with now:)

                /***
                 * 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 4 channels of Dimmable LED Lights using PWM for the MySensors.org project
                 * Inspired by the PWM example sketcy by <henrik.ekblad@gmail.com> and Bruce Lacey.
                 * 
                 * REVISION HISTORY
                 * Version 0.1 - Sept 5, 2014 John Soward <soward@soward.net>  -- Initial implementation based on example scripts.
                 * Version 0.2 - Sept 7, 2014 --  <soward@soward.net> -- Adjust Timer resolution, neaten up, separate debugging output 
                 * Version 0.3 - July 5, 2015 --  <soward@soward.net> Pin changes, use Bounce2, update encoder state when brightness changed via mySensors net
                 *
                 ***/
                #define DEBUG 0
                #define SN "RGBWW DIM + ENC"
                #define SV "0.3"
                
                #include <Encoder.h>    // Using https://www.pjrc.com/teensy/arduino_libraries/Encoder.zip
                #include <Bounce2.h>     
                #include <MySensor.h> 
                #include <SPI.h>
                
                // Ardunio pro mini's have PWM only on 3,5,6,9,10,11
                // See http://arduino.cc/en/Main/ArduinoBoardProMini
                #define RED 3      // Arduino pin attached to MOSFET Gate pin
                #define GREEN 5
                #define BLUE 6
                #define WHT 9
                #define WHT2 10    //WHT2 is a pure white strip, distinct from the RGBW strip for over stove use
                
                // Rotary Encoder connections 
                // Better response if one or both of the encoder triggers is on an interrupt pin
                #define ENC_SWITCH 8
                #define ENC_A 2
                #define ENC_B A2
                #define ENC_SCALE 2.56   // scaling encoder 256 steps to 100%
                
                #define FADE_DELAY 5  // Delay in ms
                #define FADE_DELAY_FACTOR 16
                
                // MySenor uses pin 9 for CE by default, , can be changed here.
                // Pin 10 used for CS can also be changed.
                MySensor gw(4,7);
                
                Encoder myEnc(ENC_A, ENC_B);
                Bounce PowerButton = Bounce();
                
                static int levels[5];  // Current dim levels...
                MyMessage dimMsgs[5];
                MyMessage lightMsgs[5];
                int rotValue = 0;   // encoder position (for WHT2)
                int lastBrightness; // last 'on' brightness (for WHT2)
                
                void setup()  
                { 
                  //Increase Timer frequency to prevent flicker in Pins 5,6 PWM
                  // This alters the performance of millis(), micros() & delay() (basically by 1/16) Unless wiring.c is modified.
                  // See http://playground.arduino.cc/Main/TimerPWMCheatsheet
                  // W/O this change, a low frequency 'beat' or flicker was exhibited when PWM'ing Pin 5 or 6 and another other pin (on Pro Mini 8Mhz clone)
                  TCCR0A = _BV(COM0A1) | _BV(COM0B1) | _BV(WGM00);  
                  
                  pinMode(RED,OUTPUT);
                  pinMode(GREEN,OUTPUT);
                  pinMode(BLUE,OUTPUT);
                  pinMode(WHT,OUTPUT);
                  pinMode(WHT2,OUTPUT);
                  
                  pinMode(ENC_SWITCH,INPUT);
                  digitalWrite(ENC_SWITCH,HIGH);
                  PowerButton.attach(ENC_SWITCH);
                  PowerButton.interval(80);
                
                  // FIXME Mnemonics for the colors/names/locations of the lights could be useful here.
                  for (int i = 0; i < 5; i++) {
                    dimMsgs[i] = MyMessage(i,V_DIMMER);
                    lightMsgs[i] = MyMessage(i,V_LIGHT);
                    levels[i] = 20;
                  }
                
                  startupDance();
                  analogWrite(WHT2,0);
                
                #ifdef DEBUG
                  Serial.println( SN ); 
                #endif
                  gw.begin( incomingMessage );
                  
                  // Register each color LED Dimmable Light with the gateway
                  gw.present( 0, S_DIMMER );
                  gw.present( 1, S_DIMMER );
                  gw.present( 2, S_DIMMER );
                  gw.present( 3, S_DIMMER );
                  gw.present( 4, S_DIMMER );
                  
                  gw.sendSketchInfo(SN, SV);
                  // Pull the gateway's current dim level - restore light level upon sendor node power-up
                  gw.request( 0, V_DIMMER );
                  gw.request( 1, V_DIMMER );
                  gw.request( 2, V_DIMMER );
                  gw.request( 3, V_DIMMER );
                  gw.request( 4, V_DIMMER );
                }
                
                void loop() 
                {
                  
                  // Encoder and button handling.
                  // In this implemenation the Encoder and button control the 2nd White strip, position 4 in the array of strips)
                  // The encoder will brighten/dim the strip from it's current value.
                  // The button will turn off the strip if it is on, or return it to it's last known brightness if it is off
                  bool needsUpdate = false;
                  
                  int newRotValue = myEnc.read();
                  if (newRotValue != rotValue) { // I guess it really has changed
                    Serial.print("Encoder update:");
                    Serial.println(newRotValue);
                    if (newRotValue > 255 || newRotValue < 0) {
                        myEnc.write(rotValue); // Enforce max/min
                    } else {
                      rotValue = newRotValue;
                      needsUpdate = true;
                    }   
                  }
                  
                  if (PowerButton.update()) {
                    if (!PowerButton.read()) {
                      Serial.println("Button pushed");
                      Serial.print("lastBrightness: ");Serial.println(lastBrightness);
                      Serial.print("rotValue: ");Serial.println(rotValue);
                      if (rotValue) { // we are on, need to go off
                        lastBrightness = rotValue;
                        rotValue = 0;
                      } else {
                        rotValue = lastBrightness;
                      }
                      myEnc.write(rotValue);
                      needsUpdate = true;    
                    }
                  }
                  
                  if (needsUpdate) {
                      int normalizedValue = rotValue / ENC_SCALE;
                      fadeLEDToLevel(4,normalizedValue,0);
                      gw.send(dimMsgs[4].set(normalizedValue));
                      gw.send(lightMsgs[4].set(normalizedValue > 0 ? 1 : 0));
                  }
                  
                  // Standard mySensors message processing (no sleep)
                  gw.process();
                }
                
                void incomingMessage(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;
                    
                #ifdef DEBUG
                    Serial.print( "On child id ");
                    Serial.print(message.sensor);
                    Serial.print( " Changing level to " );
                    Serial.print( requestedLevel );
                    Serial.print( ", from " ); 
                    Serial.println( levels[message.sensor]);
                #endif
                
                    fadeLEDToLevel( message.sensor,requestedLevel,FADE_DELAY*FADE_DELAY_FACTOR );
                    
                    // Sensor 4 is the strip attached the the encoder, update the encoders value, using the scaling factor
                    // FIXME Mnemonics might make this more readable/extensible. 
                    if (message.sensor == 4) {
                        myEnc.write(requestedLevel*ENC_SCALE);
                    }  
                    
                    // Inform the gateway of the current DimmableLED's SwitchPower1 and LoadLevelStatus value...
                    gw.send(lightMsgs[message.sensor].set(levels[message.sensor] > 0 ? 1 : 0));
                
                    // hek comment: Is this really nessesary?
                    // soward: Probably not, unless there exists some reason why the requested value does not equal
                    // the set value 
                    gw.send( dimMsgs[message.sensor].set(levels[message.sensor]) );
                
                    }
                }
                
                void startupDance() {
                  int i,j;
                  
                // Bring each color up and down independently
                   for (i=0;i<5;i++) {
                     fadeLEDToLevel(i,100,1);
                     delay(50*FADE_DELAY_FACTOR);
                     fadeLEDToLevel(i,0,1);
                   }
                  
                 //Bringing each color up sequentially, then back down to 2
                  for (i=0;i<5;i++) {
                   fadeLEDToLevel(i,100,1);
                  }
                  delay(50*FADE_DELAY_FACTOR);
                  for (i=0;i<5;i++) {
                    fadeLEDToLevel(i,2,1);
                  }
                }
                
                // Helper function to map controller pins to names for strips
                int pinForID(int ledID) {
                  switch (ledID) {
                     case 0: return RED;
                     case 1: return GREEN;
                     case 2: return BLUE;
                     case 3: return WHT;
                     case 4: return WHT2;
                     return 0; // Default to Red
                  }
                }
                
                /***
                 *  This method provides a graceful fade up/down effect
                 */
                void fadeLEDToLevel( int theLED, int toLevel, int wait ) {
                    
                  int delta = ( toLevel - levels[theLED] ) < 0 ? -1 : 1;
                    
                  while ( levels[theLED] != toLevel ) {
                    levels[theLED] += delta;
                    analogWrite( pinForID(theLED), (int)(levels[theLED] / 100. * 255) );
                    delay( wait );
                  }
                }
                7
                POSTS 1.1k
                VIEWS Reply
                
                1 Reply Last reply
                0
                • sowardS Offline
                  sowardS Offline
                  soward
                  wrote on last edited by
                  #8

                  How do you envision the system working?

                  Were you just thinking that turning the knob would rotate through a pre-built palette of colors, which would be shown on the knob's RGB first then transferred to the final device or something where you could control the mix of RGB by pushing the encoder's button to switch from controlling R, G, and B until you get the desired color on the indicator LED then maybe a double push to transfer it to the final device?

                  I don't think either would be too difficult, but given the differing methods for specifying a color to the various RGB devices, I'm not sure how accurate the preview color will be on the knob's LED.

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


                  8

                  Online

                  11.7k

                  Users

                  11.2k

                  Topics

                  113.0k

                  Posts


                  Copyright 2019 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
                  • OpenHardware.io
                  • Categories
                  • Recent
                  • Tags
                  • Popular