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
xydixX

xydix

@xydix
About
Posts
68
Topics
11
Shares
0
Groups
0
Followers
0
Following
1

Posts

Recent Best Controversial

  • Curtain Control Node.
    xydixX xydix

    @adds666
    I am still in "testing mode".
    I had some problems with the node, it stoped receiving messages but did always work with the button.
    Yesterday i built a new node and uploaded the sketch and it seems to work better.
    Here is the sketch i use, I changed the pin for the button due to missing digital pins on my pcb.
    And I am back on using digital pins for the stepper driver for the same reason.
    I greyed out buttonpin 2. I don't think it is needed.
    I also greyed out the heartbeat-part as I had problems. Just for testing. Don't know if it is suitable when using Home Assistant.

    /*
     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 8                     // fixed node number
    // Enable and select radio type attached
    #define MY_RADIO_RF24
    #define MY_RF24_PA_LEVEL RF24_PA_HIGH
    //#define MY_RADIO_RFM69
    
    #include <SPI.h>
    #include <MySensors.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 - Använd gammal version. testat med V0.9 och det funkar
    
    #define CHILD_ID 1                        // Id of the sensor child
    
    #define SN "Curtain control"
    #define SV "1.0"
    
    #define buttonPin1 A0                        // Arduino pin connected to buttonPin1
    //#define buttonPin2 A0                       // Arduino pin connected to buttonPin2 (fixed to ground)
    
    // Motor pin definitions
    #define motorPin1  2                        // IN1 on the ULN2003 driver 1
    #define motorPin2  3                        // 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(1000.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 ;
      }
      }
    
    My Project domoticz curtain control mysensors node

  • Curtain Control Node.
    xydixX xydix

    @adds666 What i can tell it was a long time since @AWI was active here.
    I use this sketch with my first bild since a couple of days.
    For me it works like a charm. But in my case I control the motor from analog pins just to test and it seems OK.
    No problem with the button.
    The only thing I don't like, is the calibration.
    I my case, using this on a blind, when calibrating, first it goes down, then i press the button, the blind stops at once and change it's direction and goes up. But when i reach the top level and want to stop it and save the state, it stops slow and pass the point i pressed the button and then reverse to the right spot. Problem is, the blind can't go further because it is in the top position.
    If it would be the other way around it wouldn't be a problem.
    Maybe i have the motor one the "wrong" side of the blind but when it is down the "downkey" in my HA is greyed out.
    When it i up the "upkey" it greyed out so that seems right.

    What is not working in your case?
    What motor do you use? I use 28BYJ-48 with ULN2003 and had to set stepper1.setMaxSpeed(2000.0); to stepper1.setMaxSpeed(1000.0); because the motor "slipped" at a speed of 2000.
    Like i wrote earlier in the thread I tried to figure out how to "dublicate" the sketch and ute it for two motors.
    I really don't know where to start to get this done. It would be awesome to use one arduino with two blinds.

    My Project domoticz curtain control mysensors node

  • Problem with Wind Speed sensor
    xydixX xydix

    Anyone got a working sketch for a pulse anenometer?
    I printed this. https://www.thingiverse.com/thing:2523343
    I used it with ESPHome as testing it and I got OK values.
    Now i would like to use it with mysensors.
    I tried @AWI s sketch but I get stange readings.
    Sometimes I get a very high value when is turns slow.

    Troubleshooting

  • Curtain Control Node.
    xydixX xydix

    @xydix
    To answer my own question the stepper runs fine from the analog pins.
    Next step is to find some intersted in the same thing and see if we could get the sketch adjusted to run two steppers.
    I will try when i get some time but I guess I will have problem to clone the calibration and store-to-eerprom-part.

    My Project domoticz curtain control mysensors node

  • Curtain Control Node.
    xydixX xydix

    @ton-rijnaard
    Hi. This was a problem for me to. The reason is the library changed name and updates was made.
    I use the library version 0.9.
    I have like zero skills in arduino. If you use the old library the button will work with the sketch i posted a moth ago.
    Looke here: https://github.com/JChristensen/JC_Button/releases
    Maybe some of the other older releases will work. Don't remember why o choose V0.9
    Look at 2.0.0, "This is a major release that is not backwards-compatible with previous releases."

    My Project domoticz curtain control mysensors node

  • 💬 MyPulse Sensor
    xydixX xydix

    @scalz
    I guess you have the answer to that question:point_up_2:?

    OpenHardware.io counter pulse sensor

  • Curtain Control Node.
    xydixX xydix

    Okey. This is an old thread but I hope it's ok I keep it alive.
    I just printed som parts for my blinds.
    I use a stepper motor (28BYJ-48 with ULN2003 Driver board) and this sketch found in this thread.
    The sketch is awesome.
    To my quiestion.
    I want to run 2 blinds at the same time from ONE node. Synchronized or maybe individual.
    Is this possible?
    There isn't any digital pins over for this when using button(s).
    I think i saw someone using analog pin connected to the ULN2003 someware.
    Is it possible to run 2 motors on one board?
    Really hope somone can answer som of my question.
    What modifications is needed in the sketch if this is possible.
    This is the sketch I use.

    /*
     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_RF24
    //#define MY_RADIO_RFM69
    
    #include <SPI.h>
    #include <MySensors.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 ;
    	}
      }
    
    My Project domoticz curtain control mysensors node

  • 💬 MyPulse Sensor
    xydixX xydix

    Hi. Thank you for sharing your board. It seems awesome. I got a question. When I read the BOM, I think I should use 100 ohm, 330 ohm and 1500 ohm resistor. When I look at the schematic picture it says 100k 330k. What resistor should I use?

    OpenHardware.io counter pulse sensor

  • 💬 Battery operated rain-gauge
    xydixX xydix

    @heizelmann Hi. Sorry if I wake an old thread.
    Do you still have your code?
    I am about to build a rain gauge and want it to run on battery.
    Your way to handle things is what I am looking for.
    Would you like to share your code?

    OpenHardware.io rain

  • smartSleep with 2.3.0, missing messages
    xydixX xydix

    Hi.
    I went from 2.1.1 to 2.3.0 hoping I would get a more stable network.
    When i did this I tried some OTA and went from sleep to smartSleep in some sketches.
    My problem. it's a binary sensor node reading a blinking LED.
    But if the LED blink too fast the node won't send the state change.
    I only get:

    718	2018-10-05 21:59:52	RX	5 - Pannrum	INTERNAL	C_INTERNAL	NO	I_POST_SLEEP_NOTIFICATION	0
    719	2018-10-05 21:59:52	RX	5 - Pannrum	1 - S_DOOR	C_SET	NO	V_TRIPPED	0
    720	2018-10-05 21:59:52	RX	5 - Pannrum	INTERNAL	C_INTERNAL	NO	I_BATTERY_LEVEL	100
    721	2018-10-05 21:59:52	RX	5 - Pannrum	INTERNAL	C_INTERNAL	NO	I_PRE_SLEEP_NOTIFICATION	50
    722	2018-10-05 21:59:53	RX	5 - Pannrum	INTERNAL	C_INTERNAL	NO	I_POST_SLEEP_NOTIFICATION	0
    723	2018-10-05 21:59:53	RX	5 - Pannrum	INTERNAL	C_INTERNAL	NO	I_BATTERY_LEVEL	100
    724	2018-10-05 21:59:53	RX	5 - Pannrum	INTERNAL	C_INTERNAL	NO	I_PRE_SLEEP_NOTIFICATION	50
    725	2018-10-05 21:59:54	RX	5 - Pannrum	INTERNAL	C_INTERNAL	NO	I_POST_SLEEP_NOTIFICATION	0
    726	2018-10-05 21:59:54	RX	5 - Pannrum	1 - S_DOOR	C_SET	NO	V_TRIPPED	1
    727	2018-10-05 21:59:54	RX	5 - Pannrum	INTERNAL	C_INTERNAL	NO	I_BATTERY_LEVEL	100
    728	2018-10-05 21:59:54	RX	5 - Pannrum	INTERNAL	C_INTERNAL	NO	I_PRE_SLEEP_NOTIFICATION	50
    

    This is from MYSController, what the gateway see.
    As you see sometimes i Only get the presleep, postsleep and battery, not the C_SET/ Value.

    Some from serial monitor but not the exact same time as the log above.

    51511 TSF:MSG:SEND,5-5-255-255,s=255,c=3,t=7,pt=0,l=0,sg=0,ft=2,st=OK:
    53624 !TSM:FPAR:NO REPLY
    53641 TSM:FPAR
    53706 TSF:MSG:SEND,5-5-255-255,s=255,c=3,t=7,pt=0,l=0,sg=0,ft=0,st=OK:
    55246 TSF:MSG:READ,4-4-5,s=255,c=3,t=8,pt=1,l=1,sg=0:1
    55312 TSF:MSG:FPAR OK,ID=4,D=2
    55803 TSM:FPAR:OK
    55820 TSM:ID
    55836 TSM:ID:OK
    55853 TSM:UPL
    55902 TSF:MSG:SEND,5-5-4-0,s=255,c=3,t=24,pt=1,l=1,sg=0,ft=0,st=OK:1
    56213 !TSF:SND:TNR
    56229 !TSF:SND:TNR
    57999 TSM:UPL
    58032 TSF:MSG:SEND,5-5-4-0,s=255,c=3,t=24,pt=1,l=1,sg=0,ft=0,st=OK:1
    60129 TSM:UPL
    60178 !TSF:MSG:SEND,5-5-4-0,s=255,c=3,t=24,pt=1,l=1,sg=0,ft=0,st=NACK:1
    61276 !TSF:SND:TNR
    62275 TSM:UPL
    62308 TSF:MSG:SEND,5-5-4-0,s=255,c=3,t=24,pt=1,l=1,sg=0,ft=1,st=OK:1
    64405 !TSM:UPL:FAIL
    64421 TSM:FPAR
    64471 TSF:MSG:SEND,5-5-255-255,s=255,c=3,t=7,pt=0,l=0,sg=0,ft=0,st=OK:
    64667 TSF:MSG:READ,4-4-5,s=255,c=3,t=8,pt=1,l=1,sg=0:1
    64733 TSF:MSG:FPAR OK,ID=4,D=2
    66322 !TSF:SND:TNR
    66584 TSM:FPAR:OK
    66600 TSM:ID
    66617 TSM:ID:OK
    66633 TSM:UPL
    66682 TSF:MSG:SEND,5-5-4-0,s=255,c=3,t=24,pt=1,l=1,sg=0,ft=0,st=OK:1
    68763 TSM:UPL
    68780 TSF:MSG:SEND,5-5-4-0,s=255,c=3,t=24,pt=1,l=1,sg=0,ft=0,st=OK:1
    70877 TSM:UPL
    70893 TSF:MSG:SEND,5-5-4-0,s=255,c=3,t=24,pt=1,l=1,sg=0,ft=0,st=OK:1
    70975 TSF:MSG:READ,0-4-5,s=255,c=3,t=25,pt=1,l=1,sg=0:2
    71041 TSF:MSG:PONG RECV,HP=2
    71073 TSM:UPL:OK
    71106 TSM:READY:ID=5,PAR=4,DIS=2
    71368 TSF:MSG:SEND,5-5-4-0,s=255,c=3,t=0,pt=1,l=1,sg=0,ft=0,st=OK:100
    71450 MCO:SLP:MS=0,SMS=1,I1=0,M1=1,I2=1,M2=1
    71516 TSF:MSG:SEND,5-5-4-0,s=255,c=3,t=32,pt=5,l=4,sg=0,ft=0,st=OK:100
    71712 TSF:TDI:TSL
    

    The sketch.

    /**
       The MySensors Arduino library handles the wireless radio link and protocol
       between your home built sensors/actuators and HA controller of choice.
       The sensors forms a self healing radio network with optional repeaters. Each
       repeater and gateway builds a routing tables in EEPROM which keeps track of the
       network topology allowing messages to be routed to nodes.
    
       Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
       Copyright (C) 2013-2015 Sensnology AB
       Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
    
       Documentation: http://www.mysensors.org
       Support Forum: http://forum.mysensors.org
    
       This program is free software; you can redistribute it and/or
       modify it under the terms of the GNU General Public License
       version 2 as published by the Free Software Foundation.
    
     *******************************
    
       DESCRIPTION
    
       Interrupt driven binary switch example with dual interrupts
       Author: Patrick 'Anticimex' Fallberg
       Connect one button or door/window reed switch between
       digitial I/O pin 3 (BUTTON_PIN below) and GND and the other
       one in similar fashion on digital I/O pin 2.
       This example is designed to fit Arduino Nano/Pro Mini
    
    */
    
    
    // Enable debug prints to serial monitor
    #define MY_DEBUG
    #define MY_BAUD_RATE 9600
    #define MY_SMART_SLEEP_WAIT_DURATION_MS 100
    
    #define MY_NODE_ID 5
    // Enable and select radio type attached
    #define MY_RADIO_NRF24
    //#define MY_RADIO_RFM69
    #define MY_RF24_PA_LEVEL RF24_PA_MAX
    
    #include <SPI.h>
    #include <MySensors.h>
    #include <Vcc.h>
    
    #define SKETCH_NAME "Pannrum"
    #define SKETCH_MAJOR_VER "1"
    #define SKETCH_MINOR_VER "0"
    
    #define PRIMARY_CHILD_ID 1
    #define SECONDARY_CHILD_ID 2
    
    #define PRIMARY_INPUT_PIN 2   // Arduino Digital I/O pin for button/reed switch
    #define SECONDARY_INPUT_PIN 3
    
    const float VccMin   = 1.9;           // Minimum expected Vcc level, in Volts. (NRF can only go to 1.9V)
    const float VccMax   = 3.3;           // Maximum expected Vcc level, in Volts.
    const float VccCorrection = 1.0 / 1.0; // Measured Vcc by multimeter divided by reported Vcc
    
    Vcc vcc(VccCorrection);
    
    // Change to V_LIGHT if you use S_LIGHT in presentation below
    MyMessage msg(PRIMARY_CHILD_ID, V_TRIPPED);
    MyMessage msg2(SECONDARY_CHILD_ID, V_TRIPPED);
    
    void setup()
    {
    
      // Setup the buttons
      pinMode(PRIMARY_INPUT_PIN, INPUT);
      pinMode(SECONDARY_INPUT_PIN, INPUT);
    
      // Activate internal pull-ups
      //  digitalWrite(INPUT1_PIN, HIGH);
    
    }
    
    void presentation() {
      // Send the sketch version information to the gateway and Controller
      sendSketchInfo(SKETCH_NAME, SKETCH_MAJOR_VER "." SKETCH_MINOR_VER);
    
      // Register binary input sensor to sensor_node (they will be created as child devices)
      // You can use S_DOOR, S_MOTION or S_LIGHT here depending on your usage.
      // If S_LIGHT is used, remember to update variable type you send in. See "msg" above.
      present(PRIMARY_CHILD_ID, S_DOOR);
      present(SECONDARY_CHILD_ID, S_DOOR);
    }
    
    // Loop will iterate on changes on the BUTTON_PINs
    void loop()
    {
      uint8_t value;
      static uint8_t sentValue = 2;
      static uint8_t sentValue2 = 2;
    
      // Short delay to allow buttons to properly settle
      wait(5);
    
      value = digitalRead(PRIMARY_INPUT_PIN);
    
      if (value != sentValue) {
        // Value has changed from last transmission, send the updated value
        send(msg.set(value == HIGH));
        sentValue = value;
      }
    
      value = digitalRead(SECONDARY_INPUT_PIN);
    
      if (value != sentValue2) {
        // Value has changed from last transmission, send the updated value
        send(msg2.set(value == HIGH));
        sentValue2 = value;
      }
    
    
      float  p = vcc.Read_Perc(VccMin, VccMax);
      sendBatteryLevel((uint8_t)p);
    
    
    // Sleep until something happens with the sensor
    if (isTransportReady()) {
      smartSleep(PRIMARY_INPUT_PIN-2, CHANGE, SECONDARY_INPUT_PIN-2, CHANGE, 0); // transport is OK, node can sleep
    }
    else {
      wait(5000); // transport is not operational, allow the transport layer to fix this
    }
    
    
    } 
    

    I tried This, just replacing all three files in the RF24 folder. Loading this to the sensor but it didn't help.

    Troubleshooting

  • 💬 Power Meter Pulse Sensor
    xydixX xydix

    It waswhat I thought too.
    As I said earlier, when I tested this my conclusion was, short blink, almost a flash will counted as a pulse (kWh) but it does something wrong with the calculation of instant power usage.
    A slower blink will correct this.
    My meeter gives a very short blink.

    Announcements

  • 💬 Power Meter Pulse Sensor
    xydixX xydix

    I am glad to hear it works for you too.

    Announcements

  • 💬 Power Meter Pulse Sensor
    xydixX xydix

    Nothing more.
    I use the same arduino, haven't uploaded anything new to it since i tried it last time.

    What I had to do was lower the sensitivity on the LM393 because at first the signal-LED glowed a bit but when i adjusted it to lower sensitivity and closed the door to get it totaly dark the led blinked exactly as the meeter.

    I have it on a bredboard and connected the cap between GND and to pin 3 so it is connected close to the arduino but i guess it shouldn't matter.

    Have you tried it?

    Announcements

  • 💬 Power Meter Pulse Sensor
    xydixX xydix

    Yes. I guess.
    I don't have anything to compare with but i think it is accurate.
    I have a 1000blink/kwh
    Example:
    Node send state every 20 sec.
    pulsecount: 8 pulses every 20 sec.
    Instant power in W is about 1400W

    8 pulses x 3 = pulses /minute =24
    24 pulses x 60 min = pulses /hour = 1440.

    Edit.
    Now I get a new value every 20 sec, before I didn't get any value (W) from the node at all because it was too high. I only received pulse count and kWh earlier.

    Announcements

  • 💬 Power Meter Pulse Sensor
    xydixX xydix

    I think i solved this.
    I don't know if it is a good solution.
    Maybe it is possible to solve in the code?
    I added a 0,1uf ceramic capacitor between DO and GND on the LM393.
    Then i tuned the LM393 until i had it blink as expected.

    I think, in my case the LED pulse from my meeter was to short, it gives a very short blink.
    Anyway.
    I tested it all day and it seems fine now.

    Announcements

  • Reliable communication.
    xydixX xydix

    How about RFM69W? 13dBm And RFM69HW? 20dBm. Wich one for battery nodes? Are there more alternatives? Have i seen a RFM69C somewhere? HW for the gateway?

    Development

  • Reliable communication.
    xydixX xydix

    @nca78 said in Reliable communication.:

    @xydix this is a good radio from EByte, but if "Gateway is low I think" means you have a lower power setting then you're not making use of the PA/LNA on that radio which is a shame. I have a similar radio, with 25-30cm thick concrete walls and signal manages to go around the walls.
    So I would check the power level of the gateway first, and if it doesn't solve the problem then you have to implement the resend, but no there doesn't seem to be a "right" way to do it. You just need to :

    • make sure ACK is enabled for the node (I think there is an automatic resend implemented in radio in this case)
    • check result of the send command, and if false sleep a little bit and send again, you can do this in a loop to try sending a few more times.

    I had my radio on high or max at first but experience it more stable now. After all, everything i send out from my gateway is ok. I have problem receiving from my nodes.
    Today i do not use ack on any node.
    May it be enough to enable ack to make the node try again if it doesn't receive the ack back?

    @rozpruwacz said in Reliable communication.:

    @xydix I had also problems with reliable comunication using nrf modules. I switched to rfm69 and it is much much better. It is easy to switch to rfm69 using this: https://www.mysensors.org/hardware/nrf2rfm69. But appart from that a good resend algorithm is also necessary. Unfortunately there is no one good resend algorithm for every use case, it depends on the node usage.

    I started with nrf because I was to cheap to buy RFM69, and didn't know if mysensors was something I would like.
    Then there was a lot of different versions, so i went for the NFR because it was easy. I am pretty happy with it but it isn't 100%.
    What should i choose? 433 or 868? Do they both got same features?

    Development

  • Reliable communication.
    xydixX xydix

    @nca78 said in Reliable communication.:

    Hello, @xydix

    you should not have any problem for such a short distance.
    Before checking acks and retrying to send I would check those:

    • problem with radio quality: what modules do you use on nodes and gateway ? Did you set the TX power to PA_MAX ?
    • problem with interferences: what channel do you use ? have you tried one of the channels outside of the wifi frequency ? (>=100)

    I got som concrete walls that might block the signal a little.
    For my gateway I use this radio. Bought it after watched a YouTube video, a guy compared radios.

    In my nodes I use various radios. Some bought from eBay, aliexpress, electrodragon.
    I tried different capacitors, some antenna mods.
    All nodes us PA_MAX. Gateway is low I think.
    My problem is receiving messages from nodes.
    I haven't changed the channel.
    It is so hard to know when a test/change give results. I might have a missed message once a week or something like that. This is based on when one of my motion sensors showing motion for a long time and there is no motion.
    A resend function solves the problem even if the actual problem is the hardware.

    Development

  • 💬 Power Meter Pulse Sensor
    xydixX xydix

    Okay. Really annoying. Check this.

    Received last pulse count from gw:2527
    Watt:121065
    22235 TSF:MSG:SEND,78-78-0-0,s=3,c=1,t=24,pt=5,l=4,sg=0,ft=0,st=OK:2539
    22246 TSF:MSG:SEND,78-78-0-0,s=2,c=1,t=18,pt=7,l=5,sg=0,ft=0,st=OK:2.5390
    Watt:121621
    42238 TSF:MSG:SEND,78-78-0-0,s=3,c=1,t=24,pt=5,l=4,sg=0,ft=0,st=OK:2551
    42250 TSF:MSG:SEND,78-78-0-0,s=2,c=1,t=18,pt=7,l=5,sg=0,ft=0,st=OK:2.5510
    Watt:121342
    62239 TSF:MSG:SEND,78-78-0-0,s=3,c=1,t=24,pt=5,l=4,sg=0,ft=0,st=OK:2563
    62251 TSF:MSG:SEND,78-78-0-0,s=2,c=1,t=18,pt=7,l=5,sg=0,ft=0,st=OK:2.5630
    Watt:121539
    82240 TSF:MSG:SEND,78-78-0-0,s=3,c=1,t=24,pt=5,l=4,sg=0,ft=0,st=OK:2575
    82251 TSF:MSG:SEND,78-78-0-0,s=2,c=1,t=18,pt=7,l=5,sg=0,ft=0,st=OK:2.5750
    Watt:121951
    102239 TSF:MSG:SEND,78-78-0-0,s=3,c=1,t=24,pt=5,l=4,sg=0,ft=0,st=OK:2589
    102250 TSF:MSG:SEND,78-78-0-0,s=2,c=1,t=18,pt=7,l=5,sg=0,ft=0,st=OK:2.5890
    Watt:122067
    122243 TSF:MSG:SEND,78-78-0-0,s=3,c=1,t=24,pt=5,l=4,sg=0,ft=0,st=OK:2601
    122254 TSF:MSG:SEND,78-78-0-0,s=2,c=1,t=18,pt=7,l=5,sg=0,ft=0,st=OK:2.6010
    

    The plus count seems OK, right?

    My energy meter is 1000 pluses /kwh

    Here is my sketch. I use Home assistant so i created three sensors for this as I don't think V_VAR1 is supported with S_POWER.
    Otherwise it is the standard example.

    /**
     * The MySensors Arduino library handles the wireless radio link and protocol
     * between your home built sensors/actuators and HA controller of choice.
     * The sensors forms a self healing radio network with optional repeaters. Each
     * repeater and gateway builds a routing tables in EEPROM which keeps track of the
     * network topology allowing messages to be routed to nodes.
     *
     * Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
     * Copyright (C) 2013-2015 Sensnology AB
     * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
     *
     * Documentation: http://www.mysensors.org
     * Support Forum: http://forum.mysensors.org
     *
     * This program is free software; you can redistribute it and/or
     * modify it under the terms of the GNU General Public License
     * version 2 as published by the Free Software Foundation.
     *
     *******************************
     *
     * REVISION HISTORY
     * Version 1.0 - Henrik EKblad
     *
     * DESCRIPTION
     * This sketch provides an example how to implement a distance sensor using HC-SR04
     * Use this sensor to measure KWH and Watt of your house meeter
     * You need to set the correct pulsefactor of your meeter (blinks per KWH).
     * The sensor starts by fetching current KWH value from gateway.
     * Reports both KWH and Watt back to gateway.
     *
     * Unfortunately millis() won't increment when the Arduino is in
     * sleepmode. So we cannot make this sensor sleep if we also want
     * to calculate/report watt-number.
     * http://www.mysensors.org/build/pulse_power
     */
    
    // Enable debug prints
    #define MY_DEBUG
    
    // Enable and select radio type attached
    #define MY_RADIO_NRF24
    //#define MY_RADIO_RFM69
    #define MY_NODE_ID 78
    #include <MySensors.h>
    
    #define DIGITAL_INPUT_SENSOR 3  // The digital input you attached your light sensor.  (Only 2 and 3 generates interrupt!)
    #define PULSE_FACTOR 1000       // Nummber of blinks per KWH of your meeter
    #define SLEEP_MODE false        // Watt-value can only be reported when sleep mode is false.
    #define MAX_WATT 20000          // Max watt value to report. This filetrs outliers.
    #define WATT_CHILD_ID 1              // Id of the sensor child
    #define KWH_CHILD_ID 2
    #define PC_CHILD_ID 3
    
    unsigned long SEND_FREQUENCY =
        20000; // Minimum time between send (in milliseconds). We don't wnat to spam the gateway.
    double ppwh = ((double)PULSE_FACTOR)/1000; // Pulses per watt hour
    bool pcReceived = false;
    volatile unsigned long pulseCount = 0;
    volatile unsigned long lastBlink = 0;
    volatile unsigned long watt = 0;
    unsigned long oldPulseCount = 0;
    unsigned long oldWatt = 0;
    double oldKwh;
    unsigned long lastSend;
    MyMessage wattMsg(WATT_CHILD_ID,V_WATT);
    MyMessage kwhMsg(KWH_CHILD_ID,V_KWH);
    MyMessage pcMsg(PC_CHILD_ID,V_VAR1);
    
    
    void setup()
    {
      // Fetch last known pulse count value from gw
      request(PC_CHILD_ID, V_VAR1);
    
      // Use the internal pullup to be able to hook up this sketch directly to an energy meter with S0 output
      // If no pullup is used, the reported usage will be too high because of the floating pin
      pinMode(DIGITAL_INPUT_SENSOR,INPUT_PULLUP);
    
      attachInterrupt(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR), onPulse, RISING);
      lastSend=millis();
    }
    
    void presentation()
    {
      // Send the sketch version information to the gateway and Controller
      sendSketchInfo("Energy Meter", "1.0");
    
      // Register this device as power sensor
      present(WATT_CHILD_ID, S_POWER);
      present(KWH_CHILD_ID, S_POWER);
      present(PC_CHILD_ID, S_CUSTOM);
    }
    
    void loop()
    {
      unsigned long now = millis();
      // Only send values at a maximum frequency or woken up from sleep
      bool sendTime = now - lastSend > SEND_FREQUENCY;
      if (pcReceived && (SLEEP_MODE || sendTime)) {
        // New watt value has been calculated
        if (!SLEEP_MODE && watt != oldWatt) {
          // Check that we dont get unresonable large watt value.
          // could hapen when long wraps or false interrupt triggered
          if (watt<((unsigned long)MAX_WATT)) {
            send(wattMsg.set(watt));  // Send watt value to gw
          }
          Serial.print("Watt:");
          Serial.println(watt);
          oldWatt = watt;
        }
    
        // Pulse cout has changed
        if (pulseCount != oldPulseCount) {
          send(pcMsg.set(pulseCount));  // Send pulse count value to gw
          double kwh = ((double)pulseCount/((double)PULSE_FACTOR));
          oldPulseCount = pulseCount;
          if (kwh != oldKwh) {
            send(kwhMsg.set(kwh, 4));  // Send kwh value to gw
            oldKwh = kwh;
          }
        }
        lastSend = now;
      } else if (sendTime && !pcReceived) {
        // No count received. Try requesting it again
        request(PC_CHILD_ID, V_VAR1);
        lastSend=now;
      }
    
      if (SLEEP_MODE) {
        sleep(SEND_FREQUENCY);
      }
    }
    
    void receive(const MyMessage &message)
    {
      if (message.type==V_VAR1) {
        pulseCount = oldPulseCount = message.getLong();
        Serial.print("Received last pulse count from gw:");
        Serial.println(pulseCount);
        pcReceived = true;
      }
    }
    
    void onPulse()
    {
      if (!SLEEP_MODE) {
        unsigned long newBlink = micros();
        unsigned long interval = newBlink-lastBlink;
        if (interval<10000L) { // Sometimes we get interrupt on RISING
          return;
        }
        watt = (3600000000.0 /interval) / ppwh;
        lastBlink = newBlink;
      }
      pulseCount++;
    }
    
    

    Anyone got any ideas?
    BTW. First i tried the original example sketch, unmodified, with the same result.

    Announcements

  • Reliable communication.
    xydixX xydix

    I know, there are tons of threads on this subject.
    Most of them are old, back on 1.5.*
    I have some nodes. The messages arrives 95% of the times. I would like 100% :)
    I know, more repeaters might help but i have 4-10 meters between my nodes and my gateway.
    Is it possible to acheave reliable communication?
    I've seen examples on resend, but is there a "right" way to do it? It seems you have to do it different depending of what type av node it is?
    I am on 2.1.1 right now. Are there any difference in 2.2.0 in this area?
    Other stuff is often very well explained. Like how to connect stuff and the battery measurement part is so easy with pictures like a child could understand it.

    Development
  • Login

  • Don't have an account? Register

  • Login or register to search.
  • First post
    Last post
0
  • MySensors
  • OpenHardware.io
  • Categories
  • Recent
  • Tags
  • Popular