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. Curtain Control Node.

Curtain Control Node.

Scheduled Pinned Locked Moved My Project
domoticzcurtain controlmysensors node
51 Posts 15 Posters 20.0k Views 22 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.
  • barduinoB barduino

    @Suresh-Mali

    I'm just curious, maybe its the arduino IDE version or something.

    I'm using 1.6.4 and I get this:

    0_1458129604092_upload-1364c257-d6a3-46d0-bdec-ff24cf9d2b41

    However opening with a text editor is fine:

    0_1458129652911_upload-e1883418-162b-4aba-bacf-d3e85436cca7

    Cheers

    Suresh MaliS Offline
    Suresh MaliS Offline
    Suresh Mali
    wrote on last edited by
    #12

    @barduino Seems like the IDE. Open any example MySensors Sketch. Delete the contents from sketch and copy paste from my sketch. I guess that should work.

    Are you able to compile any other sketch in Arduino?

    1 Reply Last reply
    0
    • P Offline
      P Offline
      patchmaster
      wrote on last edited by
      #13

      @AWI Are you able to share the sketch you used with the UL2003 driver board? I have tried to combine the MySensors servo sketch with other arduino only sketches utilizing the UL2003, but without luck. Thanks.

      Suresh MaliS AWIA 2 Replies Last reply
      0
      • P patchmaster

        @AWI Are you able to share the sketch you used with the UL2003 driver board? I have tried to combine the MySensors servo sketch with other arduino only sketches utilizing the UL2003, but without luck. Thanks.

        Suresh MaliS Offline
        Suresh MaliS Offline
        Suresh Mali
        wrote on last edited by
        #14

        @patchmaster I used the relay sketch and modified it to my needs. Sorry but I dont have any sketch for ULN2003. :disappointed:

        1 Reply Last reply
        0
        • P patchmaster

          @AWI Are you able to share the sketch you used with the UL2003 driver board? I have tried to combine the MySensors servo sketch with other arduino only sketches utilizing the UL2003, but without luck. Thanks.

          AWIA Offline
          AWIA Offline
          AWI
          Hero Member
          wrote on last edited by
          #15

          @patchmaster This is my current curtain control sketch. I work with the development branch, so the syntax can be a little different.

          The Accelstepper library gives you all the abilities to slow start/stop with numerous kinds of steppers.
          My sketch includes a calibration function (stored in EEPROM) so the you don't need end stop detection (a stepper knows where it is)

          /*
           PROJECT: MY Sensors curtain controller
           PROGRAMMER: AWI
           DATE: march 11, 2016
           FILE: AWI stepper1.ino
           LICENSE: Public domain
          
           Hardware: ATMega328p board w/ NRF24l01
          	and MySensors 2.0 (Development)
          		
          Special:
          	uses AccelStepper library
          	
          Summary:
          	Curtain control with stepper motor. 
          	Manual operation with 1 push button 
          	Calibration with manual button
          
          Remarks:
          	Fixed node-id
          	
          Change log:
          20160312 - Cleanup
          */
          
          // Enable debug prints to serial monitor
          #define MY_DEBUG 
          
          #define MY_NODE_ID 13											// fixed node number
          // Enable and select radio type attached
          #define MY_RADIO_NRF24
          //#define MY_RADIO_RFM69
          
          #include <SPI.h>
          #include <MySensor.h> 
          
          // stepper library
          #include <AccelStepper.h>										// http://www.airspayce.com/mikem/arduino/AccelStepper/
          #define HALFSTEP 8  											// Stepper uses "Halfstep" mode
          
          // button library
          // used for:
          // - manual open close - single click: close/ stop/ open/ stop
          // - calibration  - after long press: open calibarion- until single press - closed calibration - until single press (stop)
          #include <Button.h>												// https://github.com/JChristensen/Button
          
          #define CHILD_ID 1   											// Id of the sensor child
          
          #define SN "Curtain control 13"
          #define SV "1.0"
          
          #define buttonPin1 7  											// Arduino pin connected to buttonPin1
          #define buttonPin2 A0  											// Arduino pin connected to buttonPin2 (fixed to ground)
          
          // Motor pin definitions
          #define motorPin1  3     										// IN1 on the ULN2003 driver 1
          #define motorPin2  4     										// IN2 on the ULN2003 driver 1
          #define motorPin3  5     										// IN3 on the ULN2003 driver 1
          #define motorPin4  6     										// IN4 on the ULN2003 driver 1
          
          const unsigned long heartbeatInterval = 1 * 3600UL * 1000UL ;	// heartbeatinterval
          unsigned long heartbeatCounter = 0 ;
          
          //
          // helper routines to store and retrieve long in mysensors EEPROM
          union {															// used to convert long to bytes for EEPROM storage
          	long longInt;
          	uint8_t LongByte[4];
          	} convLongInt ;
          
          void saveStateL(int EEposition, long StateL){
          	convLongInt.longInt = StateL ;
          	for (int y = 0; y < 4 ; y++){								// convert to bytes
          		saveState(EEposition + y , convLongInt.LongByte[y]) ;
          		}
          	Serial.print("State saved: "); Serial.println(StateL);
          	}
          		
          long loadStateL(int EEposition){
          	for (int y = 0; y < 4 ; y++){								// convert from bytes
          		convLongInt.LongByte[y] = loadState(EEposition + y) ;
          		}
          	Serial.print("State read: "); Serial.println(convLongInt.longInt);
          	return convLongInt.longInt ;
          	}
          	
          
          // Initialize with pin sequence IN1-IN3-IN2-IN4 for using the AccelStepper with 28BYJ-48
          AccelStepper stepper1(HALFSTEP, motorPin1, motorPin3, motorPin2, motorPin4);
          // Initialize button active low, debounce and internal pull-up
          Button myBtn(buttonPin1, true, true, 40);						// Initiate the button (pin, pull_up, invert, debounce_ms)
          
          MyMessage percentageMsg(CHILD_ID, V_PERCENTAGE);				// used to send updates to controller
          
          const long maxRun = 4000000L ;									// maximum runway
          long setPosition = 0 ; 											// remembers set position, need to be saved in EEPROM
          const int setPositionEE = 4 ;									// eeprom location
          long openPosition = 0 ; 										// Position at open, need to be saved in EEPROM?
          const int openPositionEE = setPositionEE + 4 ;					// eeprom location
          long closedPosition = 120000UL ; 								// Position at full close, need to be saved in EEPROM
          const int closedPositionEE = openPositionEE + 4 ;				// eeprom location
          
          unsigned long idleTimer = millis() ;							// return to idle timer
          unsigned long idleTime = 100000UL ;								// return to idle after 100 secs
          
          unsigned long printTimer = millis() ;							// print timer
          unsigned long printTime = 1000UL ;								// print after 1 secs
          
          enum position_t {Open, Close, Idle, Running} ;
          position_t lastDirection = Open ; 								// lastDirection only for buttonpress
          position_t runStatus = Idle ;									// indicates current status for running motor. used for status reporting to controller
          
          enum State_t {sIdle, sCalibrateOpen, sCalibrateClose} ;
          State_t State = sIdle ;
          
          
          void setup() {
          	// setup buttons
          	pinMode(buttonPin1, OUTPUT);
          	stepper1.setMaxSpeed(2000.0);
          	stepper1.setAcceleration(1000.0);
          	//saveStateL(closedPositionEE, closedPosition) ; 			// INIT: save closed position in EEPROM
          	closedPosition = loadStateL(closedPositionEE) ;				// need to get last values from EEPROM and assume the current position is correct
          	setPosition = loadStateL(setPositionEE) ;
          	stepper1.setCurrentPosition(setPosition );
          }//--(end setup )---
          
          void presentation() {
            present(CHILD_ID, S_COVER, "Curtain");						// Window Cover sub-type, commands: V_UP, V_DOWN, V_STOP
          
            // Register the LED Dimmable Light with the gateway
            sendSketchInfo(SN, SV);
          }
          
          
          void loop() {
          unsigned int now = millis() ;								// current time for loop
          // simple state machine for button press
          	myBtn.read();  
          	switch (State) {
                  // Idle state, waiting for some action
          		// - button press
          		// - idleTimer
                  case sIdle:                
                      if (myBtn.wasReleased()){						// idle
          				Serial.println("Button release") ;
          				// if running stop
          				if (stepper1.isRunning()){
          					setPosition = stepper1.currentPosition();
          					stepper1.moveTo(setPosition) ;			// move to current position (was already there..)
          				} else if (lastDirection == Open) {
          					stepper1.moveTo(closedPosition) ;
          					lastDirection = Close ;
          				} else {									// lastDirection == Close
          					stepper1.moveTo(openPosition) ;
          					lastDirection = Open ;
          				}	
          			} else if (myBtn.pressedFor(3000)){				// move to calibratete state with long press
          				Serial.println("Button press long") ;
          				idleTimer = now ;							// return to idle after ...
          				State = sCalibrateOpen ;
          				stepper1.move(-maxRun) ;					// let the stepper open with maximum
          				}
          			break ;
          		// if not running and last action was open close ;  else open
          		// if longpress Calibrate open
                  case sCalibrateOpen:           						// calibration going on     
          			if (myBtn.wasPressed()){
          				stepper1.setCurrentPosition(0 );		// set new 0 position ??
          				openPosition = setPosition = 0 ;
          				State = sCalibrateClose ;					// next is close calibarion
          				stepper1.move(maxRun) ;						// let the stepper close with maximum
          			} else if (now > idleTimer + idleTime) {		// timer expired -> abort calibration
          				State = sIdle ;
          			}
          			break ;
                  case sCalibrateClose:								// calibrate closed position, end with keypress
          			if (myBtn.wasPressed())	{
          				closedPosition = setPosition = stepper1.currentPosition() ;
          				saveStateL(closedPositionEE, closedPosition) ; // save closed position in EEPROM
          				State = sIdle ;
          				stepper1.moveTo(openPosition) ;				// return to open after calibration
          			} else if (now > idleTimer + idleTime) {		// timer expired -> abort calibration
          				State = sIdle ;
          			}
          			break ;
          		default :
          			break ;
          		}
          	// power off stepper if not running (no need to reenable))
          	if (!stepper1.isRunning()){
          		if (runStatus != Idle){								// there was a change in runningstatus, so report to controller
          			setPosition = stepper1.currentPosition() ;		// store in EEPROM and report ready to controller
          			saveStateL(setPositionEE, setPosition) ;
          			send( percentageMsg.set((100 * setPosition)/(closedPosition - openPosition))) ;
          			runStatus = Idle ;
          		}
          		stepper1.disableOutputs();
          	} else {
          		runStatus = Running ;
          	}
          	stepper1.run();
          	/*
          	if (printTimer++ > now + printTime){
          		printTimer = now ;
          		Serial.println(stepper1.currentPosition());
          		}
          	*/
          }
          
          // This is called when a message is received 
          void receive(const MyMessage &message) {
          // We only expect few types of messages from controller, check which
            switch (message.type) {
          	case V_PERCENTAGE:
          	// Curtain should be opened
          	stepper1.moveTo(message.getInt() * (closedPosition - openPosition)/100);
          	Serial.print("Message: "); Serial.print(message.sensor); Serial.print(" , value: % "); Serial.println( message.getInt());
          	Serial.print("Moving to: "); Serial.println(message.getInt() * (closedPosition - openPosition)/100);
          	break ;
          	case V_STATUS:
          	// Curtain should be opened or closed full
          	stepper1.moveTo((message.getInt() == HIGH)?openPosition:closedPosition);
          	Serial.print("Message - valid: ");
          	Serial.print(message.sensor);
          	Serial.print(" , value: % ");
          	break ;
          	default : 
          	// not recognizable message
          	Serial.print("Message - valid: ");
          	Serial.print(message.sensor);
          	Serial.print(", Unrecognized ");
          	break ;
          	}
            }
            
          
          
          
          
          P Tore André RosanderT A 3 Replies Last reply
          0
          • AWIA AWI

            @patchmaster This is my current curtain control sketch. I work with the development branch, so the syntax can be a little different.

            The Accelstepper library gives you all the abilities to slow start/stop with numerous kinds of steppers.
            My sketch includes a calibration function (stored in EEPROM) so the you don't need end stop detection (a stepper knows where it is)

            /*
             PROJECT: MY Sensors curtain controller
             PROGRAMMER: AWI
             DATE: march 11, 2016
             FILE: AWI stepper1.ino
             LICENSE: Public domain
            
             Hardware: ATMega328p board w/ NRF24l01
            	and MySensors 2.0 (Development)
            		
            Special:
            	uses AccelStepper library
            	
            Summary:
            	Curtain control with stepper motor. 
            	Manual operation with 1 push button 
            	Calibration with manual button
            
            Remarks:
            	Fixed node-id
            	
            Change log:
            20160312 - Cleanup
            */
            
            // Enable debug prints to serial monitor
            #define MY_DEBUG 
            
            #define MY_NODE_ID 13											// fixed node number
            // Enable and select radio type attached
            #define MY_RADIO_NRF24
            //#define MY_RADIO_RFM69
            
            #include <SPI.h>
            #include <MySensor.h> 
            
            // stepper library
            #include <AccelStepper.h>										// http://www.airspayce.com/mikem/arduino/AccelStepper/
            #define HALFSTEP 8  											// Stepper uses "Halfstep" mode
            
            // button library
            // used for:
            // - manual open close - single click: close/ stop/ open/ stop
            // - calibration  - after long press: open calibarion- until single press - closed calibration - until single press (stop)
            #include <Button.h>												// https://github.com/JChristensen/Button
            
            #define CHILD_ID 1   											// Id of the sensor child
            
            #define SN "Curtain control 13"
            #define SV "1.0"
            
            #define buttonPin1 7  											// Arduino pin connected to buttonPin1
            #define buttonPin2 A0  											// Arduino pin connected to buttonPin2 (fixed to ground)
            
            // Motor pin definitions
            #define motorPin1  3     										// IN1 on the ULN2003 driver 1
            #define motorPin2  4     										// IN2 on the ULN2003 driver 1
            #define motorPin3  5     										// IN3 on the ULN2003 driver 1
            #define motorPin4  6     										// IN4 on the ULN2003 driver 1
            
            const unsigned long heartbeatInterval = 1 * 3600UL * 1000UL ;	// heartbeatinterval
            unsigned long heartbeatCounter = 0 ;
            
            //
            // helper routines to store and retrieve long in mysensors EEPROM
            union {															// used to convert long to bytes for EEPROM storage
            	long longInt;
            	uint8_t LongByte[4];
            	} convLongInt ;
            
            void saveStateL(int EEposition, long StateL){
            	convLongInt.longInt = StateL ;
            	for (int y = 0; y < 4 ; y++){								// convert to bytes
            		saveState(EEposition + y , convLongInt.LongByte[y]) ;
            		}
            	Serial.print("State saved: "); Serial.println(StateL);
            	}
            		
            long loadStateL(int EEposition){
            	for (int y = 0; y < 4 ; y++){								// convert from bytes
            		convLongInt.LongByte[y] = loadState(EEposition + y) ;
            		}
            	Serial.print("State read: "); Serial.println(convLongInt.longInt);
            	return convLongInt.longInt ;
            	}
            	
            
            // Initialize with pin sequence IN1-IN3-IN2-IN4 for using the AccelStepper with 28BYJ-48
            AccelStepper stepper1(HALFSTEP, motorPin1, motorPin3, motorPin2, motorPin4);
            // Initialize button active low, debounce and internal pull-up
            Button myBtn(buttonPin1, true, true, 40);						// Initiate the button (pin, pull_up, invert, debounce_ms)
            
            MyMessage percentageMsg(CHILD_ID, V_PERCENTAGE);				// used to send updates to controller
            
            const long maxRun = 4000000L ;									// maximum runway
            long setPosition = 0 ; 											// remembers set position, need to be saved in EEPROM
            const int setPositionEE = 4 ;									// eeprom location
            long openPosition = 0 ; 										// Position at open, need to be saved in EEPROM?
            const int openPositionEE = setPositionEE + 4 ;					// eeprom location
            long closedPosition = 120000UL ; 								// Position at full close, need to be saved in EEPROM
            const int closedPositionEE = openPositionEE + 4 ;				// eeprom location
            
            unsigned long idleTimer = millis() ;							// return to idle timer
            unsigned long idleTime = 100000UL ;								// return to idle after 100 secs
            
            unsigned long printTimer = millis() ;							// print timer
            unsigned long printTime = 1000UL ;								// print after 1 secs
            
            enum position_t {Open, Close, Idle, Running} ;
            position_t lastDirection = Open ; 								// lastDirection only for buttonpress
            position_t runStatus = Idle ;									// indicates current status for running motor. used for status reporting to controller
            
            enum State_t {sIdle, sCalibrateOpen, sCalibrateClose} ;
            State_t State = sIdle ;
            
            
            void setup() {
            	// setup buttons
            	pinMode(buttonPin1, OUTPUT);
            	stepper1.setMaxSpeed(2000.0);
            	stepper1.setAcceleration(1000.0);
            	//saveStateL(closedPositionEE, closedPosition) ; 			// INIT: save closed position in EEPROM
            	closedPosition = loadStateL(closedPositionEE) ;				// need to get last values from EEPROM and assume the current position is correct
            	setPosition = loadStateL(setPositionEE) ;
            	stepper1.setCurrentPosition(setPosition );
            }//--(end setup )---
            
            void presentation() {
              present(CHILD_ID, S_COVER, "Curtain");						// Window Cover sub-type, commands: V_UP, V_DOWN, V_STOP
            
              // Register the LED Dimmable Light with the gateway
              sendSketchInfo(SN, SV);
            }
            
            
            void loop() {
            unsigned int now = millis() ;								// current time for loop
            // simple state machine for button press
            	myBtn.read();  
            	switch (State) {
                    // Idle state, waiting for some action
            		// - button press
            		// - idleTimer
                    case sIdle:                
                        if (myBtn.wasReleased()){						// idle
            				Serial.println("Button release") ;
            				// if running stop
            				if (stepper1.isRunning()){
            					setPosition = stepper1.currentPosition();
            					stepper1.moveTo(setPosition) ;			// move to current position (was already there..)
            				} else if (lastDirection == Open) {
            					stepper1.moveTo(closedPosition) ;
            					lastDirection = Close ;
            				} else {									// lastDirection == Close
            					stepper1.moveTo(openPosition) ;
            					lastDirection = Open ;
            				}	
            			} else if (myBtn.pressedFor(3000)){				// move to calibratete state with long press
            				Serial.println("Button press long") ;
            				idleTimer = now ;							// return to idle after ...
            				State = sCalibrateOpen ;
            				stepper1.move(-maxRun) ;					// let the stepper open with maximum
            				}
            			break ;
            		// if not running and last action was open close ;  else open
            		// if longpress Calibrate open
                    case sCalibrateOpen:           						// calibration going on     
            			if (myBtn.wasPressed()){
            				stepper1.setCurrentPosition(0 );		// set new 0 position ??
            				openPosition = setPosition = 0 ;
            				State = sCalibrateClose ;					// next is close calibarion
            				stepper1.move(maxRun) ;						// let the stepper close with maximum
            			} else if (now > idleTimer + idleTime) {		// timer expired -> abort calibration
            				State = sIdle ;
            			}
            			break ;
                    case sCalibrateClose:								// calibrate closed position, end with keypress
            			if (myBtn.wasPressed())	{
            				closedPosition = setPosition = stepper1.currentPosition() ;
            				saveStateL(closedPositionEE, closedPosition) ; // save closed position in EEPROM
            				State = sIdle ;
            				stepper1.moveTo(openPosition) ;				// return to open after calibration
            			} else if (now > idleTimer + idleTime) {		// timer expired -> abort calibration
            				State = sIdle ;
            			}
            			break ;
            		default :
            			break ;
            		}
            	// power off stepper if not running (no need to reenable))
            	if (!stepper1.isRunning()){
            		if (runStatus != Idle){								// there was a change in runningstatus, so report to controller
            			setPosition = stepper1.currentPosition() ;		// store in EEPROM and report ready to controller
            			saveStateL(setPositionEE, setPosition) ;
            			send( percentageMsg.set((100 * setPosition)/(closedPosition - openPosition))) ;
            			runStatus = Idle ;
            		}
            		stepper1.disableOutputs();
            	} else {
            		runStatus = Running ;
            	}
            	stepper1.run();
            	/*
            	if (printTimer++ > now + printTime){
            		printTimer = now ;
            		Serial.println(stepper1.currentPosition());
            		}
            	*/
            }
            
            // This is called when a message is received 
            void receive(const MyMessage &message) {
            // We only expect few types of messages from controller, check which
              switch (message.type) {
            	case V_PERCENTAGE:
            	// Curtain should be opened
            	stepper1.moveTo(message.getInt() * (closedPosition - openPosition)/100);
            	Serial.print("Message: "); Serial.print(message.sensor); Serial.print(" , value: % "); Serial.println( message.getInt());
            	Serial.print("Moving to: "); Serial.println(message.getInt() * (closedPosition - openPosition)/100);
            	break ;
            	case V_STATUS:
            	// Curtain should be opened or closed full
            	stepper1.moveTo((message.getInt() == HIGH)?openPosition:closedPosition);
            	Serial.print("Message - valid: ");
            	Serial.print(message.sensor);
            	Serial.print(" , value: % ");
            	break ;
            	default : 
            	// not recognizable message
            	Serial.print("Message - valid: ");
            	Serial.print(message.sensor);
            	Serial.print(", Unrecognized ");
            	break ;
            	}
              }
              
            
            
            
            
            P Offline
            P Offline
            patchmaster
            wrote on last edited by
            #16

            @AWI Thanks. I have been using the Accelstepper library, but this has already given me several other ideas.
            I appreciate the help.

            1 Reply Last reply
            0
            • AWIA AWI

              @patchmaster This is my current curtain control sketch. I work with the development branch, so the syntax can be a little different.

              The Accelstepper library gives you all the abilities to slow start/stop with numerous kinds of steppers.
              My sketch includes a calibration function (stored in EEPROM) so the you don't need end stop detection (a stepper knows where it is)

              /*
               PROJECT: MY Sensors curtain controller
               PROGRAMMER: AWI
               DATE: march 11, 2016
               FILE: AWI stepper1.ino
               LICENSE: Public domain
              
               Hardware: ATMega328p board w/ NRF24l01
              	and MySensors 2.0 (Development)
              		
              Special:
              	uses AccelStepper library
              	
              Summary:
              	Curtain control with stepper motor. 
              	Manual operation with 1 push button 
              	Calibration with manual button
              
              Remarks:
              	Fixed node-id
              	
              Change log:
              20160312 - Cleanup
              */
              
              // Enable debug prints to serial monitor
              #define MY_DEBUG 
              
              #define MY_NODE_ID 13											// fixed node number
              // Enable and select radio type attached
              #define MY_RADIO_NRF24
              //#define MY_RADIO_RFM69
              
              #include <SPI.h>
              #include <MySensor.h> 
              
              // stepper library
              #include <AccelStepper.h>										// http://www.airspayce.com/mikem/arduino/AccelStepper/
              #define HALFSTEP 8  											// Stepper uses "Halfstep" mode
              
              // button library
              // used for:
              // - manual open close - single click: close/ stop/ open/ stop
              // - calibration  - after long press: open calibarion- until single press - closed calibration - until single press (stop)
              #include <Button.h>												// https://github.com/JChristensen/Button
              
              #define CHILD_ID 1   											// Id of the sensor child
              
              #define SN "Curtain control 13"
              #define SV "1.0"
              
              #define buttonPin1 7  											// Arduino pin connected to buttonPin1
              #define buttonPin2 A0  											// Arduino pin connected to buttonPin2 (fixed to ground)
              
              // Motor pin definitions
              #define motorPin1  3     										// IN1 on the ULN2003 driver 1
              #define motorPin2  4     										// IN2 on the ULN2003 driver 1
              #define motorPin3  5     										// IN3 on the ULN2003 driver 1
              #define motorPin4  6     										// IN4 on the ULN2003 driver 1
              
              const unsigned long heartbeatInterval = 1 * 3600UL * 1000UL ;	// heartbeatinterval
              unsigned long heartbeatCounter = 0 ;
              
              //
              // helper routines to store and retrieve long in mysensors EEPROM
              union {															// used to convert long to bytes for EEPROM storage
              	long longInt;
              	uint8_t LongByte[4];
              	} convLongInt ;
              
              void saveStateL(int EEposition, long StateL){
              	convLongInt.longInt = StateL ;
              	for (int y = 0; y < 4 ; y++){								// convert to bytes
              		saveState(EEposition + y , convLongInt.LongByte[y]) ;
              		}
              	Serial.print("State saved: "); Serial.println(StateL);
              	}
              		
              long loadStateL(int EEposition){
              	for (int y = 0; y < 4 ; y++){								// convert from bytes
              		convLongInt.LongByte[y] = loadState(EEposition + y) ;
              		}
              	Serial.print("State read: "); Serial.println(convLongInt.longInt);
              	return convLongInt.longInt ;
              	}
              	
              
              // Initialize with pin sequence IN1-IN3-IN2-IN4 for using the AccelStepper with 28BYJ-48
              AccelStepper stepper1(HALFSTEP, motorPin1, motorPin3, motorPin2, motorPin4);
              // Initialize button active low, debounce and internal pull-up
              Button myBtn(buttonPin1, true, true, 40);						// Initiate the button (pin, pull_up, invert, debounce_ms)
              
              MyMessage percentageMsg(CHILD_ID, V_PERCENTAGE);				// used to send updates to controller
              
              const long maxRun = 4000000L ;									// maximum runway
              long setPosition = 0 ; 											// remembers set position, need to be saved in EEPROM
              const int setPositionEE = 4 ;									// eeprom location
              long openPosition = 0 ; 										// Position at open, need to be saved in EEPROM?
              const int openPositionEE = setPositionEE + 4 ;					// eeprom location
              long closedPosition = 120000UL ; 								// Position at full close, need to be saved in EEPROM
              const int closedPositionEE = openPositionEE + 4 ;				// eeprom location
              
              unsigned long idleTimer = millis() ;							// return to idle timer
              unsigned long idleTime = 100000UL ;								// return to idle after 100 secs
              
              unsigned long printTimer = millis() ;							// print timer
              unsigned long printTime = 1000UL ;								// print after 1 secs
              
              enum position_t {Open, Close, Idle, Running} ;
              position_t lastDirection = Open ; 								// lastDirection only for buttonpress
              position_t runStatus = Idle ;									// indicates current status for running motor. used for status reporting to controller
              
              enum State_t {sIdle, sCalibrateOpen, sCalibrateClose} ;
              State_t State = sIdle ;
              
              
              void setup() {
              	// setup buttons
              	pinMode(buttonPin1, OUTPUT);
              	stepper1.setMaxSpeed(2000.0);
              	stepper1.setAcceleration(1000.0);
              	//saveStateL(closedPositionEE, closedPosition) ; 			// INIT: save closed position in EEPROM
              	closedPosition = loadStateL(closedPositionEE) ;				// need to get last values from EEPROM and assume the current position is correct
              	setPosition = loadStateL(setPositionEE) ;
              	stepper1.setCurrentPosition(setPosition );
              }//--(end setup )---
              
              void presentation() {
                present(CHILD_ID, S_COVER, "Curtain");						// Window Cover sub-type, commands: V_UP, V_DOWN, V_STOP
              
                // Register the LED Dimmable Light with the gateway
                sendSketchInfo(SN, SV);
              }
              
              
              void loop() {
              unsigned int now = millis() ;								// current time for loop
              // simple state machine for button press
              	myBtn.read();  
              	switch (State) {
                      // Idle state, waiting for some action
              		// - button press
              		// - idleTimer
                      case sIdle:                
                          if (myBtn.wasReleased()){						// idle
              				Serial.println("Button release") ;
              				// if running stop
              				if (stepper1.isRunning()){
              					setPosition = stepper1.currentPosition();
              					stepper1.moveTo(setPosition) ;			// move to current position (was already there..)
              				} else if (lastDirection == Open) {
              					stepper1.moveTo(closedPosition) ;
              					lastDirection = Close ;
              				} else {									// lastDirection == Close
              					stepper1.moveTo(openPosition) ;
              					lastDirection = Open ;
              				}	
              			} else if (myBtn.pressedFor(3000)){				// move to calibratete state with long press
              				Serial.println("Button press long") ;
              				idleTimer = now ;							// return to idle after ...
              				State = sCalibrateOpen ;
              				stepper1.move(-maxRun) ;					// let the stepper open with maximum
              				}
              			break ;
              		// if not running and last action was open close ;  else open
              		// if longpress Calibrate open
                      case sCalibrateOpen:           						// calibration going on     
              			if (myBtn.wasPressed()){
              				stepper1.setCurrentPosition(0 );		// set new 0 position ??
              				openPosition = setPosition = 0 ;
              				State = sCalibrateClose ;					// next is close calibarion
              				stepper1.move(maxRun) ;						// let the stepper close with maximum
              			} else if (now > idleTimer + idleTime) {		// timer expired -> abort calibration
              				State = sIdle ;
              			}
              			break ;
                      case sCalibrateClose:								// calibrate closed position, end with keypress
              			if (myBtn.wasPressed())	{
              				closedPosition = setPosition = stepper1.currentPosition() ;
              				saveStateL(closedPositionEE, closedPosition) ; // save closed position in EEPROM
              				State = sIdle ;
              				stepper1.moveTo(openPosition) ;				// return to open after calibration
              			} else if (now > idleTimer + idleTime) {		// timer expired -> abort calibration
              				State = sIdle ;
              			}
              			break ;
              		default :
              			break ;
              		}
              	// power off stepper if not running (no need to reenable))
              	if (!stepper1.isRunning()){
              		if (runStatus != Idle){								// there was a change in runningstatus, so report to controller
              			setPosition = stepper1.currentPosition() ;		// store in EEPROM and report ready to controller
              			saveStateL(setPositionEE, setPosition) ;
              			send( percentageMsg.set((100 * setPosition)/(closedPosition - openPosition))) ;
              			runStatus = Idle ;
              		}
              		stepper1.disableOutputs();
              	} else {
              		runStatus = Running ;
              	}
              	stepper1.run();
              	/*
              	if (printTimer++ > now + printTime){
              		printTimer = now ;
              		Serial.println(stepper1.currentPosition());
              		}
              	*/
              }
              
              // This is called when a message is received 
              void receive(const MyMessage &message) {
              // We only expect few types of messages from controller, check which
                switch (message.type) {
              	case V_PERCENTAGE:
              	// Curtain should be opened
              	stepper1.moveTo(message.getInt() * (closedPosition - openPosition)/100);
              	Serial.print("Message: "); Serial.print(message.sensor); Serial.print(" , value: % "); Serial.println( message.getInt());
              	Serial.print("Moving to: "); Serial.println(message.getInt() * (closedPosition - openPosition)/100);
              	break ;
              	case V_STATUS:
              	// Curtain should be opened or closed full
              	stepper1.moveTo((message.getInt() == HIGH)?openPosition:closedPosition);
              	Serial.print("Message - valid: ");
              	Serial.print(message.sensor);
              	Serial.print(" , value: % ");
              	break ;
              	default : 
              	// not recognizable message
              	Serial.print("Message - valid: ");
              	Serial.print(message.sensor);
              	Serial.print(", Unrecognized ");
              	break ;
              	}
                }
                
              
              
              
              
              Tore André RosanderT Offline
              Tore André RosanderT Offline
              Tore André Rosander
              wrote on last edited by
              #17

              @AWI
              I have been searching for something like this for a while, thank you for the code!

              But i have some problems compiling it :\

              C:\Users\ToreR\Documents\Arduino\stepper_mysensor\stepper_mysensor.ino: In function 'void saveStateL(int, long int)':
              
              stepper_mysensor:74: error: 'saveState' was not declared in this scope
              
                       saveState(EEposition + y , convLongInt.LongByte[y]) ;
              
                                                                         ^
              
              C:\Users\ToreR\Documents\Arduino\stepper_mysensor\stepper_mysensor.ino: In function 'long int loadStateL(int)':
              
              stepper_mysensor:81: error: 'loadState' was not declared in this scope
              
                       convLongInt.LongByte[y] = loadState(EEposition + y) ;
              
                                                                         ^
              
              C:\Users\ToreR\Documents\Arduino\stepper_mysensor\stepper_mysensor.ino: In function 'void presentation()':
              
              stepper_mysensor:129: error: 'present' was not declared in this scope
              
                 present(CHILD_ID, S_COVER, "Curtain");                        // Window Cover sub-type, commands: V_UP, V_DOWN, V_STOP
              
                                                     ^
              
              stepper_mysensor:132: error: 'sendSketchInfo' was not declared in this scope
              
                 sendSketchInfo(SN, SV);
              
                                      ^
              
              C:\Users\ToreR\Documents\Arduino\stepper_mysensor\stepper_mysensor.ino: In function 'void loop()':
              
              stepper_mysensor:195: error: 'send' was not declared in this scope
              
                           send( percentageMsg.set((100 * setPosition)/(closedPosition - openPosition))) ;
              
                                                                                                       ^
              
              exit status 1
              'saveState' was not declared in this scope```
              AWIA 1 Reply Last reply
              0
              • Tore André RosanderT Tore André Rosander

                @AWI
                I have been searching for something like this for a while, thank you for the code!

                But i have some problems compiling it :\

                C:\Users\ToreR\Documents\Arduino\stepper_mysensor\stepper_mysensor.ino: In function 'void saveStateL(int, long int)':
                
                stepper_mysensor:74: error: 'saveState' was not declared in this scope
                
                         saveState(EEposition + y , convLongInt.LongByte[y]) ;
                
                                                                           ^
                
                C:\Users\ToreR\Documents\Arduino\stepper_mysensor\stepper_mysensor.ino: In function 'long int loadStateL(int)':
                
                stepper_mysensor:81: error: 'loadState' was not declared in this scope
                
                         convLongInt.LongByte[y] = loadState(EEposition + y) ;
                
                                                                           ^
                
                C:\Users\ToreR\Documents\Arduino\stepper_mysensor\stepper_mysensor.ino: In function 'void presentation()':
                
                stepper_mysensor:129: error: 'present' was not declared in this scope
                
                   present(CHILD_ID, S_COVER, "Curtain");                        // Window Cover sub-type, commands: V_UP, V_DOWN, V_STOP
                
                                                       ^
                
                stepper_mysensor:132: error: 'sendSketchInfo' was not declared in this scope
                
                   sendSketchInfo(SN, SV);
                
                                        ^
                
                C:\Users\ToreR\Documents\Arduino\stepper_mysensor\stepper_mysensor.ino: In function 'void loop()':
                
                stepper_mysensor:195: error: 'send' was not declared in this scope
                
                             send( percentageMsg.set((100 * setPosition)/(closedPosition - openPosition))) ;
                
                                                                                                         ^
                
                exit status 1
                'saveState' was not declared in this scope```
                AWIA Offline
                AWIA Offline
                AWI
                Hero Member
                wrote on last edited by AWI
                #18

                @Tore-André-Rosander are you using the development branch? The errors seem to indicate that is the case.

                Tore André RosanderT 1 Reply Last reply
                0
                • AWIA AWI

                  @Tore-André-Rosander are you using the development branch? The errors seem to indicate that is the case.

                  Tore André RosanderT Offline
                  Tore André RosanderT Offline
                  Tore André Rosander
                  wrote on last edited by
                  #19

                  @AWI Thank you, that helped :)
                  I now have it up and running.

                  But how do i connect and use this with a controller (like Domoticz)?

                  I use an ESP gateway (from the dev branch) and the curtain node is connected and showing up in domoticz.
                  But how do i make domoticz send commands to the curtain node?

                  All i get when adding the curtain node both as on/off button and blinds in domoticz is "unreconized" in the curtain serial monoitor.

                  AWIA 1 Reply Last reply
                  0
                  • Tore André RosanderT Tore André Rosander

                    @AWI Thank you, that helped :)
                    I now have it up and running.

                    But how do i connect and use this with a controller (like Domoticz)?

                    I use an ESP gateway (from the dev branch) and the curtain node is connected and showing up in domoticz.
                    But how do i make domoticz send commands to the curtain node?

                    All i get when adding the curtain node both as on/off button and blinds in domoticz is "unreconized" in the curtain serial monoitor.

                    AWIA Offline
                    AWIA Offline
                    AWI
                    Hero Member
                    wrote on last edited by
                    #20

                    @Tore-André-Rosander I have defined it as "Blinds Percentage" in Domoticz. This send the V_STATUS and V_PERCENTAGE messages where the node should respond to...
                    0_1458557025507_upload-d16cb932-d511-433f-9488-112b68d308f4

                    Tore André RosanderT 1 Reply Last reply
                    0
                    • AWIA AWI

                      @Tore-André-Rosander I have defined it as "Blinds Percentage" in Domoticz. This send the V_STATUS and V_PERCENTAGE messages where the node should respond to...
                      0_1458557025507_upload-d16cb932-d511-433f-9488-112b68d308f4

                      Tore André RosanderT Offline
                      Tore André RosanderT Offline
                      Tore André Rosander
                      wrote on last edited by
                      #21

                      @AWI THanks again for your fast replys!

                      This is what i get in serial monitor when i use the "up" "down" buttons for blinds percentage in domoticz.

                      This is my very first MySensor setup so it might be some error with my setup, i will have a deeper look at it later tonight.

                      Starting sensor (RNNNA-, 2.0.0-beta)
                      Radio init successful.
                      State read: -1
                      State read: -1
                      send: 13-13-0-0 s=255,c=3,t=15,pt=0,l=2,sg=0,st=ok:
                      send: 13-13-0-0 s=255,c=0,t=17,pt=0,l=10,sg=0,st=ok:2.0.0-beta
                      send: 13-13-0-0 s=255,c=3,t=6,pt=1,l=1,sg=0,st=ok:0
                      read: 0-0-13 s=255,c=3,t=15,pt=0,l=2,sg=0:
                      read: 0-0-13 s=255,c=3,t=6,pt=0,l=1,sg=0:M
                      send: 13-13-0-0 s=1,c=0,t=5,pt=0,l=7,sg=0,st=ok:Curtain
                      send: 13-13-0-0 s=255,c=3,t=11,pt=0,l=18,sg=0,st=ok:Curtain control 13
                      send: 13-13-0-0 s=255,c=3,t=12,pt=0,l=3,sg=0,st=ok:1.0
                      Init complete, id=13, parent=0, distance=1
                      read: 0-0-13 s=1,c=1,t=29,pt=0,l=0,sg=0:
                      Message - valid: 1, Unrecognized read: 0-0-13 s=1,c=1,t=30,pt=0,l=0,sg=0:
                      Message - valid: 1, Unrecognized read: 0-0-13 s=1,c=1,t=29,pt=0,l=0,sg=0:
                      Message - valid: 1, Unrecognized read: 0-0-13 s=1,c=1,t=30,pt=0,l=0,sg=0:
                      Message - valid: 1, Unrecognized read: 0-0-13 s=1,c=1,t=29,pt=0,l=0,sg=0:
                      Message - valid: 1, Unrecognized read: 0-0-13 s=1,c=1,t=30,pt=0,l=0,sg=0:
                      Message - valid: 1, Unrecognized read: 0-0-13 s=1,c=1,t=29,pt=0,l=0,sg=0:
                      Message - valid: 1, Unrecognized read: 0-0-13 s=1,c=1,t=30,pt=0,l=0,sg=0:
                      Message - valid: 1, Unrecognized read: 0-0-13 s=1,c=1,t=29,pt=0,l=0,sg=0:
                      Message - valid: 1, Unrecognized read: 0-0-13 s=1,c=1,t=30,pt=0,l=0,sg=0:
                      Message - valid: 1, Unrecognized```
                      AWIA 1 Reply Last reply
                      0
                      • Tore André RosanderT Tore André Rosander

                        @AWI THanks again for your fast replys!

                        This is what i get in serial monitor when i use the "up" "down" buttons for blinds percentage in domoticz.

                        This is my very first MySensor setup so it might be some error with my setup, i will have a deeper look at it later tonight.

                        Starting sensor (RNNNA-, 2.0.0-beta)
                        Radio init successful.
                        State read: -1
                        State read: -1
                        send: 13-13-0-0 s=255,c=3,t=15,pt=0,l=2,sg=0,st=ok:
                        send: 13-13-0-0 s=255,c=0,t=17,pt=0,l=10,sg=0,st=ok:2.0.0-beta
                        send: 13-13-0-0 s=255,c=3,t=6,pt=1,l=1,sg=0,st=ok:0
                        read: 0-0-13 s=255,c=3,t=15,pt=0,l=2,sg=0:
                        read: 0-0-13 s=255,c=3,t=6,pt=0,l=1,sg=0:M
                        send: 13-13-0-0 s=1,c=0,t=5,pt=0,l=7,sg=0,st=ok:Curtain
                        send: 13-13-0-0 s=255,c=3,t=11,pt=0,l=18,sg=0,st=ok:Curtain control 13
                        send: 13-13-0-0 s=255,c=3,t=12,pt=0,l=3,sg=0,st=ok:1.0
                        Init complete, id=13, parent=0, distance=1
                        read: 0-0-13 s=1,c=1,t=29,pt=0,l=0,sg=0:
                        Message - valid: 1, Unrecognized read: 0-0-13 s=1,c=1,t=30,pt=0,l=0,sg=0:
                        Message - valid: 1, Unrecognized read: 0-0-13 s=1,c=1,t=29,pt=0,l=0,sg=0:
                        Message - valid: 1, Unrecognized read: 0-0-13 s=1,c=1,t=30,pt=0,l=0,sg=0:
                        Message - valid: 1, Unrecognized read: 0-0-13 s=1,c=1,t=29,pt=0,l=0,sg=0:
                        Message - valid: 1, Unrecognized read: 0-0-13 s=1,c=1,t=30,pt=0,l=0,sg=0:
                        Message - valid: 1, Unrecognized read: 0-0-13 s=1,c=1,t=29,pt=0,l=0,sg=0:
                        Message - valid: 1, Unrecognized read: 0-0-13 s=1,c=1,t=30,pt=0,l=0,sg=0:
                        Message - valid: 1, Unrecognized read: 0-0-13 s=1,c=1,t=29,pt=0,l=0,sg=0:
                        Message - valid: 1, Unrecognized read: 0-0-13 s=1,c=1,t=30,pt=0,l=0,sg=0:
                        Message - valid: 1, Unrecognized```
                        AWIA Offline
                        AWIA Offline
                        AWI
                        Hero Member
                        wrote on last edited by
                        #22

                        @Tore-André-Rosander Nothing wrong with you interpretation. I have not written this sketch as a complete S_COVER implementation. Only the V_PERCENTAGE part (not V_UP/V_DOWN). If you define it in Domoticz as "Blinds percentage" (see my previous post) it will work. Sorry for the confusion.

                        Tore André RosanderT 1 Reply Last reply
                        0
                        • AWIA AWI

                          @Tore-André-Rosander Nothing wrong with you interpretation. I have not written this sketch as a complete S_COVER implementation. Only the V_PERCENTAGE part (not V_UP/V_DOWN). If you define it in Domoticz as "Blinds percentage" (see my previous post) it will work. Sorry for the confusion.

                          Tore André RosanderT Offline
                          Tore André RosanderT Offline
                          Tore André Rosander
                          wrote on last edited by
                          #23

                          @AWI Seems like my problem is with Domoticz itselfe.
                          I have the same problem as described in this post https://www.domoticz.com/forum/viewtopic.php?f=6&t=7748

                          AWIA 1 Reply Last reply
                          0
                          • Tore André RosanderT Tore André Rosander

                            @AWI Seems like my problem is with Domoticz itselfe.
                            I have the same problem as described in this post https://www.domoticz.com/forum/viewtopic.php?f=6&t=7748

                            AWIA Offline
                            AWIA Offline
                            AWI
                            Hero Member
                            wrote on last edited by
                            #24

                            @Tore-André-Rosander You can probably solve it by deleting the sensor in Domoticz and let the sketch present itself as S_DIMMER (and use another sensor id)

                            1 Reply Last reply
                            0
                            • Tore André RosanderT Offline
                              Tore André RosanderT Offline
                              Tore André Rosander
                              wrote on last edited by
                              #25

                              Maybe its because i have not calibrated it? I dont have any pushbuttons laying around, so im gonna make one with some wires. But i see that there is two pins defined as buttons. Should i use the buttonPin1 as VCC?

                              So it would look something like buttonPin1 -> buttonPin2 -> button -> gnd?

                              AWIA 1 Reply Last reply
                              0
                              • Tore André RosanderT Tore André Rosander

                                Maybe its because i have not calibrated it? I dont have any pushbuttons laying around, so im gonna make one with some wires. But i see that there is two pins defined as buttons. Should i use the buttonPin1 as VCC?

                                So it would look something like buttonPin1 -> buttonPin2 -> button -> gnd?

                                AWIA Offline
                                AWIA Offline
                                AWI
                                Hero Member
                                wrote on last edited by
                                #26

                                @Tore-André-Rosander You can ignore buttonpin2. Just connect your "button" to buttonpin1 and ground.

                                1 Reply Last reply
                                0
                                • AWIA AWI

                                  Looks good. I am curious to see the details... jealous for the speed :runner: your curtain is moving.

                                  I have been working on a similar project last week. The mechanics and ´looks´ are the most difficult part for me.

                                  For now I have used a ´tuned´ cheap & small stepper which makes it slooow but effective ;-) The rail and mounting is standard IKEA. The pro-mini has the jModule attached. Works like a charm (/snail)!

                                  0_1457980545567_upload-c50fc1e9-f23e-458d-a812-62ad4bf478e0
                                  0_1457981153586_upload-c7064209-3900-4e4b-b335-8c88721367c0

                                  TheoLT Offline
                                  TheoLT Offline
                                  TheoL
                                  Contest Winner
                                  wrote on last edited by
                                  #27

                                  @AWI I'm curious where you got the rails for the curtain. I wasn't been able to find them, but stumbled on this topic.

                                  AWIA 1 Reply Last reply
                                  0
                                  • TheoLT TheoL

                                    @AWI I'm curious where you got the rails for the curtain. I wasn't been able to find them, but stumbled on this topic.

                                    AWIA Offline
                                    AWIA Offline
                                    AWI
                                    Hero Member
                                    wrote on last edited by
                                    #28

                                    @TheoL Ikea :smile:

                                    TheoLT 1 Reply Last reply
                                    0
                                    • AWIA AWI

                                      @TheoL Ikea :smile:

                                      TheoLT Offline
                                      TheoLT Offline
                                      TheoL
                                      Contest Winner
                                      wrote on last edited by
                                      #29

                                      @AWI Really interested in the mechanics ;-)

                                      1 Reply Last reply
                                      0
                                      • franzelareF Offline
                                        franzelareF Offline
                                        franzelare
                                        wrote on last edited by
                                        #30

                                        I'm currently working on a similar project, only I got started with 24V DC motors that I got from my work (left overs from a test project) These motors are very strong (way way over rated) and have a big gearbox what unfortunately makes the movement a bit slow.
                                        I started off with 1 motor to move 2 curtains at the same time, but will change this to 2 motors for either side since the better half of me likes to control the curtains separately in case she only wants to close 1.
                                        Next to the automation there will also be a manual control switch be hidden behind the curtains in case the node is down and I'm not at home to fix the issue...
                                        all running on an ESP8266 (ESP-12e) unit to have it over WiFi and have enough io

                                        Currently the test setup is working fine and I'm ordering parts to start implementing this a bit bigger in the first room. the test setup I made with some old wood 1 meter of rail and a few old rugs as curtains...
                                        alt text

                                        I use a GT2 timing belt that is commently used for 3D printers and pully's are widely available as well as the belts in different lengths (I order them on rolls of 10 meters) and attached the timing belt to a carriage that is normally to pull the curtains with a rod.
                                        alt text

                                        the motor is mounted on a bracket with currently 2 end stop switches for open and close (but will be 1 switch for open and 1 for close in the final solution)
                                        alt text

                                        resulting in driving the curtain from 1 side
                                        alt text

                                        alt text

                                        electronics are working fine now and need to be ported to a test print and later to a real PCB design

                                        alt text

                                        alt text

                                        1 Reply Last reply
                                        3
                                        • R Offline
                                          R Offline
                                          romeok01
                                          wrote on last edited by romeok01
                                          #31

                                          Hello.

                                          To my project i use stepper motor JK42HS34-0404 and driver L298N.

                                          This is a wiring diagram.
                                          alt text

                                          This is a program code that I use

                                          #include <MySensor.h>  
                                          #include <SPI.h>
                                          #include <AccelStepper.h>
                                          #define HALFSTEP 4  // Stepper uses "Halfstep" mode
                                          #define CURTAIN_CLOSED 1000 // value when closed
                                          #define CURTAIN_OPEN 0 // value when open
                                          #define CHILD_ID 1   // Id of the sensor child
                                          // MySensors definitions
                                          MySensor gw;
                                          // Initialize message
                                          MyMessage msg(CHILD_ID, V_TRIPPED);
                                          
                                          
                                          // Motor pin definitions
                                          #define motorPin1  3     // IN1 on the ULN2003 driver 1
                                          #define motorPin2  4     // IN2 on the ULN2003 driver 1
                                          #define motorPin3  5     // IN3 on the ULN2003 driver 1
                                          #define motorPin4  6     // IN4 on the ULN2003 driver 1
                                          
                                          // Initialize with pin sequence IN1-IN3-IN2-IN4 for using the AccelStepper with 28BYJ-48
                                          AccelStepper stepper1(HALFSTEP, motorPin1, motorPin2, motorPin3, motorPin4);
                                          
                                          unsigned long current_position ; // remembers current position, need to be saved in EEPROM?
                                          
                                          void setup() {
                                            // MySensors
                                            gw.begin(); // fixed node 13
                                            gw.sendSketchInfo("Curtain control 13", "1.0"); // Send the sketch version information to the gateway and Controller
                                          
                                            //pinMode(DIGITAL_INPUT_SENSOR, INPUT);      // sets the motion sensor digital pin as input
                                            // Register all sensors to gw (they will be created as child devices)
                                            gw.present(CHILD_ID, S_COVER); // Window Cover sub-type, commands: V_UP, V_DOWN, V_STOP
                                            
                                            stepper1.setMaxSpeed(500.0);
                                            stepper1.setAcceleration(700.0);
                                            stepper1.moveTo(CURTAIN_OPEN);
                                            
                                            current_position = CURTAIN_OPEN ;
                                            stepper1.moveTo(CURTAIN_OPEN);
                                          }//--(end setup )---
                                          
                                          void loop() {
                                            // if message = V_UP start moving until closed
                                            // if message = V_DOWN start moving back until open
                                            // if message = V_STOP stop moving
                                            // Test: Change direction when the stepper reaches the target position
                                            gw.process(); // check if message from controller
                                            if (stepper1.distanceToGo() == 0){
                                              if (stepper1.currentPosition() == CURTAIN_OPEN){
                                                stepper1.moveTo(CURTAIN_CLOSED);
                                                Serial.println("Curtain Open, now closing");
                                                gw.request(CHILD_ID, V_UP, 0); // request new values from controller  
                                              }
                                              else{
                                                stepper1.moveTo(CURTAIN_OPEN);
                                                Serial.println("Curtain Closed, now opening");
                                                gw.request(CHILD_ID, V_DOWN, 0); // request new values from controller   
                                              }
                                            }
                                            
                                            stepper1.run();
                                          }
                                          
                                          // This is called when a message is received 
                                          void incomingMessage(const MyMessage &message) {
                                            // We only expect few types of messages from controller, check which
                                            stepper1.moveTo(message.getInt() * CURTAIN_CLOSED/100);
                                            Serial.print("Message - valid: ");
                                            Serial.print(message.sensor);
                                            Serial.print(" , value: % ");
                                            Serial.println(message.getInt());
                                            switch (message.getInt()) {
                                            case 100:
                                              // Curtain should be opened
                                               Serial.print("Message - valid: ");
                                               Serial.print(message.sensor);
                                               Serial.print(", Message UP ");
                                               stepper1.moveTo(CURTAIN_OPEN);
                                               break;
                                            case 0:
                                              // Curtain should be closed
                                               Serial.print("Message - valid: ");
                                               Serial.print(message.sensor);
                                               Serial.print(", Message DOWN ");
                                               stepper1.moveTo(CURTAIN_CLOSED);
                                              break;
                                            case 50:
                                              // Curtain action should be stopped
                                               Serial.print("Message - valid: ");
                                               Serial.print(message.sensor);
                                               Serial.print(", Message STOP ");
                                              break;
                                            default: 
                                              // not recognizable message
                                               Serial.print("Message - valid: ");
                                               Serial.print(message.sensor);
                                               Serial.print(", Unrecognized ");
                                          
                                            }
                                           
                                          }
                                          

                                          When the program I have uploaded to my mysensors, the engine still turns, one left and one to the right and did not work the button blinds in Domoticz.

                                          I cant turn off my stepper motor in Domoticz.

                                          https://www.youtube.com/embed/1Wc1p_9YDQQ

                                          Please help me.

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


                                          29

                                          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