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 ); } }
-
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
-
@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
-
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);