Skip to content
  • MySensors
  • 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. My Project
  3. Relay and light dimmer with light level in one node

Relay and light dimmer with light level in one node

Scheduled Pinned Locked Moved My Project
7 Posts 3 Posters 3.0k Views 3 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.
  • J Offline
    J Offline
    jacek
    wrote on last edited by jacek
    #1

    Hello,

    I have a problem with programing one node with light dimmer, temp, light level and relay.
    Node with temp,, light level and light dimmer node work perfectli but when I add relay with button then node work fine when I click the button on node to turn on or off light and click another button to turn on or off relay and on domoticz icons is read state from node fine but problem is when I wont turn "on" or "off" light or relay from domoticz, if I wont turn "on" light from domoticz on node is on light and relay and I dont know why :( can you help mi with this, please ?

    I add that light can "on" only when light level is smaller then 350 but relay must working independently light level.

    Code for relay is betwen tags "//WENT" and "//END"

    This is my code from node:

     
    #include <SPI.h>
    #include <Encoder.h>
    #include <MySensor.h>  
    #include <Bounce2.h>
    #include <DallasTemperature.h>
    #include <OneWire.h>
    
    #define COMPARE_TEMP 1 // Send temperature only if changed? 1 = Yes 0 = No
    #define ONE_WIRE_BUS 19 // Pin where dallase sensor is connected 
    #define MAX_ATTACHED_DS18B20 1
    OneWire oneWire(ONE_WIRE_BUS); // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
    DallasTemperature sensors(&oneWire); // Pass the oneWire reference to Dallas Temperature. 
    
    #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 photoPin A6         // Fotorezystor 
    #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 16
    #define ID 15
    #define EEPROM_DIM_LEVEL_LAST 1
    #define EEPROM_DIM_LEVEL_SAVE 2
    
    #define LIGHT_OFF 0
    #define LIGHT_ON 1
    
    //WENT
    #define WENT_RELAY_PIN  17  // Arduino Digital I/O pin number for relay 
    #define WENT_BUTTON_PIN  18  // Arduino Digital I/O pin number for button 
    #define CHILD_ID_WENT 17   // Id of the sensor child
    #define RELAY_ON 1
    #define RELAY_OFF 0
    
    //END
    
    int dimValue;
    int fadeTo;
    int fadeDelta;
    int persons;
    byte oldButtonVal;
    bool changedByKnob=false;
    bool sendDimValue=false;
    unsigned long lastFadeStep;
    unsigned long sendDimTimeout;
    char convBuffer[10];
    
    float lastTemperature[MAX_ATTACHED_DS18B20];
    int numSensors=0;
    boolean receivedConfig = false;
    boolean metric = true;
    
    unsigned long on = 0;
    unsigned long onT = 0;
    
    MySensor gw;
    
    // Initialize temperature message
    MyMessage msg(0,V_TEMP);
    MyMessage dimmerMsg(CHILD_ID_LIGHT, V_DIMMER);
    MyMessage msgl(0, V_LIGHT_LEVEL);
    
    //WENT
    MyMessage msgW(CHILD_ID_WENT,V_ARMED);
    Bounce debouncer2 = Bounce(); 
    int oldValue=0;
    bool state;
    //END
    Encoder knob(KNOB_ENC_PIN_1, KNOB_ENC_PIN_2);  
    Bounce debouncer = Bounce(); 
    int lastLightLevel;
    
    void setup()  
    { 
      
       // The third argument enables repeater mode.
    //  gw.begin(NULL, AUTO, true);
    
      //Send the sensor node sketch version information to the gateway
     // gw.sendSketchInfo("Repeater Node", "1.0");
    
    
      
      // Set knob button pin as input (with debounce)
      pinMode(KNOB_BUTTON_PIN, INPUT);
      pinMode(photoPin, 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, ID, true);
    
      // Send the Sketch Version Information to the Gateway
      gw.present(CHILD_ID_LIGHT, S_DIMMER);
      
      gw.sendSketchInfo(SN, SV);
      gw.sendSketchInfo("Repeater Node", "1.0");
      // Retreive our last dim levels from the eprom
      fadeTo = dimValue = 0;
      byte oldLevel = 0;
      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..."); 
    
       // Startup up the OneWire library
      sensors.begin();
      // requestTemperatures() will not block current thread
      sensors.setWaitForConversion(false);
      // Fetch the number of attached temperature sensors  
      numSensors = sensors.getDeviceCount();
    
      // Present all sensors to controller
      for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) {   
         gw.present(i, S_TEMP);
         
      }
      gw.present(15, S_LIGHT_LEVEL);
      //WENT
      
    // Send the sketch version information to the gateway and Controller
      gw.sendSketchInfo("Relay & Button", "1.0");
    
     // Setup the button
      pinMode(WENT_BUTTON_PIN,INPUT);
      // Activate internal pull-up
      digitalWrite(WENT_BUTTON_PIN,HIGH);
      
      // After setting up the button, setup debouncer
      debouncer2.attach(WENT_BUTTON_PIN);
      debouncer2.interval(4);
    
      // Register all sensors to gw (they will be created as child devices)
      gw.present(CHILD_ID_WENT, V_ARMED);
    
      // Make sure relays are off when starting up
      digitalWrite(WENT_RELAY_PIN, RELAY_OFF);
      // Then set relay pins in output mode
      pinMode(WENT_RELAY_PIN, OUTPUT);   
          
      // Set relay to last known state (using eeprom storage) 
      state = gw.loadState(CHILD_ID_WENT);
      digitalWrite(WENT_RELAY_PIN, state?RELAY_ON:RELAY_OFF);
      //END
    }
    
    void loop()      
    {
      // Process incoming messages (like config and light state from controller)
      gw.process();
    //WENT
    
    debouncer2.update();
      // Get the update value
      int value = debouncer2.read();
      if (value != oldValue && value==0) {
          gw.send(msgW.set(state?false:true), true); // Send new state and request ack back
      }
      oldValue = value;
    //END
      // Sprawdzenie temperatury
      CheckTemp();
      onT = onT + 1;
      on = on + 1;
      if (on > 401 + 2*ID) {
      // Poziom swiata
      lightLevel();
      on = 0;
      }
    
      if (analogRead(photoPin) > 350) { persons = 0;} else {persons = 1;}
        
      // Check if someone has pressed the knob button
      checkButtonClick();
      
      // Fade light to new dim value
      fadeStep();
    }
    
    
    
    void lightLevel()
    {
    int lightLevel = (analogRead(photoPin)); 
      Serial.println(lightLevel);
      if (lightLevel != lastLightLevel) {
          gw.send(msgl.set(lightLevel));
          lastLightLevel = lightLevel;
      }
    }
    
    
    void CheckTemp()
    {
    
    // Fetch temperatures from Dallas sensors
      sensors.requestTemperatures();
      
      // Read temperatures and send them to controller 
      for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) {
     
        // Fetch and round temperature to one decimal
        float temperature = static_cast<float>(static_cast<int>((gw.getConfig().isMetric?sensors.getTempCByIndex(i):sensors.getTempFByIndex(i)) * 10.)) / 10.;
     
        // Only send data if temperature has changed and no error
        #if COMPARE_TEMP == 1
        if (lastTemperature[i] != temperature && temperature != -127.00 && temperature != 85.00) {
        #else
        if (temperature != -127.00 && temperature != 85.00) {
        #endif
          
              if (onT > 400 + 2*ID) {
          // Send in the new temperature
          gw.send(msg.setSensor(i).set(temperature,1));
             onT = 0; }
          // Save new temperatures for next compare
          lastTemperature[i]=temperature;
        }
      }
      
    }
    
    
    
    
    void incomingMessage(const MyMessage &message)
    {
      
        //WENT
     // We only expect one type of message from controller. But we better check anyway.
      if (message.isAck()) {
         Serial.println("This is an ack from gateway");
      }
    
      if (message.type == V_ARMED) {
         // Change relay state
         state = message.getBool();
         digitalWrite(WENT_RELAY_PIN, state?RELAY_ON:RELAY_OFF);
         // Store state in eeprom
         gw.saveState(CHILD_ID_WENT, state);
        
         // Write some debug info
         Serial.print("Incoming change for sensor:");
         Serial.print(message.sensor);
         Serial.print(", New status: ");
         Serial.println(message.getBool());
       } 
      //END
      if (analogRead(photoPin) > 350) { persons = 0;} else {persons = 1;}
      if (message.type == V_LIGHT && persons == 1) {
        // 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 && persons == 1) {
        // 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);
      }
     if (persons == 1){
           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();
    } else if (persons == 0){
      if (message.getString() != 0) 
              {gw.send(dimmerMsg.set(0), true);}
       else
              {return;}  
    
     }
    }
    
    
    void checkButtonClick()
    {
    if ( persons == 1 ) {
      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);
         int saved = 100;
          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));
    }
    
    
    
    
    
    J sundberg84S 2 Replies Last reply
    0
    • J jacek

      Hello,

      I have a problem with programing one node with light dimmer, temp, light level and relay.
      Node with temp,, light level and light dimmer node work perfectli but when I add relay with button then node work fine when I click the button on node to turn on or off light and click another button to turn on or off relay and on domoticz icons is read state from node fine but problem is when I wont turn "on" or "off" light or relay from domoticz, if I wont turn "on" light from domoticz on node is on light and relay and I dont know why :( can you help mi with this, please ?

      I add that light can "on" only when light level is smaller then 350 but relay must working independently light level.

      Code for relay is betwen tags "//WENT" and "//END"

      This is my code from node:

       
      #include <SPI.h>
      #include <Encoder.h>
      #include <MySensor.h>  
      #include <Bounce2.h>
      #include <DallasTemperature.h>
      #include <OneWire.h>
      
      #define COMPARE_TEMP 1 // Send temperature only if changed? 1 = Yes 0 = No
      #define ONE_WIRE_BUS 19 // Pin where dallase sensor is connected 
      #define MAX_ATTACHED_DS18B20 1
      OneWire oneWire(ONE_WIRE_BUS); // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
      DallasTemperature sensors(&oneWire); // Pass the oneWire reference to Dallas Temperature. 
      
      #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 photoPin A6         // Fotorezystor 
      #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 16
      #define ID 15
      #define EEPROM_DIM_LEVEL_LAST 1
      #define EEPROM_DIM_LEVEL_SAVE 2
      
      #define LIGHT_OFF 0
      #define LIGHT_ON 1
      
      //WENT
      #define WENT_RELAY_PIN  17  // Arduino Digital I/O pin number for relay 
      #define WENT_BUTTON_PIN  18  // Arduino Digital I/O pin number for button 
      #define CHILD_ID_WENT 17   // Id of the sensor child
      #define RELAY_ON 1
      #define RELAY_OFF 0
      
      //END
      
      int dimValue;
      int fadeTo;
      int fadeDelta;
      int persons;
      byte oldButtonVal;
      bool changedByKnob=false;
      bool sendDimValue=false;
      unsigned long lastFadeStep;
      unsigned long sendDimTimeout;
      char convBuffer[10];
      
      float lastTemperature[MAX_ATTACHED_DS18B20];
      int numSensors=0;
      boolean receivedConfig = false;
      boolean metric = true;
      
      unsigned long on = 0;
      unsigned long onT = 0;
      
      MySensor gw;
      
      // Initialize temperature message
      MyMessage msg(0,V_TEMP);
      MyMessage dimmerMsg(CHILD_ID_LIGHT, V_DIMMER);
      MyMessage msgl(0, V_LIGHT_LEVEL);
      
      //WENT
      MyMessage msgW(CHILD_ID_WENT,V_ARMED);
      Bounce debouncer2 = Bounce(); 
      int oldValue=0;
      bool state;
      //END
      Encoder knob(KNOB_ENC_PIN_1, KNOB_ENC_PIN_2);  
      Bounce debouncer = Bounce(); 
      int lastLightLevel;
      
      void setup()  
      { 
        
         // The third argument enables repeater mode.
      //  gw.begin(NULL, AUTO, true);
      
        //Send the sensor node sketch version information to the gateway
       // gw.sendSketchInfo("Repeater Node", "1.0");
      
      
        
        // Set knob button pin as input (with debounce)
        pinMode(KNOB_BUTTON_PIN, INPUT);
        pinMode(photoPin, 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, ID, true);
      
        // Send the Sketch Version Information to the Gateway
        gw.present(CHILD_ID_LIGHT, S_DIMMER);
        
        gw.sendSketchInfo(SN, SV);
        gw.sendSketchInfo("Repeater Node", "1.0");
        // Retreive our last dim levels from the eprom
        fadeTo = dimValue = 0;
        byte oldLevel = 0;
        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..."); 
      
         // Startup up the OneWire library
        sensors.begin();
        // requestTemperatures() will not block current thread
        sensors.setWaitForConversion(false);
        // Fetch the number of attached temperature sensors  
        numSensors = sensors.getDeviceCount();
      
        // Present all sensors to controller
        for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) {   
           gw.present(i, S_TEMP);
           
        }
        gw.present(15, S_LIGHT_LEVEL);
        //WENT
        
      // Send the sketch version information to the gateway and Controller
        gw.sendSketchInfo("Relay & Button", "1.0");
      
       // Setup the button
        pinMode(WENT_BUTTON_PIN,INPUT);
        // Activate internal pull-up
        digitalWrite(WENT_BUTTON_PIN,HIGH);
        
        // After setting up the button, setup debouncer
        debouncer2.attach(WENT_BUTTON_PIN);
        debouncer2.interval(4);
      
        // Register all sensors to gw (they will be created as child devices)
        gw.present(CHILD_ID_WENT, V_ARMED);
      
        // Make sure relays are off when starting up
        digitalWrite(WENT_RELAY_PIN, RELAY_OFF);
        // Then set relay pins in output mode
        pinMode(WENT_RELAY_PIN, OUTPUT);   
            
        // Set relay to last known state (using eeprom storage) 
        state = gw.loadState(CHILD_ID_WENT);
        digitalWrite(WENT_RELAY_PIN, state?RELAY_ON:RELAY_OFF);
        //END
      }
      
      void loop()      
      {
        // Process incoming messages (like config and light state from controller)
        gw.process();
      //WENT
      
      debouncer2.update();
        // Get the update value
        int value = debouncer2.read();
        if (value != oldValue && value==0) {
            gw.send(msgW.set(state?false:true), true); // Send new state and request ack back
        }
        oldValue = value;
      //END
        // Sprawdzenie temperatury
        CheckTemp();
        onT = onT + 1;
        on = on + 1;
        if (on > 401 + 2*ID) {
        // Poziom swiata
        lightLevel();
        on = 0;
        }
      
        if (analogRead(photoPin) > 350) { persons = 0;} else {persons = 1;}
          
        // Check if someone has pressed the knob button
        checkButtonClick();
        
        // Fade light to new dim value
        fadeStep();
      }
      
      
      
      void lightLevel()
      {
      int lightLevel = (analogRead(photoPin)); 
        Serial.println(lightLevel);
        if (lightLevel != lastLightLevel) {
            gw.send(msgl.set(lightLevel));
            lastLightLevel = lightLevel;
        }
      }
      
      
      void CheckTemp()
      {
      
      // Fetch temperatures from Dallas sensors
        sensors.requestTemperatures();
        
        // Read temperatures and send them to controller 
        for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) {
       
          // Fetch and round temperature to one decimal
          float temperature = static_cast<float>(static_cast<int>((gw.getConfig().isMetric?sensors.getTempCByIndex(i):sensors.getTempFByIndex(i)) * 10.)) / 10.;
       
          // Only send data if temperature has changed and no error
          #if COMPARE_TEMP == 1
          if (lastTemperature[i] != temperature && temperature != -127.00 && temperature != 85.00) {
          #else
          if (temperature != -127.00 && temperature != 85.00) {
          #endif
            
                if (onT > 400 + 2*ID) {
            // Send in the new temperature
            gw.send(msg.setSensor(i).set(temperature,1));
               onT = 0; }
            // Save new temperatures for next compare
            lastTemperature[i]=temperature;
          }
        }
        
      }
      
      
      
      
      void incomingMessage(const MyMessage &message)
      {
        
          //WENT
       // We only expect one type of message from controller. But we better check anyway.
        if (message.isAck()) {
           Serial.println("This is an ack from gateway");
        }
      
        if (message.type == V_ARMED) {
           // Change relay state
           state = message.getBool();
           digitalWrite(WENT_RELAY_PIN, state?RELAY_ON:RELAY_OFF);
           // Store state in eeprom
           gw.saveState(CHILD_ID_WENT, state);
          
           // Write some debug info
           Serial.print("Incoming change for sensor:");
           Serial.print(message.sensor);
           Serial.print(", New status: ");
           Serial.println(message.getBool());
         } 
        //END
        if (analogRead(photoPin) > 350) { persons = 0;} else {persons = 1;}
        if (message.type == V_LIGHT && persons == 1) {
          // 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 && persons == 1) {
          // 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);
        }
       if (persons == 1){
             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();
      } else if (persons == 0){
        if (message.getString() != 0) 
                {gw.send(dimmerMsg.set(0), true);}
         else
                {return;}  
      
       }
      }
      
      
      void checkButtonClick()
      {
      if ( persons == 1 ) {
        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);
           int saved = 100;
            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));
      }
      
      
      
      
      
      J Offline
      J Offline
      jacek
      wrote on last edited by
      #2

      Nobody can help me?

      1 Reply Last reply
      0
      • hekH Offline
        hekH Offline
        hek
        Admin
        wrote on last edited by
        #3

        Sorry, it's pretty hard to follow this code...
        You should probably look at the debug log and add your own debug prints to narrow down your problem.

        First check that message arrives to node then follow up what happens to your incoming data.

        1 Reply Last reply
        0
        • J jacek

          Hello,

          I have a problem with programing one node with light dimmer, temp, light level and relay.
          Node with temp,, light level and light dimmer node work perfectli but when I add relay with button then node work fine when I click the button on node to turn on or off light and click another button to turn on or off relay and on domoticz icons is read state from node fine but problem is when I wont turn "on" or "off" light or relay from domoticz, if I wont turn "on" light from domoticz on node is on light and relay and I dont know why :( can you help mi with this, please ?

          I add that light can "on" only when light level is smaller then 350 but relay must working independently light level.

          Code for relay is betwen tags "//WENT" and "//END"

          This is my code from node:

           
          #include <SPI.h>
          #include <Encoder.h>
          #include <MySensor.h>  
          #include <Bounce2.h>
          #include <DallasTemperature.h>
          #include <OneWire.h>
          
          #define COMPARE_TEMP 1 // Send temperature only if changed? 1 = Yes 0 = No
          #define ONE_WIRE_BUS 19 // Pin where dallase sensor is connected 
          #define MAX_ATTACHED_DS18B20 1
          OneWire oneWire(ONE_WIRE_BUS); // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
          DallasTemperature sensors(&oneWire); // Pass the oneWire reference to Dallas Temperature. 
          
          #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 photoPin A6         // Fotorezystor 
          #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 16
          #define ID 15
          #define EEPROM_DIM_LEVEL_LAST 1
          #define EEPROM_DIM_LEVEL_SAVE 2
          
          #define LIGHT_OFF 0
          #define LIGHT_ON 1
          
          //WENT
          #define WENT_RELAY_PIN  17  // Arduino Digital I/O pin number for relay 
          #define WENT_BUTTON_PIN  18  // Arduino Digital I/O pin number for button 
          #define CHILD_ID_WENT 17   // Id of the sensor child
          #define RELAY_ON 1
          #define RELAY_OFF 0
          
          //END
          
          int dimValue;
          int fadeTo;
          int fadeDelta;
          int persons;
          byte oldButtonVal;
          bool changedByKnob=false;
          bool sendDimValue=false;
          unsigned long lastFadeStep;
          unsigned long sendDimTimeout;
          char convBuffer[10];
          
          float lastTemperature[MAX_ATTACHED_DS18B20];
          int numSensors=0;
          boolean receivedConfig = false;
          boolean metric = true;
          
          unsigned long on = 0;
          unsigned long onT = 0;
          
          MySensor gw;
          
          // Initialize temperature message
          MyMessage msg(0,V_TEMP);
          MyMessage dimmerMsg(CHILD_ID_LIGHT, V_DIMMER);
          MyMessage msgl(0, V_LIGHT_LEVEL);
          
          //WENT
          MyMessage msgW(CHILD_ID_WENT,V_ARMED);
          Bounce debouncer2 = Bounce(); 
          int oldValue=0;
          bool state;
          //END
          Encoder knob(KNOB_ENC_PIN_1, KNOB_ENC_PIN_2);  
          Bounce debouncer = Bounce(); 
          int lastLightLevel;
          
          void setup()  
          { 
            
             // The third argument enables repeater mode.
          //  gw.begin(NULL, AUTO, true);
          
            //Send the sensor node sketch version information to the gateway
           // gw.sendSketchInfo("Repeater Node", "1.0");
          
          
            
            // Set knob button pin as input (with debounce)
            pinMode(KNOB_BUTTON_PIN, INPUT);
            pinMode(photoPin, 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, ID, true);
          
            // Send the Sketch Version Information to the Gateway
            gw.present(CHILD_ID_LIGHT, S_DIMMER);
            
            gw.sendSketchInfo(SN, SV);
            gw.sendSketchInfo("Repeater Node", "1.0");
            // Retreive our last dim levels from the eprom
            fadeTo = dimValue = 0;
            byte oldLevel = 0;
            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..."); 
          
             // Startup up the OneWire library
            sensors.begin();
            // requestTemperatures() will not block current thread
            sensors.setWaitForConversion(false);
            // Fetch the number of attached temperature sensors  
            numSensors = sensors.getDeviceCount();
          
            // Present all sensors to controller
            for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) {   
               gw.present(i, S_TEMP);
               
            }
            gw.present(15, S_LIGHT_LEVEL);
            //WENT
            
          // Send the sketch version information to the gateway and Controller
            gw.sendSketchInfo("Relay & Button", "1.0");
          
           // Setup the button
            pinMode(WENT_BUTTON_PIN,INPUT);
            // Activate internal pull-up
            digitalWrite(WENT_BUTTON_PIN,HIGH);
            
            // After setting up the button, setup debouncer
            debouncer2.attach(WENT_BUTTON_PIN);
            debouncer2.interval(4);
          
            // Register all sensors to gw (they will be created as child devices)
            gw.present(CHILD_ID_WENT, V_ARMED);
          
            // Make sure relays are off when starting up
            digitalWrite(WENT_RELAY_PIN, RELAY_OFF);
            // Then set relay pins in output mode
            pinMode(WENT_RELAY_PIN, OUTPUT);   
                
            // Set relay to last known state (using eeprom storage) 
            state = gw.loadState(CHILD_ID_WENT);
            digitalWrite(WENT_RELAY_PIN, state?RELAY_ON:RELAY_OFF);
            //END
          }
          
          void loop()      
          {
            // Process incoming messages (like config and light state from controller)
            gw.process();
          //WENT
          
          debouncer2.update();
            // Get the update value
            int value = debouncer2.read();
            if (value != oldValue && value==0) {
                gw.send(msgW.set(state?false:true), true); // Send new state and request ack back
            }
            oldValue = value;
          //END
            // Sprawdzenie temperatury
            CheckTemp();
            onT = onT + 1;
            on = on + 1;
            if (on > 401 + 2*ID) {
            // Poziom swiata
            lightLevel();
            on = 0;
            }
          
            if (analogRead(photoPin) > 350) { persons = 0;} else {persons = 1;}
              
            // Check if someone has pressed the knob button
            checkButtonClick();
            
            // Fade light to new dim value
            fadeStep();
          }
          
          
          
          void lightLevel()
          {
          int lightLevel = (analogRead(photoPin)); 
            Serial.println(lightLevel);
            if (lightLevel != lastLightLevel) {
                gw.send(msgl.set(lightLevel));
                lastLightLevel = lightLevel;
            }
          }
          
          
          void CheckTemp()
          {
          
          // Fetch temperatures from Dallas sensors
            sensors.requestTemperatures();
            
            // Read temperatures and send them to controller 
            for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) {
           
              // Fetch and round temperature to one decimal
              float temperature = static_cast<float>(static_cast<int>((gw.getConfig().isMetric?sensors.getTempCByIndex(i):sensors.getTempFByIndex(i)) * 10.)) / 10.;
           
              // Only send data if temperature has changed and no error
              #if COMPARE_TEMP == 1
              if (lastTemperature[i] != temperature && temperature != -127.00 && temperature != 85.00) {
              #else
              if (temperature != -127.00 && temperature != 85.00) {
              #endif
                
                    if (onT > 400 + 2*ID) {
                // Send in the new temperature
                gw.send(msg.setSensor(i).set(temperature,1));
                   onT = 0; }
                // Save new temperatures for next compare
                lastTemperature[i]=temperature;
              }
            }
            
          }
          
          
          
          
          void incomingMessage(const MyMessage &message)
          {
            
              //WENT
           // We only expect one type of message from controller. But we better check anyway.
            if (message.isAck()) {
               Serial.println("This is an ack from gateway");
            }
          
            if (message.type == V_ARMED) {
               // Change relay state
               state = message.getBool();
               digitalWrite(WENT_RELAY_PIN, state?RELAY_ON:RELAY_OFF);
               // Store state in eeprom
               gw.saveState(CHILD_ID_WENT, state);
              
               // Write some debug info
               Serial.print("Incoming change for sensor:");
               Serial.print(message.sensor);
               Serial.print(", New status: ");
               Serial.println(message.getBool());
             } 
            //END
            if (analogRead(photoPin) > 350) { persons = 0;} else {persons = 1;}
            if (message.type == V_LIGHT && persons == 1) {
              // 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 && persons == 1) {
              // 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);
            }
           if (persons == 1){
                 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();
          } else if (persons == 0){
            if (message.getString() != 0) 
                    {gw.send(dimmerMsg.set(0), true);}
             else
                    {return;}  
          
           }
          }
          
          
          void checkButtonClick()
          {
          if ( persons == 1 ) {
            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);
               int saved = 100;
                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));
          }
          
          
          
          
          
          sundberg84S Offline
          sundberg84S Offline
          sundberg84
          Hardware Contributor
          wrote on last edited by
          #4

          @jacek said:

          when I add relay with button then node work fine when I click the button on node to turn on or off light and click another button to turn on > or off relay and on domoticz icons is read state from node fine but problem is when I wont turn "on" or "off" light or relay from domoticz

          This is found in several threads in this forum. Its most probably a ack issue, Domoticz needs a ack back from the node that it has been turned on/off but this does not reach back to the gateway. Follow the logs in gateway and node and you will see.

          You need to treat this problem like a radio issue, either you need more range or it can also be a power issue with the radio making it fail.

          Controller: Proxmox VM - Home Assistant
          MySensors GW: Arduino Uno - W5100 Ethernet, Gw Shield Nrf24l01+ 2,4Ghz
          MySensors GW: Arduino Uno - Gw Shield RFM69, 433mhz
          RFLink GW - Arduino Mega + RFLink Shield, 433mhz

          1 Reply Last reply
          0
          • J Offline
            J Offline
            jacek
            wrote on last edited by jacek
            #5

            Thank you for answers.
            I do something like this:
            I clear the code from parts whitch use RELAY but in domoticz I do not delete RELAY switch

             /* 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>
            #include <DallasTemperature.h>
            #include <OneWire.h>
            
            #define COMPARE_TEMP 1 // Send temperature only if changed? 1 = Yes 0 = No
            #define ONE_WIRE_BUS 19 // Pin where dallase sensor is connected 
            #define MAX_ATTACHED_DS18B20 1
            OneWire oneWire(ONE_WIRE_BUS); // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
            DallasTemperature sensors(&oneWire); // Pass the oneWire reference to Dallas Temperature. 
            
            #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 photoPin A6         // Fotorezystor 
            #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 16
            #define ID 15
            #define EEPROM_DIM_LEVEL_LAST 1
            #define EEPROM_DIM_LEVEL_SAVE 2
            
            #define LIGHT_OFF 0
            #define LIGHT_ON 1
            
            ////WENT
            //#define WENT_RELAY_PIN  17  // Arduino Digital I/O pin number for relay 
            //#define WENT_BUTTON_PIN  18  // Arduino Digital I/O pin number for button 
            //#define CHILD_ID_WENT 17   // Id of the sensor child
            //#define RELAY_ON 1
            //#define RELAY_OFF 0
            //
            ////END
            
            int dimValue;
            int fadeTo;
            int fadeDelta;
            int persons;
            byte oldButtonVal;
            bool changedByKnob=false;
            bool sendDimValue=false;
            unsigned long lastFadeStep;
            unsigned long sendDimTimeout;
            char convBuffer[10];
            
            float lastTemperature[MAX_ATTACHED_DS18B20];
            int numSensors=0;
            boolean receivedConfig = false;
            boolean metric = true;
            
            unsigned long on = 0;
            unsigned long onT = 0;
            
            MySensor gw;
            
            // Initialize temperature message
            MyMessage msg(0,V_TEMP);
            MyMessage dimmerMsg(CHILD_ID_LIGHT, V_DIMMER);
            MyMessage msgl(0, V_LIGHT_LEVEL);
            
            ////WENT
            //MyMessage msgW(CHILD_ID_WENT,V_ARMED);
            //Bounce debouncer2 = Bounce(); 
            //int oldValue=0;
            //bool state;
            ////END
            Encoder knob(KNOB_ENC_PIN_1, KNOB_ENC_PIN_2);  
            Bounce debouncer = Bounce(); 
            int lastLightLevel;
            
            void setup()  
            { 
              
               // The third argument enables repeater mode.
            //  gw.begin(NULL, AUTO, true);
            
              //Send the sensor node sketch version information to the gateway
             // gw.sendSketchInfo("Repeater Node", "1.0");
            
            
              
              // Set knob button pin as input (with debounce)
              pinMode(KNOB_BUTTON_PIN, INPUT);
              pinMode(photoPin, 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, ID, true);
            
              // Send the Sketch Version Information to the Gateway
              gw.present(CHILD_ID_LIGHT, S_DIMMER);
              
              gw.sendSketchInfo(SN, SV);
              gw.sendSketchInfo("Repeater Node", "1.0");
              // Retreive our last dim levels from the eprom
              fadeTo = dimValue = 0;
              byte oldLevel = 0;
              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..."); 
            
               // Startup up the OneWire library
              sensors.begin();
              // requestTemperatures() will not block current thread
              sensors.setWaitForConversion(false);
              // Fetch the number of attached temperature sensors  
              numSensors = sensors.getDeviceCount();
            
              // Present all sensors to controller
              for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) {   
                 gw.present(i, S_TEMP);
                 
              }
              gw.present(15, S_LIGHT_LEVEL);
            //  //WENT
            //  
            //// Send the sketch version information to the gateway and Controller
            //  gw.sendSketchInfo("Relay & Button", "1.0");
            //
            // // Setup the button
            //  pinMode(WENT_BUTTON_PIN,INPUT);
            //  // Activate internal pull-up
            //  digitalWrite(WENT_BUTTON_PIN,HIGH);
            //  
            //  // After setting up the button, setup debouncer
            //  debouncer2.attach(WENT_BUTTON_PIN);
            //  debouncer2.interval(4);
            //
            //  // Register all sensors to gw (they will be created as child devices)
            //  gw.present(CHILD_ID_WENT, V_ARMED);
            //
            //  // Make sure relays are off when starting up
            //  digitalWrite(WENT_RELAY_PIN, RELAY_OFF);
            //  // Then set relay pins in output mode
            //  pinMode(WENT_RELAY_PIN, OUTPUT);   
            //      
            //  // Set relay to last known state (using eeprom storage) 
            //  state = gw.loadState(CHILD_ID_WENT);
            //  digitalWrite(WENT_RELAY_PIN, state?RELAY_ON:RELAY_OFF);
            //  //END
            }
            
            void loop()      
            {
              // Process incoming messages (like config and light state from controller)
              gw.process();
            ////WENT
            //
            //debouncer2.update();
            //  // Get the update value
            //  int value = debouncer2.read();
            //  if (value != oldValue && value==0) {
            //      gw.send(msgW.set(state?false:true), true); // Send new state and request ack back
            //  }
            //  oldValue = value;
            ////END
              // Sprawdzenie temperatury
              CheckTemp();
              onT = onT + 1;
              on = on + 1;
              if (on > 401 + 2*ID) {
              // Poziom swiata
              lightLevel();
              on = 0;
              }
            
              if (analogRead(photoPin) > 350) { persons = 0;} else {persons = 1;}
                
              // Check if someone has pressed the knob button
              checkButtonClick();
              
              // Fade light to new dim value
              fadeStep();
            }
            
            
            
            void lightLevel()
            {
            int lightLevel = (analogRead(photoPin)); 
              Serial.println(lightLevel);
              if (lightLevel != lastLightLevel) {
                  gw.send(msgl.set(lightLevel));
                  lastLightLevel = lightLevel;
              }
            }
            
            
            void CheckTemp()
            {
            
            // Fetch temperatures from Dallas sensors
              sensors.requestTemperatures();
              
              // Read temperatures and send them to controller 
              for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) {
             
                // Fetch and round temperature to one decimal
                float temperature = static_cast<float>(static_cast<int>((gw.getConfig().isMetric?sensors.getTempCByIndex(i):sensors.getTempFByIndex(i)) * 10.)) / 10.;
             
                // Only send data if temperature has changed and no error
                #if COMPARE_TEMP == 1
                if (lastTemperature[i] != temperature && temperature != -127.00 && temperature != 85.00) {
                #else
                if (temperature != -127.00 && temperature != 85.00) {
                #endif
                  
                      if (onT > 400 + 2*ID) {
                  // Send in the new temperature
                  gw.send(msg.setSensor(i).set(temperature,1));
                     onT = 0; }
                  // Save new temperatures for next compare
                  lastTemperature[i]=temperature;
                }
              }
              
            }
            
            
            
            
            void incomingMessage(const MyMessage &message)
            {
              
            //    //WENT
            // // We only expect one type of message from controller. But we better check anyway.
            //  if (message.isAck()) {
            //     Serial.println("This is an ack from gateway");
            //  }
            //
            //  if (message.type == V_ARMED) {
            //     // Change relay state
            //     state = message.getBool();
            //     digitalWrite(WENT_RELAY_PIN, state?RELAY_ON:RELAY_OFF);
            //     // Store state in eeprom
            //     gw.saveState(CHILD_ID_WENT, state);
            //    
            //     // Write some debug info
            //     Serial.print("Incoming change for sensor:");
            //     Serial.print(message.sensor);
            //     Serial.print(", New status: ");
            //     Serial.println(message.getBool());
            //   } 
            //  //END
              if (analogRead(photoPin) > 350) { persons = 0;} else {persons = 1;}
              if (message.type == V_LIGHT && persons == 1) {
                // 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 && persons == 1) {
                // 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);
              }
             if (persons == 1){
                   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();
            } else if (persons == 0){
              if (message.getString() != 0) 
                      {gw.send(dimmerMsg.set(0), true);}
               else
                      {return;}  
            
             }
            }
            
            
            void checkButtonClick()
            {
            if ( persons == 1 ) {
              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);
                 int saved = 100;
                  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));
            }
            
            

            and Domoticz:

            Domoticz

            When I send from domoticz turn "on" or "off" Relay domoticz send to node and to child_id 17 but node send do domoticz reck to child_id 16

            read: 0-1-15 s=17,c=1,t=2,pt=0,l=1,sg=0:1
            send: 15-15-1-0 s=16,c=1,t=3,pt=2,l=2,sg=0,st=ok:100
            read: 0-1-15 s=16,c=1,t=3,pt=2,l=2,sg=0:100
            

            and if we send from domoticz do child_id 16 answers is OK

            read: 0-1-15 s=16,c=1,t=2,pt=0,l=1,sg=0:0
            send: 15-15-1-0 s=16,c=1,t=3,pt=2,l=2,sg=0,st=ok:0
            read: 0-1-15 s=16,c=1,t=3,pt=2,l=2,sg=0:0
            
            1 Reply Last reply
            0
            • sundberg84S Offline
              sundberg84S Offline
              sundberg84
              Hardware Contributor
              wrote on last edited by sundberg84
              #6

              Do you need two childs, one for dimmer and one for on/off? I dont think so. Either its a dimmer where 0% is off or its a switch.

              Controller: Proxmox VM - Home Assistant
              MySensors GW: Arduino Uno - W5100 Ethernet, Gw Shield Nrf24l01+ 2,4Ghz
              MySensors GW: Arduino Uno - Gw Shield RFM69, 433mhz
              RFLink GW - Arduino Mega + RFLink Shield, 433mhz

              1 Reply Last reply
              0
              • J Offline
                J Offline
                jacek
                wrote on last edited by jacek
                #7

                OK thanks everyone for help, this is code witch works very well:

                Only I must add the line where the light will be turn "off" when light level will be > 350 after 5 minutes.

                 
                #include <SPI.h>
                #include <Encoder.h>
                #include <MySensor.h>  
                #include <Bounce2.h>
                #include <DallasTemperature.h>
                #include <OneWire.h>
                
                #define COMPARE_TEMP 1 // Send temperature only if changed? 1 = Yes 0 = No
                #define ONE_WIRE_BUS 19 // Pin where dallase sensor is connected 
                #define MAX_ATTACHED_DS18B20 1
                OneWire oneWire(ONE_WIRE_BUS); // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
                DallasTemperature sensors(&oneWire); // Pass the oneWire reference to Dallas Temperature. 
                
                #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 photoPin A6         // Fotorezystor 
                #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 16
                #define ID 15
                #define EEPROM_DIM_LEVEL_LAST 1
                #define EEPROM_DIM_LEVEL_SAVE 2
                
                #define LIGHT_OFF 0
                #define LIGHT_ON 1
                
                //WENT
                //#define WENT_RELAY_PIN  17  // Arduino Digital I/O pin number for relay 
                //#define WENT_BUTTON_PIN  18  // Arduino Digital I/O pin number for button 
                //#define CHILD_ID_WENT 17   // Id of the sensor child
                #define RELAY_ON 1
                #define RELAY_OFF 0
                
                #define noRelays 1
                const int relayPin[] = {17};          //  switch around pins to your desire
                const int buttonPin[] = {18};      //  switch around pins to your desire
                
                class Relay             // relay class, store all relevant data (equivalent to struct)
                {
                public:                                      
                  int buttonPin;                   // physical pin number of button
                  int relayPin;             // physical pin number of relay
                  byte oldValue;                    // last Values for key (debounce)
                  boolean relayState;               // relay status (also stored in EEPROM)
                };
                
                
                //END
                
                int dimValue;
                int fadeTo;
                int fadeDelta;
                int persons;
                byte oldButtonVal;
                bool changedByKnob=false;
                bool sendDimValue=false;
                unsigned long lastFadeStep;
                unsigned long sendDimTimeout;
                char convBuffer[10];
                
                float lastTemperature[MAX_ATTACHED_DS18B20];
                int numSensors=0;
                boolean receivedConfig = false;
                boolean metric = true;
                
                unsigned long on = 0;
                unsigned long onT = 0;
                
                MySensor gw;
                
                // Initialize temperature message
                MyMessage msg(0,V_TEMP);
                MyMessage dimmerMsg(CHILD_ID_LIGHT, V_DIMMER);
                MyMessage msgl(0, V_LIGHT_LEVEL);
                
                //WENT
                Relay Relays[noRelays]; 
                Bounce debouncer1[noRelays];
                MyMessage msg1[noRelays];
                //END
                Encoder knob(KNOB_ENC_PIN_1, KNOB_ENC_PIN_2);  
                Bounce debouncer = Bounce(); 
                int lastLightLevel;
                
                void setup()  
                { 
                  
                   // The third argument enables repeater mode.
                //  gw.begin(NULL, AUTO, true);
                
                  //Send the sensor node sketch version information to the gateway
                 // gw.sendSketchInfo("Repeater Node", "1.0");
                
                
                  
                  // Set knob button pin as input (with debounce)
                  pinMode(KNOB_BUTTON_PIN, INPUT);
                  pinMode(photoPin, 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, ID, true);
                
                  // Send the Sketch Version Information to the Gateway
                  gw.present(CHILD_ID_LIGHT, S_DIMMER);
                  
                  gw.sendSketchInfo(SN, SV);
                  gw.sendSketchInfo("Repeater Node", "1.0");
                  // Retreive our last dim levels from the eprom
                  fadeTo = dimValue = 0;
                  byte oldLevel = 0;
                  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..."); 
                
                   // Startup up the OneWire library
                  sensors.begin();
                  // requestTemperatures() will not block current thread
                  sensors.setWaitForConversion(false);
                  // Fetch the number of attached temperature sensors  
                  numSensors = sensors.getDeviceCount();
                
                  // Present all sensors to controller
                  for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) {   
                     gw.present(i, S_TEMP);
                     
                  }
                  gw.present(15, S_LIGHT_LEVEL);
                  //WENT
                 gw.sendSketchInfo("MultiRelayButton", "0.9b");
                    delay(250);
                
                    // Initialize Relays with corresponding buttons
                    for (int i = 0; i < noRelays; i++){
                    Relays[i].buttonPin = buttonPin[i];              // assign physical pins
                    Relays[i].relayPin = relayPin[i];
                    msg1[i].sensor = i;                                   // initialize messages
                    msg1[i].type = V_LIGHT;
                    debouncer1[i] = Bounce();                        // initialize debouncer
                    debouncer1[i].attach(buttonPin[i]);
                    debouncer1[i].interval(5);
                    pinMode(Relays[i].buttonPin, INPUT_PULLUP);
                    pinMode(Relays[i].relayPin, OUTPUT);
                    Relays[i].relayState = gw.loadState(i);                               // retrieve last values from EEPROM
                    digitalWrite(Relays[i].relayPin, Relays[i].relayState? RELAY_ON:RELAY_OFF);   // and set relays accordingly
                    gw.send(msg1[i].set(Relays[i].relayState? true : false));                  // make controller aware of last status
                    gw.present(i, S_LIGHT);                               // present sensor to gateway
                    delay(250);
                
                    }
                  //END
                }
                
                void loop()      
                {
                  // Process incoming messages (like config and light state from controller)
                  gw.process();
                //WENT
                for (byte i = 0; i < noRelays; i++){
                    debouncer1[i].update();
                    byte value = debouncer1[i].read();
                    if (value != Relays[i].oldValue && value == 0){
                    Relays[i].relayState = !Relays[i].relayState;
                    digitalWrite(Relays[i].relayPin, Relays[i].relayState?RELAY_ON:RELAY_OFF);
                    gw.send(msg1[i].set(Relays[i].relayState? true : false));
                    gw.saveState( i, Relays[i].relayState );}                 // save sensor state in EEPROM (location == sensor number)
                    
                        Relays[i].oldValue = value;
                        
                    }
                //END
                  // Sprawdzenie temperatury
                  CheckTemp();
                  onT = onT + 1;
                  on = on + 1;
                  if (on > 401 + 2*ID) {
                  // Poziom swiata
                  lightLevel();
                  on = 0;
                  }
                
                  if (analogRead(photoPin) > 350) { persons = 0;} else {persons = 1;}
                    
                  // Check if someone has pressed the knob button
                  checkButtonClick();
                  
                  // Fade light to new dim value
                  fadeStep();
                }
                
                
                
                void lightLevel()
                {
                int lightLevel = (analogRead(photoPin)); 
                  Serial.println(lightLevel);
                  if (lightLevel != lastLightLevel) {
                      gw.send(msgl.set(lightLevel));
                      lastLightLevel = lightLevel;
                  }
                }
                
                
                void CheckTemp()
                {
                
                // Fetch temperatures from Dallas sensors
                  sensors.requestTemperatures();
                  
                  // Read temperatures and send them to controller 
                  for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) {
                 
                    // Fetch and round temperature to one decimal
                    float temperature = static_cast<float>(static_cast<int>((gw.getConfig().isMetric?sensors.getTempCByIndex(i):sensors.getTempFByIndex(i)) * 10.)) / 10.;
                 
                    // Only send data if temperature has changed and no error
                    #if COMPARE_TEMP == 1
                    if (lastTemperature[i] != temperature && temperature != -127.00 && temperature != 85.00) {
                    #else
                    if (temperature != -127.00 && temperature != 85.00) {
                    #endif
                      
                          if (onT > 400 + 2*ID) {
                      // Send in the new temperature
                      gw.send(msg.setSensor(i).set(temperature,1));
                         onT = 0; }
                      // Save new temperatures for next compare
                      lastTemperature[i]=temperature;
                    }
                  }
                  
                }
                
                
                
                
                void incomingMessage(const MyMessage &message)
                {// if (message.sensor == 17){ 
                     
                //} else {
                  if (analogRead(photoPin) > 350) { persons = 0;} else {persons = 1;}
                  if (message.type == V_LIGHT && persons == 1 && message.sensor == 16) {
                    // 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 && persons == 1  && message.sensor == 16) {
                    // 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);
                  }
                 if (persons == 1  && message.sensor == 16){
                       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();
                } else if (persons == 0){
                  if (message.getString() != 0) 
                          {gw.send(dimmerMsg.set(0), true);}
                   else
                          {return;}  
                
                 }
                
                 //WENT
                
                 if (message.type == V_LIGHT){ 
                        if (message.sensor <noRelays){            // check if message is valid for relays..... previous line  [[[ if (message.sensor <=noRelays){ ]]]
                        Relays[message.sensor].relayState = message.getBool(); 
                        digitalWrite(Relays[message.sensor].relayPin, Relays[message.sensor].relayState? RELAY_ON:RELAY_OFF); // and set relays accordingly
                        gw.saveState( message.sensor, Relays[message.sensor].relayState ); // save sensor state in EEPROM (location == sensor number)
                        }
                    }
                  //END
                 
                }//}
                
                
                void checkButtonClick()
                {
                if ( persons == 1 ) {
                  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);
                     int saved = 100;
                      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
                Reply
                • Reply as topic
                Log in to reply
                • Oldest to Newest
                • Newest to Oldest
                • Most Votes


                17

                Online

                11.7k

                Users

                11.2k

                Topics

                113.1k

                Posts


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