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