💬 MySensors Cover Node





  • Really cool, I just started (was about to) my first bare atmega328-pu project with exactly the same goal, after having it working with arduino pro mini.
    I understand you also have headers for input pins, if made high it manually switches the relays?
    Any plans for including more relays? My goal was to integrate 2-3 double relays, which I need for at least one node.



  • Hello, interesting project. I am looking for some relays 10A, but i do not find under 5VDC. Where did you buy them ?



  • hello guys. i changed @dpressle scketch for work with our South European shutters. that means now work with a standard shutter mechanical wall switch, without stop ,and 2 relays ,one for up ,one for down and all shutter motors have mechanic limits/stoppers embedded,So i don't pay much attention to calibrate or have exact stop time. I removed the calibration code and i add manually the exact time that windows shutter take to open +1sec (for be sure it reach mechanical limit).
    Stop is now on release(fall) any key from the mechanical switch(up or down), and in power fail case ,it stays were it was left and start counting up or down from there.

    Unfortunately if you use Domoticz ,percentage appear be not supported... And without any v_status on code,appear that domoticz don't know if state is open or close,but respond to close and open and stop like blind switch/sensor.

    // Enable debug prints to serial monitor
    #define MY_DEBUG
    
    // Enable and select radio type attached
    #define MY_RADIO_RFM69
    
    //#define MY_RF24_PA_LEVEL RF24_PA_LOW
    
    //#define MY_REPEATER_FEATURE
    
    
    
    #include <Bounce2.h>
    #include <MySensors.h>
    #include <SPI.h>
    
    // uncomment if we want to manually assign an ID
    //#define MY_NODE_ID 1 /
    
    #define BUTTON_UP_PIN 5  // Arduino Digital I/O pin number for up button
    #define BUTTON_DOWN_PIN 6  // Arduino Digital I/O pin number for down button
    //#define BUTTON_STOP_PIN 7  // Arduino Digital I/O pin number for stop button
    #define RELAY_UP_PIN 3  // Arduino Digital I/O pin number for direction relay
    #define RELAY_DOWN_PIN 4  // Arduino Digital I/O pin number for power relay
    #define RELAY_ON 0
    #define RELAY_OFF 1
    //#define RELAY_DOWN 1
    //#define RELAY_UP 0
    #define DIRECTION_DOWN 1
    #define DIRECTION_UP 0
    #define SKETCH_NAME "Cover"
    #define SKETCH_VER "2.0"
    #define CHILD_ID_COVER 0   // sensor Id of the sensor child
    #define STATE_UP 100 // 100 is open - up
    #define STATE_DOWN 0 // 0 is closed - down
    //#define CHILD_ID_CALIBRATE 1   // sensor Id of the sensor child to calibrate
    #define CHILD_ID_SET 1   // sensor Id of the sensor child to init the roll time
    #define PRESENT_MESSAGE "shuttle for Livingroom"
    const int LEVELS = 100; //the number of levels
    float rollTime = 28.0; //the overall rolling time of the shutter
    const bool IS_ACK = false; //is to acknowlage
    static bool initial_state_sent = false;//for hass we need at list one state send at begining
    
    // debouncing parameters
    int value = 0;
    int oldValueUp = 0;
    int oldValueDown = 0;
    //int value1=0;int value2=0;
    int oldValueStop=0;
    int oldValueStop1=0;
    //static unsigned long last_interrupt_time_up = 0;
    //static unsigned long last_interrupt_time_down = 0;
    //static unsigned long debounce_time = 200;
    
    Bounce debouncerUp = Bounce();
    Bounce debouncerDown = Bounce();
    //Bounce debouncerStop = Bounce();
    
    // shutter position parameters
    float timeOneLevel = rollTime / LEVELS;
    int requestedShutterLevel = 0;
    int currentShutterLevel = 0;
    unsigned long lastLevelTime = 0;
    bool isMoving = false;
    int directionUpDown;
    
    enum CoverState {
      STOP,
     UP, // Window covering. Up.
      DOWN, // Window covering. Down.
    };
    
    static int coverState = STOP;
    
    MyMessage msgUP(CHILD_ID_COVER, V_UP);
    MyMessage msgDown(CHILD_ID_COVER, V_DOWN);
    MyMessage msgStop(CHILD_ID_COVER, V_STOP);
    MyMessage msgPercentage(CHILD_ID_COVER, V_PERCENTAGE);
    
    
    void sendState() {
      // Send current state and status to gateway.
      send(msgUP.set(coverState == UP));
      send(msgDown.set(coverState == DOWN));
      send(msgStop.set(coverState == STOP));
      send(msgPercentage.set(currentShutterLevel));
    }
    
    void shuttersUp(void) {
    #ifdef MY_DEBUG
      Serial.println("Shutters going up");
    #endif
      if (digitalRead(RELAY_DOWN_PIN) == RELAY_ON) {
          digitalWrite(RELAY_DOWN_PIN, RELAY_OFF);
          delay(100);
      }
      digitalWrite(RELAY_UP_PIN, RELAY_ON);
     
    
      directionUpDown = DIRECTION_UP;
      isMoving = true;
      coverState = UP;
      sendState();
    }
    
    void shuttersDown(void) {
    #ifdef MY_DEBUG
      Serial.println("Shutters going down");
    #endif
      if (digitalRead(RELAY_UP_PIN) ==  RELAY_ON) {
         digitalWrite(RELAY_UP_PIN, RELAY_OFF);
         delay(100);
      }
      digitalWrite(RELAY_DOWN_PIN, RELAY_ON);
      
    
      directionUpDown = DIRECTION_DOWN;
      isMoving = true;
      coverState = DOWN;
      sendState();
    }
    
    void shuttersHalt(void) {
    #ifdef MY_DEBUG
      Serial.println("Shutters halted X");
    #endif
        digitalWrite(RELAY_UP_PIN, RELAY_OFF);
        digitalWrite(RELAY_DOWN_PIN, RELAY_OFF);
        delay(100);
       //}
    
      isMoving = false;
      requestedShutterLevel = currentShutterLevel;
    #ifdef MY_DEBUG
      Serial.println("saving state to: ");
      Serial.println(String(currentShutterLevel));
    #endif
      saveState(CHILD_ID_COVER, currentShutterLevel);
      coverState = STOP;
      //sendState();
    }
    
    void changeShuttersLevel(int level) {
      int dir = (level > currentShutterLevel) ? DIRECTION_UP : DIRECTION_DOWN;
      if (isMoving && dir != directionUpDown) {
        shuttersHalt();
      }
      requestedShutterLevel = level;
    }
    
    void receive(const MyMessage &message) {
    #ifdef MY_DEBUG
      Serial.println("recieved incomming message");
      Serial.println("Recieved message for sensor: ");
      Serial.println(String(message.sensor));
      Serial.println("Recieved message with type: ");
      Serial.println(String(message.type));
    #endif
      if (message.sensor == CHILD_ID_COVER) {
        switch (message.type) {
          case V_UP:
            //Serial.println(", New status: V_UP");
            changeShuttersLevel(STATE_UP);
           
            break;
    
          case V_DOWN:
            //Serial.println(", New status: V_DOWN");
            changeShuttersLevel(STATE_DOWN);
           
            break;
    
          case V_STOP:
            //Serial.println(", New status: V_STOP");
            shuttersHalt();
       
            break;
    
          case V_PERCENTAGE:
    
            int per = message.getInt();
            if (per > STATE_UP) {
              per = STATE_UP;
            }
            changeShuttersLevel(per);
            
            break;
        }
      } 
    
    #ifdef MY_DEBUG
      Serial.println("exiting incoming message");
    #endif
      return;
    }
    
    void before() {
    
      // Setup the button
      pinMode(BUTTON_UP_PIN, INPUT_PULLUP);
      // Activate internal pull-up
      digitalWrite(BUTTON_UP_PIN, HIGH);
      
      pinMode(BUTTON_DOWN_PIN, INPUT_PULLUP);
      // Activate internal pull-up
      digitalWrite(BUTTON_DOWN_PIN, HIGH);
     
      // After setting up the button, setup debouncer
      debouncerUp.attach(BUTTON_UP_PIN);
      debouncerUp.interval(5);
      // After setting up the button, setup debouncer
      debouncerDown.attach(BUTTON_DOWN_PIN);
      debouncerDown.interval(5);
      // Make sure relays are off when starting up
      digitalWrite(RELAY_UP_PIN, RELAY_OFF);
      // Then set relay pins in output mode
      pinMode(RELAY_UP_PIN, OUTPUT);
    
      // Make sure relays are off when starting up
      digitalWrite(RELAY_DOWN_PIN, RELAY_OFF);
      // Then set relay pins in output mode
      pinMode(RELAY_DOWN_PIN, OUTPUT);
    }
    
    void presentation() {
      // Send the sketch version information to the gateway and Controller
      sendSketchInfo(SKETCH_NAME, SKETCH_VER);
      // Register all sensors to gw (they will be created as child devices)
      present(CHILD_ID_COVER, S_COVER, PRESENT_MESSAGE, IS_ACK);
      //present(CHILD_ID_SET, S_CUSTOM);
    }
    
    void setup(void) {
      
      int state = loadState(CHILD_ID_COVER);
    
    #ifdef MY_DEBUG
      Serial.println("getting state from eeprom: ");
      Serial.println(String(state));
    #endif
      currentShutterLevel=state;
      changeShuttersLevel(state);
      
    }
    
    
    void loop(void) {
      
       if (!initial_state_sent) {
    #ifdef MY_DEBUG
        Serial.println("Sending initial value");
    #endif
        sendState();
        
      
        initial_state_sent = true;
       
      } 
    
      debouncerUp.update();
      value = debouncerUp.read();
      if (value == 0 && value != oldValueUp) {
        changeShuttersLevel(STATE_UP);
      }
      oldValueUp = value;
    
      debouncerDown.update();
      value = debouncerDown.read();
      if (value == 0 && value != oldValueDown) {
        changeShuttersLevel(STATE_DOWN);
       }
      oldValueDown = value;
    
      value = debouncerUp.rose();
       if ((value == 0) && (value != oldValueStop) &&(isMoving==true)){
       shuttersHalt();
       }
       oldValueStop = value;
       
      value = debouncerDown.rose();
        if ((value) == 0 && (value != oldValueStop1)&&(isMoving==true)){
        
        shuttersHalt();
       }
        oldValueStop1 = value;
    
    
      if (isMoving) {
        unsigned long _now = millis();
        if (_now - lastLevelTime >= timeOneLevel * 1000) {
          if (directionUpDown == DIRECTION_UP) {
            currentShutterLevel += 1;
          } else {
            currentShutterLevel -= 1;
          }
    #ifdef MY_DEBUG
          //Serial.println(String(requestedShutterLevel));
          Serial.println(String(currentShutterLevel));
    #endif
          lastLevelTime = millis();
          //send(msgPercentage.set(currentShutterLevel));
        }
    
        
        if (currentShutterLevel == requestedShutterLevel){
          shuttersHalt();
        }
      } 
      else if (requestedShutterLevel != currentShutterLevel) {
        if (requestedShutterLevel > currentShutterLevel) {
          shuttersUp();
        }
        else {
          shuttersDown();
        }
        lastLevelTime = millis();
      }
    }
    

 

174
Online

8.6k
Users

9.4k
Topics

99.5k
Posts