Several dimmers



  • In my project i need to run 3 separate dimmers from one board. Can somebody give a hint how to integrate 3 dimmers in the standard dimmer sketch?

    #define SN "DimmableLED"
    #define SV "1.1"
    
    #include <MySensor.h> 
    #include <SPI.h>
    
    #define LED_PIN 3      // Arduino pin attached to MOSFET Gate pin
    #define FADE_DELAY 10  // Delay in ms for each percentage fade up/down (10ms = 1s full-range dim)
    
    MySensor gw;
    
    static int currentLevel = 0;  // Current dim level...
    MyMessage dimmerMsg(0, V_DIMMER);
    MyMessage lightMsg(0, V_LIGHT);
    
    
    /***
     * Dimmable LED initialization method
     */
    void setup()  
    { 
      Serial.println( SN ); 
      gw.begin( incomingMessage );
      
      // Register the LED Dimmable Light with the gateway
      gw.present( 0, 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 );
    }
    
    /***
     *  Dimmable LED main processing loop 
     */
    void loop() 
    {
      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;
        
        Serial.print( "Changing level to " );
        Serial.print( requestedLevel );
        Serial.print( ", from " ); 
        Serial.println( currentLevel );
    
        fadeToLevel( requestedLevel );
        
        // Inform the gateway of the current DimmableLED's SwitchPower1 and LoadLevelStatus value...
        gw.send(lightMsg.set(currentLevel > 0 ? 1 : 0));
    
        // hek comment: Is this really nessesary?
        gw.send( dimmerMsg.set(currentLevel) );
    
        
        }
    }
    
    /***
     *  This method provides a graceful fade up/down effect
     */
    void fadeToLevel( int toLevel ) {
    
      int delta = ( toLevel - currentLevel ) < 0 ? -1 : 1;
      
      while ( currentLevel != toLevel ) {
        currentLevel += delta;
        analogWrite( LED_PIN, (int)(currentLevel / 100. * 255) );
        delay( FADE_DELAY );
      }
    }
    

  • Contest Winner

    Here's the declaration part, including presenting the node. Didn't have time to modify the incoming message handler, but hopefully it helpts

    #define SN "DimmableLED"
    #define SV "1.1"
    
    #include <MySensor.h> 
    #include <SPI.h>
    
    #define LED_PIN 3      // Arduino pin attached to MOSFET Gate pin
    #define FADE_DELAY 10  // Delay in ms for each percentage fade up/down (10ms = 1s full-range dim)
    #define DIMMER_NODE_1 1
    #define DIMMER_NODE_2 1
    #define DIMMER_NODE_3 1
    
    MySensor gw;
    
    // static int currentLevel1 = 0;  // Current dim level... <== static is static don't think you want that
    byte currentLevel1 = 0;  // Current dim level... 
    byte currentLevel2 = 0;  // Current dim level... 
    byte currentLevel3 = 0;  // Current dim level... 
    MyMessage dimmerMsg1(DIMMER_NODE_1, V_DIMMER);
    MyMessage lightMsg1(DIMMER_NODE_1, V_LIGHT);
    MyMessage dimmerMsg2(DIMMER_NODE_2, V_DIMMER);
    MyMessage lightMsg2(DIMMER_NODE_2, V_LIGHT);
    MyMessage dimmerMsg3(DIMMER_NODE_3, V_DIMMER);
    MyMessage lightMsg3(DIMMER_NODE_3, V_LIGHT);
    
    
    /***
     * Dimmable LED initialization method
     */
    void setup()  
    { 
      Serial.println( SN ); 
      gw.begin( incomingMessage );
      
      // Register the LED Dimmable Light with the gateway
      gw.present( DIMMER_NODE_1, S_DIMMER );
      gw.wait( 50 );
      gw.present( DIMMER_NODE_2, S_DIMMER );
      gw.wait( 50 );
      gw.present( DIMMER_NODE_3, S_DIMMER );
      gw.wait( 50 );
      
      gw.sendSketchInfo(SN, SV);
      gw.wait( 50 );
      // Pull the gateway's current dim level - restore light level upon sendor node power-up
      gw.request( DIMMER_NODE_1, V_DIMMER );
      gw.wait( 50 );
      gw.request( DIMMER_NODE_2, V_DIMMER );
      gw.wait( 50 );
      gw.request( DIMMER_NODE_3, V_DIMMER );
    }
    

    I also changed the current level from static int to byte. The static part could never have worked. Dim level is 0-100 which fits in a byte (0-255) and thus a byte is better. Saves memory



  • Thank you for the help.

    Here is the final working code in case somebody needs it

    #define SN "DimmableLEDs"
    #define SV "1.0"
    
    #include <MySensor.h> 
    #include <SPI.h>
    
    #define LED_PIN_1 3
    #define LED_PIN_2 5
    #define LED_PIN_3 6
    #define FADE_DELAY 10
    #define DIMMER_NODE_1 0
    #define DIMMER_NODE_2 1
    #define DIMMER_NODE_3 2
    
    MySensor gw;
    
    byte currentLevel[3] = {0,0,0};
    MyMessage dimmerMsg0(0, V_DIMMER);
    MyMessage lightMsg0(0, V_LIGHT);
    MyMessage dimmerMsg1(1, V_DIMMER);
    MyMessage lightMsg1(1, V_LIGHT);
    MyMessage dimmerMsg2(2, V_DIMMER);
    MyMessage lightMsg2(2, V_LIGHT);
    
    
    
    void setup()  
    { 
      Serial.println( SN ); 
      gw.begin( incomingMessage );
      
      // Register the LED Dimmable Light with the gateway
      gw.present( DIMMER_NODE_1, S_DIMMER );
      gw.wait( 50 );
      gw.present( DIMMER_NODE_2, S_DIMMER );
      gw.wait( 50 );
      gw.present( DIMMER_NODE_3, S_DIMMER );
      gw.wait( 50 );
      
      gw.sendSketchInfo(SN, SV);
      gw.wait( 50 );
      // Pull the gateway's current dim level - restore light level upon sendor node power-up
      gw.request( DIMMER_NODE_1, V_DIMMER );
      gw.wait( 50 );
      gw.request( DIMMER_NODE_2, V_DIMMER );
      gw.wait( 50 );
      gw.request( DIMMER_NODE_3, V_DIMMER );
    }
    
    void loop() 
    {
      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;
        
        Serial.print( "Changing level to " );
        Serial.print( requestedLevel );
        Serial.print( ", from " ); 
        Serial.println( currentLevel[message.sensor] );
    
        fadeToLevel( requestedLevel, message.sensor);
        
      // Inform the gateway of the current DimmableLED's SwitchPower1 and LoadLevelStatus value...
      // hek comment: Is this really nessesary?
    switch(message.sensor)
      {
        case 0:
          gw.send(lightMsg0.set(currentLevel[0] > 0 ? 1 : 0));
          gw.send( dimmerMsg0.set(currentLevel[0]) );
          break;
        case 1:
          gw.send(lightMsg1.set(currentLevel[1] > 0 ? 1 : 0));
          gw.send( dimmerMsg1.set(currentLevel[1]) );
          break;
        case 2:
          gw.send(lightMsg2.set(currentLevel[2] > 0 ? 1 : 0));
          gw.send( dimmerMsg2.set(currentLevel[2]) );
          break;  
      }
        
        }
    }
    
    void fadeToLevel( int toLevel, byte sensorId ) {
    
      int delta = ( toLevel - currentLevel[sensorId] ) < 0 ? -1 : 1;
      
      while ( currentLevel[sensorId] != toLevel ) {
        currentLevel[sensorId] += delta;
      
     switch(sensorId)
      {
        case 0:
          analogWrite( LED_PIN_1, (int)(currentLevel[sensorId] / 100. * 255) );
          break;
        case 1:
          analogWrite( LED_PIN_2, (int)(currentLevel[sensorId] / 100. * 255) );  
          break;
        case 2:
          analogWrite( LED_PIN_3, (int)(currentLevel[sensorId] / 100. * 255) );
          break;      
      }
        
        delay( FADE_DELAY );
      }
    }```


  • Every time the node is reset - LED is on. You have to send 100% first to make it work. Is there a way to start with LED off?



  • This effect is also on the standard LED dimmer sketch published on mysensors site


  • Admin

    @moskovskiy82 said:

    Is there a way to start with LED off?

    Yes, instead of requesting value at startup, your can send a level 0 to controller.



  • @hek
    Can you help with the code example for this?
    So we comment out
    gw.request( DIMMER_NODE_1, V_DIMMER );
    and substitute it with?



  • Should it go like this?

    
    void setup()  
    { SOME CODE HERE
    ...
     gw.present( DIMMER_NODE_1, S_DIMMER );
     gw.send(dimmerMsg0.set(0));
     digitalWrite( LED_PIN_1, 0);```


  • No luck with this one


  • Admin

    You should probably send with ack enabled, this this:

    gw.send(dimmerMsg0.set(0), true);



  • The answer was simple

    Change
    digitalWrite( LED_PIN_1, 0);
    to
    analogWrite( LED_PIN_1, 0);


 

285
Online

8.0k
Users

8.8k
Topics

94.3k
Posts