DimmableLED+Relay problem



  • Please help me verify the source of the problem. I use mysensors + domoticz.
    When I turn on one of the three dimmable led pins, the corresponding screen (first, second or third) is also activated
    Probably the problem lies in the code, but despite many attempts I did not manage to come to what is the reason for the error

    // Enable debug prints to serial monitor
    #define MY_DEBUG
    
    // Enable serial gateway
    #define MY_GATEWAY_SERIAL
    
    #include <MySensors.h>
    
    //relay
    #define RELAY_PIN 26  // Arduino Digital I/O pin number for first relay (second on pin+1 etc)
    //#define NUMBER_OF_RELAYS 16 // Total number of attached relays
    #define NUMBER_OF_RELAYS 20
    #define RELAY_ON 0  // GPIO value to write to turn on attached relay
    #define RELAY_OFF 1 // GPIO value to write to turn off attached relay
    int lastLightLevel;
    
    //dimmable led
    #define noLEDs 3
    const int LED_Pin[] = {4, 5, 6};
    
    #define FADE_DELAY 10  // Delay in ms for each percentage fade up/down (10ms = 1s full-range dim)
    static int currentLevel1 = 0;  // Current dim level...
    static int currentLevel2 = 0;  // Current dim level...
    static int currentLevel3 = 0;  // Current dim level...
    
    MyMessage dimmer1Msg(1, V_DIMMER);
    MyMessage light1Msg(1, V_LIGHT);
    MyMessage dimmer2Msg(2, V_DIMMER);
    MyMessage light2Msg(2, V_LIGHT);
    MyMessage dimmer3Msg(3, V_DIMMER);
    MyMessage light3Msg(3, V_LIGHT);
    
    
    
    
    
    void before()
    {
      for (int sensorRel = 4, pin = RELAY_PIN; sensorRel <= NUMBER_OF_RELAYS; sensorRel++, pin++) {
        // Then set relay pins in output mode
        pinMode(pin, OUTPUT);
        // Set relay to last known state (using eeprom storage)
        digitalWrite(pin, loadState(sensorRel) ? RELAY_ON : RELAY_OFF);
      }
    }
    
    void setup()
    {
      // LEDS
      // 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()
    {
      // Send the sketch version information to the gateway and Controller
      sendSketchInfo("mysz0n", "4.0");
      for (int sensorRel = 4, pin = RELAY_PIN; sensorRel <= NUMBER_OF_RELAYS; sensorRel++, pin++) {
        // Register all sensors to gw (they will be created as child devices)
        present(sensorRel, S_BINARY);
      }
    
      // Register the LED Dimmable Light with the gateway
      for (int sensor = 1; sensor <= noLEDs; sensor++) {
        present(sensor, S_DIMMER);
        wait(2);
      }
    
    
    
    }
    
    
    void loop()
    {
    
    }
    
    
    void receive(const MyMessage &message)
    {
      // We only expect one type of message from controller. But we better check anyway.
      if (message.type == V_STATUS) {
        // Change relay state
        digitalWrite(message.sensor - 1 + RELAY_PIN, message.getBool() ? RELAY_ON : RELAY_OFF);
        // Store state in eeprom
        saveState(message.sensor, message.getBool());
        // Write some debug info
        Serial.print("Incoming change for sensor:");
        Serial.print(message.sensor);
        Serial.print(", New status: ");
        Serial.println(message.getBool());
      }
    
    
    
      if (message.type == V_LIGHT || message.type == V_DIMMER) {
    
        if (message.sensor == 1) {
          //  Retrieve the power or dim level from the incoming request message
          int requestedLevel1 = atoi( message.data );
          // Adjust incoming level if this is a V_LIGHT variable update [0 == off, 1 == on]
          requestedLevel1 *= ( message.type == V_LIGHT ? 100 : 1 );
          // Clip incoming level to valid range of 0 to 100
          requestedLevel1 = requestedLevel1 > 100 ? 100 : requestedLevel1;
          requestedLevel1 = requestedLevel1 < 0   ? 0   : requestedLevel1;
          fadeToLevel1( requestedLevel1, message.sensor );
          send(light1Msg.set(currentLevel1 > 0 ? 1 : 0));
          send(dimmer1Msg.set(currentLevel1) );
        }
        if (message.sensor == 2) {
          //  Retrieve the power or dim level from the incoming request message
          int requestedLevel2 = atoi( message.data );
          // Adjust incoming level if this is a V_LIGHT variable update [0 == off, 1 == on]
          requestedLevel2 *= ( message.type == V_LIGHT ? 100 : 1 );
          // Clip incoming level to valid range of 0 to 100
          requestedLevel2 = requestedLevel2 > 100 ? 100 : requestedLevel2;
          requestedLevel2 = requestedLevel2 < 0   ? 0   : requestedLevel2;
          fadeToLevel2( requestedLevel2, message.sensor );
          send(light2Msg.set(currentLevel2 > 0 ? 1 : 0));
          send(dimmer2Msg.set(currentLevel2) );
        }
    
        if (message.sensor == 3) {
          //  Retrieve the power or dim level from the incoming request message
          int requestedLevel3 = atoi( message.data );
          // Adjust incoming level if this is a V_LIGHT variable update [0 == off, 1 == on]
          requestedLevel3 *= ( message.type == V_LIGHT ? 100 : 1 );
          // Clip incoming level to valid range of 0 to 100
          requestedLevel3 = requestedLevel3 > 100 ? 100 : requestedLevel3;
          requestedLevel3 = requestedLevel3 < 0   ? 0   : requestedLevel3;
          fadeToLevel3( requestedLevel3, message.sensor );
          send(light3Msg.set(currentLevel3 > 0 ? 1 : 0));
          send(dimmer3Msg.set(currentLevel3) );
        }
      }
    
    
    }
    
    
    
    /***
        This method provides a graceful fade up/down effect
    */
    void fadeToLevel1( int toLevel1, int ledid1 ) {
      int delta1 = ( toLevel1 - currentLevel1 ) < 0 ? -1 : 1;
      while ( currentLevel1 != toLevel1 ) {
        currentLevel1 += delta1;
        analogWrite(LED_Pin[ledid1 - 1], (int)(currentLevel1 / 100. * 255) );
        wait( FADE_DELAY );
      }
    }
    void fadeToLevel2( int toLevel2, int ledid2 ) {
    
      int delta2 = ( toLevel2 - currentLevel2 ) < 0 ? -1 : 1;
    
      while ( currentLevel2 != toLevel2 ) {
        currentLevel2 += delta2;
        analogWrite(LED_Pin[ledid2 - 1], (int)(currentLevel2 / 100. * 255) );
        wait( FADE_DELAY );
      }
    }
    void fadeToLevel3( int toLevel3, int ledid3 ) {
    
      int delta3 = ( toLevel3 - currentLevel3 ) < 0 ? -1 : 1;
    
      while ( currentLevel3 != toLevel3 ) {
        currentLevel3 += delta3;
        analogWrite(LED_Pin[ledid3 - 1], (int)(currentLevel3 / 100. * 255) );
        wait( FADE_DELAY );
      }
    }```

  • Mod

    @mysz0n calling send() from within receive() will cause the current message to be overwritten which makes the logic match on the sent message instead of the received message.

    You’ll need to move the send() calls to loop() and use variables to let loop() know when it should send.



  • @mfalkvidd Basically the code above is a combination of 2 examples from mysensors library. Dimmable LED Actuator and Relay Actuator. I thought that since the individual scripts work properly, combining them should not change the logic of the whole script?


  • Mod

    @mysz0n it is actually the combination that causes the problem.

    In the library examples, the message is never looked at after send() is called, so overwriting the message is not a problem.

    But still, it would be nice if someone could spend the time and effort required to change the examples to make them safe to combine.


 

292
Online

7.6k
Users

8.5k
Topics

91.2k
Posts