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. OpenHardware.io
  3. 💬 MySensors Cover Node

💬 MySensors Cover Node

Scheduled Pinned Locked Moved OpenHardware.io
rollershuttermysensorhlk-pm01nrf24l01
5 Posts 5 Posters 2.2k Views 4 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.
  • openhardware.ioO Offline
    openhardware.ioO Offline
    openhardware.io
    wrote on last edited by openhardware.io
    #1

    https://www.openhardware.io/view/464/MySensors-Cover-Node

    1 Reply Last reply
    0
    • P Offline
      P Offline
      ppenguin
      wrote on last edited by
      #2

      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.

      1 Reply Last reply
      0
      • jeremushkaJ Offline
        jeremushkaJ Offline
        jeremushka
        wrote on last edited by
        #3

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

        1 Reply Last reply
        0
        • TmasterT Offline
          TmasterT Offline
          Tmaster
          wrote on last edited by Tmaster
          #4

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

          i'm a arduino fan .Even sometimes don't undestanding how to use it :P

          1 Reply Last reply
          0
          • Filip KoÅ›nyF Offline
            Filip KośnyF Offline
            Filip Kośny
            wrote on last edited by
            #5

            Hi guys,
            I've made MySensors node based on that sketch, but I can't figure out, how to send V_VAR message from Home Assistant to set rollTime. Any ideas? I'm interested in UI number_input or something simmilar.

            1 Reply Last reply
            0
            Reply
            • Reply as topic
            Log in to reply
            • Oldest to Newest
            • Newest to Oldest
            • Most Votes


            19

            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