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. Troubleshooting
  3. Momentary button to control lights

Momentary button to control lights

Scheduled Pinned Locked Moved Troubleshooting
29 Posts 6 Posters 7.0k Views 7 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.
  • MasMatM Offline
    MasMatM Offline
    MasMat
    wrote on last edited by
    #1

    I have wrestled with this one a lot already.
    The idea: one battery powered node, with one push button (momentary).
    I want it to toggle the lights (controled by another node). Also I want the node to report battery status only when the button is pressed, otherwise sleep.
    I can't find what's wrong with my code. The node will not sleep, nor will it send messages when button is pressed. It will however check battery status on constant loop.
    Here's my code.
    If there's an easier way, I would GLADLY hear it.

    // Enable debug prints to serial monitor
    #define MY_DEBUG
    
    // Enable and select radio type attached
    #define MY_RADIO_NRF24
    //#define MY_RADIO_RFM69
    #define MY_NODE_ID 7
    
    #include <MySensors.h>
    
    int BATTERY_SENSE_PIN = A0;  // select the input pin for the battery sense point
    
    //unsigned long SLEEP_TIME = 900000;  // sleep time between reads (seconds * 1000 milliseconds)
    int oldBatteryPcnt = 0;
    
    #define CHILD_ID_BUTTON1 3
    //#define SECONDARY_CHILD_ID 4
    
    #define BUTTON_PIN 2   // Arduino Digital I/O pin for button/reed switch
    //#define SECONDARY_BUTTON_PIN 3 // Arduino Digital I/O pin for button/reed switch
    
    // Change to V_LIGHT if you use S_LIGHT in presentation below
    MyMessage msg(CHILD_ID_BUTTON1, V_TRIPPED);
    //MyMessage msg2(SECONDARY_CHILD_ID, V_TRIPPED);
    
    void setup()
    {
    	// Setup the buttons
    	pinMode(BUTTON_PIN, INPUT);
    	//pinMode(SECONDARY_BUTTON_PIN, INPUT);
    
    	// Activate internal pull-ups
    	digitalWrite(BUTTON_PIN, HIGH);
    	//digitalWrite(SECONDARY_BUTTON_PIN, HIGH);
    
      // use the 1.1 V internal reference
      #if defined(__AVR_ATmega2560__)
      analogReference(INTERNAL1V1);
      #else
      analogReference(INTERNAL);
      #endif
    }
    
    void presentation()
    {
      // Send the sketch version information to the gateway
      sendSketchInfo("WCNappiBAT", "vMasi020717");
    
    	// 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(CHILD_ID_BUTTON1, 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;
      int NumberPushes = 0;
    	//static uint8_t sentValue2=2;
    
    	// Short delay to allow buttons to properly settle
    	delay(20);
    
    	value = digitalRead(BUTTON_PIN);
    
    	if (value != sentValue) {
    		// Value has changed from last transmission, send the updated value
        NumberPushes++;
        Serial.println("Button counter:  ");
        Serial.print(NumberPushes);
        
        if (NumberPushes % 4 == 0) {
        send(msg.set(value==HIGH));
        Serial.println("Sent Button ON");
        }
    		
    		sentValue = value;
    	}
    
      // get the battery Voltage
      int sensorValue = analogRead(BATTERY_SENSE_PIN);
    #ifdef MY_DEBUG
      Serial.println(sensorValue);
    #endif
    
      // 1M, 470K divider across battery and using internal ADC ref of 1.1V
      // Sense point is bypassed with 0.1 uF cap to reduce noise at that point
      // ((1e6+470e3)/470e3)*1.1 = Vmax = 3.44 Volts
      // 3.44/1023 = Volts per bit = 0.003363075
    
      int batteryPcnt = sensorValue / 10;
    
    #ifdef MY_DEBUG
      float batteryV  = sensorValue * 0.003363075;
      Serial.print("Battery Voltage: ");
      Serial.print(batteryV);
      Serial.println(" V");
    
      Serial.print("Battery percent: ");
      Serial.print(batteryPcnt);
      Serial.println(" %");
    #endif
    
      //if (oldBatteryPcnt != batteryPcnt) {
        // Power up radio after sleep
        sendBatteryLevel(batteryPcnt);
        //oldBatteryPcnt = batteryPcnt;
      //}
    
    	// Sleep until something happens with the sensor
    	sleep(BUTTON_PIN-2, CHANGE, 0);
    }
    
    1 Reply Last reply
    0
    • T Offline
      T Offline
      Topdawg2881
      wrote on last edited by
      #2

      To start off with I would place the button on an interrupt pin and add an interrupt into the sketch. This way the interrupt can trigger the read of the battery voltage sense and also send that information along with the button change status.

      MasMatM 1 Reply Last reply
      0
      • T Topdawg2881

        To start off with I would place the button on an interrupt pin and add an interrupt into the sketch. This way the interrupt can trigger the read of the battery voltage sense and also send that information along with the button change status.

        MasMatM Offline
        MasMatM Offline
        MasMat
        wrote on last edited by
        #3

        @Topdawg2881 The button is on pin2 (=interrupt 0).
        I have a motion sensor that doesn't require this, but I will add

        #define INTERRUPT BUTTON_PIN-2

        Is that enough?

        1 Reply Last reply
        0
        • T Offline
          T Offline
          Topdawg2881
          wrote on last edited by
          #4

          Someone better than me may be able to help further, but another thing you define NumberPushes as equal to 0 in the loop function. Every time the loop runs through it will set it equal to 0. I would define the integer as equal to 0 in the setup or prior to the setup so that your NumberPushes ++ function will actually count correctly.
          Also what does your debug info look like? If I remember correctly if you do not connect to the gateway the loop will not run correctly.

          MasMatM 1 Reply Last reply
          1
          • T Topdawg2881

            Someone better than me may be able to help further, but another thing you define NumberPushes as equal to 0 in the loop function. Every time the loop runs through it will set it equal to 0. I would define the integer as equal to 0 in the setup or prior to the setup so that your NumberPushes ++ function will actually count correctly.
            Also what does your debug info look like? If I remember correctly if you do not connect to the gateway the loop will not run correctly.

            MasMatM Offline
            MasMatM Offline
            MasMat
            wrote on last edited by
            #5

            @Topdawg2881 Great point! Thanks for lending your eyes.
            Moving the numberPushes out of 'loop'. I'll see what it does. I'm also working to simplify the way the presses toggle between sending on-off.

            1 Reply Last reply
            0
            • MasMatM Offline
              MasMatM Offline
              MasMat
              wrote on last edited by
              #6

              Tried moving the numberPushes. Not working. I decided to tackle the "toggle problem" another way. Still no joy.
              Anyone have time to check my writing, much appreciated. Also if someone has code that works to make a momentary switch work like a toggle, that would be greatly appreciated.

              // Enable debug prints to serial monitor
              #define MY_DEBUG
              
              // Enable and select radio type attached
              #define MY_RADIO_NRF24
              //#define MY_RADIO_RFM69
              #define MY_NODE_ID 7
              
              #include <MySensors.h>
              
              int BATTERY_SENSE_PIN = A0;  // select the input pin for the battery sense point
              
              //unsigned long SLEEP_TIME = 900000;  // sleep time between reads (seconds * 1000 milliseconds)
              int oldBatteryPcnt = 0;
              
              #define CHILD_ID_BUTTON1 3
              //#define SECONDARY_CHILD_ID 4
              
              #define BUTTON_PIN 2   // Arduino Digital I/O pin for button/reed switch
              //#define SECONDARY_BUTTON_PIN 3 // Arduino Digital I/O pin for button/reed switch
              
              #define INTERRUPT BUTTON_PIN-2
              
              // Change to V_LIGHT if you use S_LIGHT in presentation below
              MyMessage msg(CHILD_ID_BUTTON1, V_TRIPPED);
              //MyMessage msg2(SECONDARY_CHILD_ID, V_TRIPPED);
              
              int tripped = 1;
              int lastStatus = 1;
              int numberPushes = 0;
              
              int light1 = LOW;      // the current state of the output pin
              int reading;           // the current reading from the input pin
              int previous = HIGH;    // the previous reading from the input pin
              
              // the follow variables are long's because the time, measured in miliseconds,
              // will quickly become a bigger number than can be stored in an int.
              long time = 0;         // the last time the output pin was toggled
              long debounce = 400;   // the debounce time, increase if the output flickers
              long batteryinterval = 10000;
              
              
              void setup()
              {
              	// Setup the buttons
              	pinMode(BUTTON_PIN, INPUT);
              	//pinMode(SECONDARY_BUTTON_PIN, INPUT);
              
              	// Activate internal pull-ups
              	digitalWrite(BUTTON_PIN, HIGH);
              	//digitalWrite(SECONDARY_BUTTON_PIN, HIGH);
              
                // use the 1.1 V internal reference
                #if defined(__AVR_ATmega2560__)
                analogReference(INTERNAL1V1);
                #else
                analogReference(INTERNAL);
                #endif
              }
              
              void presentation()
              {
                // Send the sketch version information to the gateway
                sendSketchInfo("WCNappiBAT", "vMasi030717");
              
              	// 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(CHILD_ID_BUTTON1, S_DOOR);
              	//present(SECONDARY_CHILD_ID, S_DOOR);
              }
              
              // Loop will iterate on changes on the BUTTON_PINs
              void loop()
              {
              // Another approach
              
              reading = digitalRead(BUTTON_PIN);
              
                // if the input just went from LOW and HIGH and we've waited long enough
                // to ignore any noise on the circuit, toggle the output pin and remember
                // the time
                if (reading == HIGH && previous == LOW && millis() - time > debounce) {
                  if (light1 == LOW)
                    light1 = HIGH && send(msg.set("1"));
                    
                    //Serial.println("Switching on");
                  else
                    light1 = LOW && send(msg.set("0"));
                    
                  }
                  
              Serial.println("Switch toggling");
              delay (100);
                previous = reading;
              
              
              // if (millis() - time > batteryinterval) {
              
                // get the battery Voltage
                int sensorValue = analogRead(BATTERY_SENSE_PIN);
              #ifdef MY_DEBUG
                Serial.println(sensorValue);
              #endif
              
                // 1M, 470K divider across battery and using internal ADC ref of 1.1V
                // Sense point is bypassed with 0.1 uF cap to reduce noise at that point
                // ((1e6+470e3)/470e3)*1.1 = Vmax = 3.44 Volts
                // 3.44/1023 = Volts per bit = 0.003363075
              
                int batteryPcnt = sensorValue / 10;
              
              #ifdef MY_DEBUG
                float batteryV  = sensorValue * 0.003363075;
                Serial.print("Battery Voltage: ");
                Serial.print(batteryV);
                Serial.println(" V");
              
                Serial.print("Battery percent: ");
                Serial.print(batteryPcnt);
                Serial.println(" %");
              #endif
              
                //if (oldBatteryPcnt != batteryPcnt) {
                  // Power up radio after sleep
                  sendBatteryLevel(batteryPcnt);
                  //oldBatteryPcnt = batteryPcnt;
                //}
               // }
              
                    time = millis();   
              
              	// Sleep until something happens with the sensor
              	sleep(BUTTON_PIN-2, FALLING, 0);
              }
              
              Boots33B 1 Reply Last reply
              0
              • gohanG Offline
                gohanG Offline
                gohan
                Mod
                wrote on last edited by
                #7

                Why do you use button_pin and button_pin-2?

                mfalkviddM 1 Reply Last reply
                0
                • gohanG gohan

                  Why do you use button_pin and button_pin-2?

                  mfalkviddM Offline
                  mfalkviddM Offline
                  mfalkvidd
                  Mod
                  wrote on last edited by
                  #8

                  @gohan BUTTON_PIN-2 was used in some early MySensors examples instead of digitalPinToInterrupt(BUTTON_PIN). Very ugly and we have gotten rid of it in the current examples but early users could still have sketches with that code.

                  1 Reply Last reply
                  0
                  • MasMatM MasMat

                    Tried moving the numberPushes. Not working. I decided to tackle the "toggle problem" another way. Still no joy.
                    Anyone have time to check my writing, much appreciated. Also if someone has code that works to make a momentary switch work like a toggle, that would be greatly appreciated.

                    // Enable debug prints to serial monitor
                    #define MY_DEBUG
                    
                    // Enable and select radio type attached
                    #define MY_RADIO_NRF24
                    //#define MY_RADIO_RFM69
                    #define MY_NODE_ID 7
                    
                    #include <MySensors.h>
                    
                    int BATTERY_SENSE_PIN = A0;  // select the input pin for the battery sense point
                    
                    //unsigned long SLEEP_TIME = 900000;  // sleep time between reads (seconds * 1000 milliseconds)
                    int oldBatteryPcnt = 0;
                    
                    #define CHILD_ID_BUTTON1 3
                    //#define SECONDARY_CHILD_ID 4
                    
                    #define BUTTON_PIN 2   // Arduino Digital I/O pin for button/reed switch
                    //#define SECONDARY_BUTTON_PIN 3 // Arduino Digital I/O pin for button/reed switch
                    
                    #define INTERRUPT BUTTON_PIN-2
                    
                    // Change to V_LIGHT if you use S_LIGHT in presentation below
                    MyMessage msg(CHILD_ID_BUTTON1, V_TRIPPED);
                    //MyMessage msg2(SECONDARY_CHILD_ID, V_TRIPPED);
                    
                    int tripped = 1;
                    int lastStatus = 1;
                    int numberPushes = 0;
                    
                    int light1 = LOW;      // the current state of the output pin
                    int reading;           // the current reading from the input pin
                    int previous = HIGH;    // the previous reading from the input pin
                    
                    // the follow variables are long's because the time, measured in miliseconds,
                    // will quickly become a bigger number than can be stored in an int.
                    long time = 0;         // the last time the output pin was toggled
                    long debounce = 400;   // the debounce time, increase if the output flickers
                    long batteryinterval = 10000;
                    
                    
                    void setup()
                    {
                    	// Setup the buttons
                    	pinMode(BUTTON_PIN, INPUT);
                    	//pinMode(SECONDARY_BUTTON_PIN, INPUT);
                    
                    	// Activate internal pull-ups
                    	digitalWrite(BUTTON_PIN, HIGH);
                    	//digitalWrite(SECONDARY_BUTTON_PIN, HIGH);
                    
                      // use the 1.1 V internal reference
                      #if defined(__AVR_ATmega2560__)
                      analogReference(INTERNAL1V1);
                      #else
                      analogReference(INTERNAL);
                      #endif
                    }
                    
                    void presentation()
                    {
                      // Send the sketch version information to the gateway
                      sendSketchInfo("WCNappiBAT", "vMasi030717");
                    
                    	// 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(CHILD_ID_BUTTON1, S_DOOR);
                    	//present(SECONDARY_CHILD_ID, S_DOOR);
                    }
                    
                    // Loop will iterate on changes on the BUTTON_PINs
                    void loop()
                    {
                    // Another approach
                    
                    reading = digitalRead(BUTTON_PIN);
                    
                      // if the input just went from LOW and HIGH and we've waited long enough
                      // to ignore any noise on the circuit, toggle the output pin and remember
                      // the time
                      if (reading == HIGH && previous == LOW && millis() - time > debounce) {
                        if (light1 == LOW)
                          light1 = HIGH && send(msg.set("1"));
                          
                          //Serial.println("Switching on");
                        else
                          light1 = LOW && send(msg.set("0"));
                          
                        }
                        
                    Serial.println("Switch toggling");
                    delay (100);
                      previous = reading;
                    
                    
                    // if (millis() - time > batteryinterval) {
                    
                      // get the battery Voltage
                      int sensorValue = analogRead(BATTERY_SENSE_PIN);
                    #ifdef MY_DEBUG
                      Serial.println(sensorValue);
                    #endif
                    
                      // 1M, 470K divider across battery and using internal ADC ref of 1.1V
                      // Sense point is bypassed with 0.1 uF cap to reduce noise at that point
                      // ((1e6+470e3)/470e3)*1.1 = Vmax = 3.44 Volts
                      // 3.44/1023 = Volts per bit = 0.003363075
                    
                      int batteryPcnt = sensorValue / 10;
                    
                    #ifdef MY_DEBUG
                      float batteryV  = sensorValue * 0.003363075;
                      Serial.print("Battery Voltage: ");
                      Serial.print(batteryV);
                      Serial.println(" V");
                    
                      Serial.print("Battery percent: ");
                      Serial.print(batteryPcnt);
                      Serial.println(" %");
                    #endif
                    
                      //if (oldBatteryPcnt != batteryPcnt) {
                        // Power up radio after sleep
                        sendBatteryLevel(batteryPcnt);
                        //oldBatteryPcnt = batteryPcnt;
                      //}
                     // }
                    
                          time = millis();   
                    
                    	// Sleep until something happens with the sensor
                    	sleep(BUTTON_PIN-2, FALLING, 0);
                    }
                    
                    Boots33B Offline
                    Boots33B Offline
                    Boots33
                    Hero Member
                    wrote on last edited by
                    #9

                    @MasMat Your remote switch node can never be sure if the light on the slave node is on or off (it may have been changed by the controller)

                    To toggle a light from a remote I have found it easiest to place the toggle code in the node that controls the light not in the remote switch. You can then just send a node to node message from your remote to trigger the toggle.

                    You could also use a node to node request to get the current state of the light but I think you will find it simpler using the first method.

                    Without seeing your light controller node sketch it is hard to be specific but a very simple sketch could be like bellow.
                    You can see all the work is done in the receive function.
                    If the message is from your controller (through the gateway node 0) it will just set the light to the arriving state.
                    If the message is from your remote (node 7) then it will toggle the light state.

                    /* This sketch is to control a light and also
                     *  allow control from a remote switch 
                    */
                    
                    // Enable debug prints to serial monitor
                    #define MY_DEBUG
                    
                    // Enable and select radio type attached
                    #define MY_RADIO_NRF24
                    
                    #include <MySensors.h>
                    
                    #define LIGHT_PIN  6             // Arduino Digital  pin connected to mosfet or relay that controls light
                    #define LIGHT_ON 1                 // Output value to write to turn on attached mosfet
                    #define LIGHT_OFF 0                // Output value to write to turn off attached mosfet
                    #define CHILD_ID_LIGHT 1
                    
                    bool state = 0;                        // State holder for light 
                    
                    MyMessage msg(CHILD_ID_LIGHT, V_STATUS);
                    
                    void setup() {
                      pinMode(LIGHT_PIN, OUTPUT);            //set light pin as output
                      digitalWrite(LIGHT_PIN, LIGHT_OFF);    //   make sure light is off at startup
                    }
                    
                    void presentation()  {
                      // Send the sketch version information to the gateway and Controller
                      sendSketchInfo("Light controller", "1.0");
                      // Register all sensors to gateway (they will be created as child devices)
                      present(CHILD_ID_LIGHT, S_BINARY, "House Light");
                      }
                    
                    void loop()
                    { 
                    
                    }
                    
                    
                    /*-------------------------start of functions-------------------*/
                    
                    void receive(const MyMessage &message) {
                    
                    if (message.type == V_STATUS) {                                  // check that message is for binary switch
                      if (message.sender == 0) {                                     // check if message is from gateway (node 0)   
                           state = message.getBool();
                           digitalWrite(LIGHT_PIN, state ? LIGHT_ON : LIGHT_OFF); // Set Light A to the new state
                      } 
                      else if (message.sender == 7) {                                  // message is from  remote (node 7)
                            state = !state;                                         // toggle light state
                            digitalWrite(LIGHT_PIN, state ? LIGHT_ON : LIGHT_OFF); // Set Light A to the new state
                            send(msg.set(state), false);                            //Message the gateway so controller will be aware of the change. No ack
                       }
                      } 
                        /*-------Write some debug info-----*/
                    #ifdef MY_DEBUG
                        Serial.print("Incoming change for sensor:");
                        Serial.print(message.sensor);
                        Serial.print(" from node: ");
                        Serial.println(message.sender);
                    #endif  
                    }
                    
                    MasMatM 1 Reply Last reply
                    0
                    • Boots33B Boots33

                      @MasMat Your remote switch node can never be sure if the light on the slave node is on or off (it may have been changed by the controller)

                      To toggle a light from a remote I have found it easiest to place the toggle code in the node that controls the light not in the remote switch. You can then just send a node to node message from your remote to trigger the toggle.

                      You could also use a node to node request to get the current state of the light but I think you will find it simpler using the first method.

                      Without seeing your light controller node sketch it is hard to be specific but a very simple sketch could be like bellow.
                      You can see all the work is done in the receive function.
                      If the message is from your controller (through the gateway node 0) it will just set the light to the arriving state.
                      If the message is from your remote (node 7) then it will toggle the light state.

                      /* This sketch is to control a light and also
                       *  allow control from a remote switch 
                      */
                      
                      // Enable debug prints to serial monitor
                      #define MY_DEBUG
                      
                      // Enable and select radio type attached
                      #define MY_RADIO_NRF24
                      
                      #include <MySensors.h>
                      
                      #define LIGHT_PIN  6             // Arduino Digital  pin connected to mosfet or relay that controls light
                      #define LIGHT_ON 1                 // Output value to write to turn on attached mosfet
                      #define LIGHT_OFF 0                // Output value to write to turn off attached mosfet
                      #define CHILD_ID_LIGHT 1
                      
                      bool state = 0;                        // State holder for light 
                      
                      MyMessage msg(CHILD_ID_LIGHT, V_STATUS);
                      
                      void setup() {
                        pinMode(LIGHT_PIN, OUTPUT);            //set light pin as output
                        digitalWrite(LIGHT_PIN, LIGHT_OFF);    //   make sure light is off at startup
                      }
                      
                      void presentation()  {
                        // Send the sketch version information to the gateway and Controller
                        sendSketchInfo("Light controller", "1.0");
                        // Register all sensors to gateway (they will be created as child devices)
                        present(CHILD_ID_LIGHT, S_BINARY, "House Light");
                        }
                      
                      void loop()
                      { 
                      
                      }
                      
                      
                      /*-------------------------start of functions-------------------*/
                      
                      void receive(const MyMessage &message) {
                      
                      if (message.type == V_STATUS) {                                  // check that message is for binary switch
                        if (message.sender == 0) {                                     // check if message is from gateway (node 0)   
                             state = message.getBool();
                             digitalWrite(LIGHT_PIN, state ? LIGHT_ON : LIGHT_OFF); // Set Light A to the new state
                        } 
                        else if (message.sender == 7) {                                  // message is from  remote (node 7)
                              state = !state;                                         // toggle light state
                              digitalWrite(LIGHT_PIN, state ? LIGHT_ON : LIGHT_OFF); // Set Light A to the new state
                              send(msg.set(state), false);                            //Message the gateway so controller will be aware of the change. No ack
                         }
                        } 
                          /*-------Write some debug info-----*/
                      #ifdef MY_DEBUG
                          Serial.print("Incoming change for sensor:");
                          Serial.print(message.sensor);
                          Serial.print(" from node: ");
                          Serial.println(message.sender);
                      #endif  
                      }
                      
                      MasMatM Offline
                      MasMatM Offline
                      MasMat
                      wrote on last edited by MasMat
                      #10

                      @Boots33 Will try that.
                      My idea was to "let the switch be dumb" sending alternating 1 or 0. People tend to push on buttons until something happens :)

                      Also I'm using this sketch as a run-up to building a two button remote.

                      I can easily access the code the receiving node and have the remote node "just send 1or0" every time it's pushed?
                      It will need more code if I have two buttons.

                      PS where can I find the docs for "message.sender & message.destination" options?

                      mfalkviddM Boots33B 2 Replies Last reply
                      0
                      • MasMatM MasMat

                        @Boots33 Will try that.
                        My idea was to "let the switch be dumb" sending alternating 1 or 0. People tend to push on buttons until something happens :)

                        Also I'm using this sketch as a run-up to building a two button remote.

                        I can easily access the code the receiving node and have the remote node "just send 1or0" every time it's pushed?
                        It will need more code if I have two buttons.

                        PS where can I find the docs for "message.sender & message.destination" options?

                        mfalkviddM Offline
                        mfalkviddM Offline
                        mfalkvidd
                        Mod
                        wrote on last edited by
                        #11

                        @MasMat I'm not sure if there is a more user-friendy documentation somewhere, but the source code has some information: https://github.com/mysensors/MySensors/blob/ff0953dd05b4f5e52e7d2c39ad23d207c896ea5e/core/MyMessage.h#L345

                        1 Reply Last reply
                        1
                        • MasMatM MasMat

                          @Boots33 Will try that.
                          My idea was to "let the switch be dumb" sending alternating 1 or 0. People tend to push on buttons until something happens :)

                          Also I'm using this sketch as a run-up to building a two button remote.

                          I can easily access the code the receiving node and have the remote node "just send 1or0" every time it's pushed?
                          It will need more code if I have two buttons.

                          PS where can I find the docs for "message.sender & message.destination" options?

                          Boots33B Offline
                          Boots33B Offline
                          Boots33
                          Hero Member
                          wrote on last edited by Boots33
                          #12

                          @MasMat said in Momentary button to control lights:

                          @Boots33 Will try that.
                          My idea was to "let the switch be dumb" sending alternating 1 or 0.

                          Yes that is the best way. But it doesn't really need to change from 1 or 0 it can just send the same thing all the time.

                          Also I'm using this sketch as a run-up to building a two button remote.
                          I can easily access the code the receiving node and have the remote node "just >send 1or0" every time it's pushed?

                          In the receive function of my sketch you can see that it will toggle on any message from node 7.
                          So it does not matter whether you send a 1 or 0 it will still toggle. This will make your switch code simpler, it does not need to know what the current state is it can for example just send a 1 every time the button is pushed and the light will toggle.

                          It will need more code if I have two buttons.

                          Multiple buttons will be fine. you will just need to use message.sensor in the receive function to test for which child sensor the message is for.

                          PS where can I find the docs for "message.sender & message.destination" >options?

                          The core files as linked to by @mfalkvidd are the place to look.

                          I used most of what you will need in previous posts and projects, have a read thru these.

                          LCD Node - display temp from other sensor - How?

                          Synchronising Light switch

                          Outdoors Touch Switch light controller

                          Display node: how to set up

                          AC Power controller with node to node remotes

                          MasMatM 1 Reply Last reply
                          1
                          • Boots33B Boots33

                            @MasMat said in Momentary button to control lights:

                            @Boots33 Will try that.
                            My idea was to "let the switch be dumb" sending alternating 1 or 0.

                            Yes that is the best way. But it doesn't really need to change from 1 or 0 it can just send the same thing all the time.

                            Also I'm using this sketch as a run-up to building a two button remote.
                            I can easily access the code the receiving node and have the remote node "just >send 1or0" every time it's pushed?

                            In the receive function of my sketch you can see that it will toggle on any message from node 7.
                            So it does not matter whether you send a 1 or 0 it will still toggle. This will make your switch code simpler, it does not need to know what the current state is it can for example just send a 1 every time the button is pushed and the light will toggle.

                            It will need more code if I have two buttons.

                            Multiple buttons will be fine. you will just need to use message.sensor in the receive function to test for which child sensor the message is for.

                            PS where can I find the docs for "message.sender & message.destination" >options?

                            The core files as linked to by @mfalkvidd are the place to look.

                            I used most of what you will need in previous posts and projects, have a read thru these.

                            LCD Node - display temp from other sensor - How?

                            Synchronising Light switch

                            Outdoors Touch Switch light controller

                            Display node: how to set up

                            AC Power controller with node to node remotes

                            MasMatM Offline
                            MasMatM Offline
                            MasMat
                            wrote on last edited by
                            #13

                            @Boots33 I checked out your links. I love the outdoor touch controller!! That's awesome!

                            I'm trying to figure out the "switch"-function, but Mysensors-docs nor Google cant find much.
                            I'm trying to figure out how switch=>case works. I could use that to further my one (and two or more!) button remote. Where I get lost is why "case 4" is completely different from the other three?

                            Any advice?

                            Boots33B 1 Reply Last reply
                            0
                            • MasMatM MasMat

                              @Boots33 I checked out your links. I love the outdoor touch controller!! That's awesome!

                              I'm trying to figure out the "switch"-function, but Mysensors-docs nor Google cant find much.
                              I'm trying to figure out how switch=>case works. I could use that to further my one (and two or more!) button remote. Where I get lost is why "case 4" is completely different from the other three?

                              Any advice?

                              Boots33B Offline
                              Boots33B Offline
                              Boots33
                              Hero Member
                              wrote on last edited by
                              #14

                              @MasMat said in Momentary button to control lights:

                              I'm trying to figure out the "switch"-function, but Mysensors-docs nor Google cant find much.
                              I'm trying to figure out how switch=>case works.

                              the switch/case is a standard arduino function. It can be very useful and sometimes much neater than using multiple if then else statements.

                              I could use that to further my one (and two or more!) button remote.

                              Yes it is well suited to that task.

                              Where I get lost is why "case 4" is completely different from the other three?

                              Any advice?

                              Is it this you are referring to

                              case 4:
                                       groupState = !groupState ;                   //Toggle the state
                                       send(msg.set(groupState), false);     // send new state to controller, no ack requested
                                       tone(buzzerPin, 1200, 60);                  //Play short beep to acknowledge touch
                                       break;    
                              

                              The first three case statements are sending direct node to node messages which are handled by the receiving node. The case 4 code is simply sending a standard binary switch message to my controller (Domoticz) and toggles the state of the switch in domoticz. I have that one switch set up as a group control switch in Domoticz so it turns on/off several light nodes at the same time. Sort of like a master control switch.

                              As i indicated in that original post the sketch was still in it's early testing stages. While I still have not completely finished the project yet it has been out in the garden for some months and has shown no false triggers from either rain or even birds landing on the touch pad.

                              Hope that helps. feel free to ask if you require any more info. MySensors node to node messages are really quite flexible once you get the hang of them. :)

                              1 Reply Last reply
                              2
                              • MasMatM Offline
                                MasMatM Offline
                                MasMat
                                wrote on last edited by
                                #15

                                All right. Been banging my head at this all day again.
                                I seem to be sending the message from the node OK, but the receiving node appears to have intermittent problems. And for some reason, my gateway reboots at some "combinations".
                                I have gone thru the send-node & receive-node code tens of times.
                                Help & ideas appreciated. Plz excuse the finnish in the code :)

                                Send-node

                                // Enable debug prints to serial monitor
                                #define MY_DEBUG
                                
                                // Enable and select radio type attached
                                #define MY_RADIO_NRF24
                                //#define MY_RADIO_RFM69
                                #define MY_NODE_ID 7
                                
                                #include <MySensors.h>
                                
                                //destination specs
                                #define WC_SENSOR_ID 3
                                #define WC_NODE_ID 3
                                
                                int BATTERY_SENSE_PIN = A0;  // select the input pin for the battery sense point
                                int oldBatteryPcnt = 0;
                                
                                #define CHILD_ID_BUTTON1 3
                                #define BUTTON_PIN 2   //pin for button
                                //#define INTERRUPT BUTTON_PIN
                                
                                MyMessage msg(CHILD_ID_BUTTON1, V_STATUS);
                                
                                int tripped = 1;
                                int lastStatus = 1;
                                int numberPushes = 0;
                                int sentCounter = 0;
                                
                                int light1 = LOW;      // the current state of the output pin
                                int reading;           // the current reading from the input pin
                                int previous = HIGH;    // the previous reading from the input pin
                                
                                // the follow variables are long's because the time, measured in miliseconds,
                                // will quickly become a bigger number than can be stored in an int.
                                long time = 0;         // the last time the output pin was toggled
                                long debounce = 400;   // the debounce time, increase if the output flickers
                                long batteryinterval = 10000;
                                
                                
                                void setup()
                                {
                                	// Setup the buttons
                                	pinMode(BUTTON_PIN, INPUT);
                                	//pinMode(SECONDARY_BUTTON_PIN, INPUT);
                                
                                	// Activate internal pull-ups
                                	digitalWrite(BUTTON_PIN, HIGH);
                                	//digitalWrite(SECONDARY_BUTTON_PIN, HIGH);
                                
                                  // use the 1.1 V internal reference
                                  #if defined(__AVR_ATmega2560__)
                                  analogReference(INTERNAL1V1);
                                  #else
                                  analogReference(INTERNAL);
                                  #endif
                                }
                                
                                void presentation()
                                {
                                  sendSketchInfo("WCNappiBAT", "v290717");
                                	present(CHILD_ID_BUTTON1, S_BINARY);
                                }
                                
                                void loop()
                                {
                                reading = digitalRead(BUTTON_PIN);
                                  if (reading == LOW && previous == HIGH) {
                                    send(MyMessage(CHILD_ID_BUTTON1, V_STATUS).setSensor(WC_SENSOR_ID).setDestination(WC_NODE_ID).set(true));
                                    Serial.println("Toggling..");
                                    sentCounter++;
                                    }
                                
                                previous = reading;
                                
                                if (sentCounter % 10 == 0) {
                                    
                                 int sensorValue = analogRead(BATTERY_SENSE_PIN);
                                
                                  // 1M, 470K divider across battery and using internal ADC ref of 1.1V
                                  // Sense point is bypassed with 0.1 uF cap to reduce noise at that point
                                  // ((1e6+470e3)/470e3)*1.1 = Vmax = 3.44 Volts
                                  // 3.44/1023 = Volts per bit = 0.003363075
                                
                                  int batteryPcnt = sensorValue / 10;
                                
                                  float batteryV  = sensorValue * 0.003363075;
                                  Serial.print("Battery Voltage: ");
                                  Serial.print(batteryV);
                                  Serial.println(" V");
                                
                                  Serial.print("Battery percent: ");
                                  Serial.print(batteryPcnt);
                                  Serial.println(" %");
                                
                                  sendBatteryLevel(batteryPcnt);
                                  }
                                  
                                  delay (200);
                                  
                                    // Sleep until something happens with the sensor
                                  sleep(BUTTON_PIN-2, CHANGE, 0);
                                }
                                

                                And the receiving end.
                                In the code is preparations for my second "remote"

                                // Enable debug prints to serial monitor
                                #define MY_DEBUG
                                
                                // Enable and select radio type attached
                                #define MY_RADIO_NRF24
                                //#define MY_RADIO_RFM69
                                #define MY_NODE_ID 3
                                
                                // Enable repeater functionality for this node
                                //#define MY_REPEATER_FEATURE
                                
                                #include <MySensors.h>
                                
                                #define RELAY_1  3  // Arduino Digital I/O pin number for first relay (second on pin+1 etc)
                                #define NUMBER_OF_RELAYS 6 // Total number of attached relays
                                #define RELAY_ON 0  // GPIO value to write to turn on attached relay
                                #define RELAY_OFF 1 // GPIO value to write to turn off attached relay
                                #define RELAY_7 14   //pin A0 
                                #define RELAY_8 15   //pin A1
                                
                                bool stateWC = 0;
                                bool stateKei = 0;
                                bool stateRuo = 0;
                                
                                void before()
                                {
                                	for (int sensor=1, pin=RELAY_1; sensor<=NUMBER_OF_RELAYS; sensor++, pin++) {
                                		// Then set relay pins in output mode
                                		pinMode(pin, OUTPUT);
                                		// Set relay to last known state (using eeprom storage)
                                		digitalWrite(pin, loadState(sensor)?RELAY_ON:RELAY_OFF);
                                	}
                                 pinMode(RELAY_7, OUTPUT);
                                 digitalWrite(RELAY_7, loadState(7)?RELAY_ON:RELAY_OFF);
                                 pinMode(RELAY_8, OUTPUT);
                                 digitalWrite(RELAY_8, loadState(8)?RELAY_ON:RELAY_OFF);
                                }
                                
                                MyMessage msgWC(3, V_STATUS);
                                MyMessage msgKei(1, V_STATUS);
                                MyMessage msgRuo(2, V_STATUS);
                                
                                void setup()
                                {
                                
                                }
                                
                                void presentation()
                                {
                                	// Send the sketch version information to the gateway and Controller
                                	sendSketchInfo("TeknRele8x", "v29072017");
                                
                                	for (int sensor=1, pin=RELAY_1; sensor<=NUMBER_OF_RELAYS; sensor++, pin++) {
                                		// Register all sensors to gw (they will be created as child devices)
                                		present(sensor, S_BINARY);
                                	}
                                 present(7, S_BINARY);
                                 present(8, S_BINARY);
                                }
                                
                                
                                void loop()
                                {
                                
                                }
                                
                                void receive(const MyMessage &message)
                                {
                                	// We only expect one type of message from controller. But we better check anyway.
                                	if (message.type==V_STATUS) {                             	// Change relay state
                                   if (message.sensor == 7) {
                                   digitalWrite(RELAY_7, message.getBool()?RELAY_ON:RELAY_OFF);    //Write to A0
                                   // Store state in eeprom
                                    saveState(message.sensor, message.getBool());
                                   }
                                   if (message.sensor == 8) {
                                    digitalWrite(RELAY_8, message.getBool()?RELAY_ON:RELAY_OFF);   //Write to A1
                                    // Store state in eeprom
                                    saveState(message.sensor, message.getBool());
                                   }
                                   if (message.sender == 7) {                      //Message from WC remote
                                   stateWC = !stateWC;                             // toggle light state
                                   digitalWrite(5, stateWC?RELAY_ON:RELAY_OFF);    // 5 is RELAY_3 pin 
                                   // Store state in eeprom
                                    saveState(message.sensor, stateWC);
                                    send(msgWC.set(stateWC), false);             //Msg gateway aware of the change. No ack
                                   }
                                   if (message.sender == 8) {
                                    switch (message.sensor) {
                                      case 1:                                     //message for kitchen
                                        stateKei = !stateKei;
                                        digitalWrite(message.sensor, stateKei?RELAY_ON:RELAY_OFF);
                                        saveState(message.sensor, stateKei);
                                        send(msgKei.set(stateKei), false);             //Msg gateway aware of the change. No ack
                                        break;
                                      case 2:                                    //message for dining table
                                        stateRuo = !stateRuo;
                                        digitalWrite(message.sensor, stateRuo?RELAY_ON:RELAY_OFF);
                                        saveState(message.sensor, stateRuo);
                                        send(msgRuo.set(stateRuo), false);             //Msg gateway aware of the change. No ack
                                        break;
                                      }
                                    }
                                   }
                                		digitalWrite(message.sensor-1+RELAY_1, message.getBool()?RELAY_ON:RELAY_OFF);
                                		// Store state in eeprom
                                		saveState(message.sensor, message.getBool());
                                		// Write some debug info
                                		Serial.print("Incoming change for sensor:");
                                		Serial.print(message.sensor);
                                		Serial.print(", New status: ");
                                		Serial.println(message.getBool());
                                	}
                                
                                
                                

                                To add, I would say there's nothing special in either serial output. I can elborate if nothing else appears.
                                Thanks everybody!

                                Boots33B 1 Reply Last reply
                                0
                                • MasMatM MasMat

                                  All right. Been banging my head at this all day again.
                                  I seem to be sending the message from the node OK, but the receiving node appears to have intermittent problems. And for some reason, my gateway reboots at some "combinations".
                                  I have gone thru the send-node & receive-node code tens of times.
                                  Help & ideas appreciated. Plz excuse the finnish in the code :)

                                  Send-node

                                  // Enable debug prints to serial monitor
                                  #define MY_DEBUG
                                  
                                  // Enable and select radio type attached
                                  #define MY_RADIO_NRF24
                                  //#define MY_RADIO_RFM69
                                  #define MY_NODE_ID 7
                                  
                                  #include <MySensors.h>
                                  
                                  //destination specs
                                  #define WC_SENSOR_ID 3
                                  #define WC_NODE_ID 3
                                  
                                  int BATTERY_SENSE_PIN = A0;  // select the input pin for the battery sense point
                                  int oldBatteryPcnt = 0;
                                  
                                  #define CHILD_ID_BUTTON1 3
                                  #define BUTTON_PIN 2   //pin for button
                                  //#define INTERRUPT BUTTON_PIN
                                  
                                  MyMessage msg(CHILD_ID_BUTTON1, V_STATUS);
                                  
                                  int tripped = 1;
                                  int lastStatus = 1;
                                  int numberPushes = 0;
                                  int sentCounter = 0;
                                  
                                  int light1 = LOW;      // the current state of the output pin
                                  int reading;           // the current reading from the input pin
                                  int previous = HIGH;    // the previous reading from the input pin
                                  
                                  // the follow variables are long's because the time, measured in miliseconds,
                                  // will quickly become a bigger number than can be stored in an int.
                                  long time = 0;         // the last time the output pin was toggled
                                  long debounce = 400;   // the debounce time, increase if the output flickers
                                  long batteryinterval = 10000;
                                  
                                  
                                  void setup()
                                  {
                                  	// Setup the buttons
                                  	pinMode(BUTTON_PIN, INPUT);
                                  	//pinMode(SECONDARY_BUTTON_PIN, INPUT);
                                  
                                  	// Activate internal pull-ups
                                  	digitalWrite(BUTTON_PIN, HIGH);
                                  	//digitalWrite(SECONDARY_BUTTON_PIN, HIGH);
                                  
                                    // use the 1.1 V internal reference
                                    #if defined(__AVR_ATmega2560__)
                                    analogReference(INTERNAL1V1);
                                    #else
                                    analogReference(INTERNAL);
                                    #endif
                                  }
                                  
                                  void presentation()
                                  {
                                    sendSketchInfo("WCNappiBAT", "v290717");
                                  	present(CHILD_ID_BUTTON1, S_BINARY);
                                  }
                                  
                                  void loop()
                                  {
                                  reading = digitalRead(BUTTON_PIN);
                                    if (reading == LOW && previous == HIGH) {
                                      send(MyMessage(CHILD_ID_BUTTON1, V_STATUS).setSensor(WC_SENSOR_ID).setDestination(WC_NODE_ID).set(true));
                                      Serial.println("Toggling..");
                                      sentCounter++;
                                      }
                                  
                                  previous = reading;
                                  
                                  if (sentCounter % 10 == 0) {
                                      
                                   int sensorValue = analogRead(BATTERY_SENSE_PIN);
                                  
                                    // 1M, 470K divider across battery and using internal ADC ref of 1.1V
                                    // Sense point is bypassed with 0.1 uF cap to reduce noise at that point
                                    // ((1e6+470e3)/470e3)*1.1 = Vmax = 3.44 Volts
                                    // 3.44/1023 = Volts per bit = 0.003363075
                                  
                                    int batteryPcnt = sensorValue / 10;
                                  
                                    float batteryV  = sensorValue * 0.003363075;
                                    Serial.print("Battery Voltage: ");
                                    Serial.print(batteryV);
                                    Serial.println(" V");
                                  
                                    Serial.print("Battery percent: ");
                                    Serial.print(batteryPcnt);
                                    Serial.println(" %");
                                  
                                    sendBatteryLevel(batteryPcnt);
                                    }
                                    
                                    delay (200);
                                    
                                      // Sleep until something happens with the sensor
                                    sleep(BUTTON_PIN-2, CHANGE, 0);
                                  }
                                  

                                  And the receiving end.
                                  In the code is preparations for my second "remote"

                                  // Enable debug prints to serial monitor
                                  #define MY_DEBUG
                                  
                                  // Enable and select radio type attached
                                  #define MY_RADIO_NRF24
                                  //#define MY_RADIO_RFM69
                                  #define MY_NODE_ID 3
                                  
                                  // Enable repeater functionality for this node
                                  //#define MY_REPEATER_FEATURE
                                  
                                  #include <MySensors.h>
                                  
                                  #define RELAY_1  3  // Arduino Digital I/O pin number for first relay (second on pin+1 etc)
                                  #define NUMBER_OF_RELAYS 6 // Total number of attached relays
                                  #define RELAY_ON 0  // GPIO value to write to turn on attached relay
                                  #define RELAY_OFF 1 // GPIO value to write to turn off attached relay
                                  #define RELAY_7 14   //pin A0 
                                  #define RELAY_8 15   //pin A1
                                  
                                  bool stateWC = 0;
                                  bool stateKei = 0;
                                  bool stateRuo = 0;
                                  
                                  void before()
                                  {
                                  	for (int sensor=1, pin=RELAY_1; sensor<=NUMBER_OF_RELAYS; sensor++, pin++) {
                                  		// Then set relay pins in output mode
                                  		pinMode(pin, OUTPUT);
                                  		// Set relay to last known state (using eeprom storage)
                                  		digitalWrite(pin, loadState(sensor)?RELAY_ON:RELAY_OFF);
                                  	}
                                   pinMode(RELAY_7, OUTPUT);
                                   digitalWrite(RELAY_7, loadState(7)?RELAY_ON:RELAY_OFF);
                                   pinMode(RELAY_8, OUTPUT);
                                   digitalWrite(RELAY_8, loadState(8)?RELAY_ON:RELAY_OFF);
                                  }
                                  
                                  MyMessage msgWC(3, V_STATUS);
                                  MyMessage msgKei(1, V_STATUS);
                                  MyMessage msgRuo(2, V_STATUS);
                                  
                                  void setup()
                                  {
                                  
                                  }
                                  
                                  void presentation()
                                  {
                                  	// Send the sketch version information to the gateway and Controller
                                  	sendSketchInfo("TeknRele8x", "v29072017");
                                  
                                  	for (int sensor=1, pin=RELAY_1; sensor<=NUMBER_OF_RELAYS; sensor++, pin++) {
                                  		// Register all sensors to gw (they will be created as child devices)
                                  		present(sensor, S_BINARY);
                                  	}
                                   present(7, S_BINARY);
                                   present(8, S_BINARY);
                                  }
                                  
                                  
                                  void loop()
                                  {
                                  
                                  }
                                  
                                  void receive(const MyMessage &message)
                                  {
                                  	// We only expect one type of message from controller. But we better check anyway.
                                  	if (message.type==V_STATUS) {                             	// Change relay state
                                     if (message.sensor == 7) {
                                     digitalWrite(RELAY_7, message.getBool()?RELAY_ON:RELAY_OFF);    //Write to A0
                                     // Store state in eeprom
                                      saveState(message.sensor, message.getBool());
                                     }
                                     if (message.sensor == 8) {
                                      digitalWrite(RELAY_8, message.getBool()?RELAY_ON:RELAY_OFF);   //Write to A1
                                      // Store state in eeprom
                                      saveState(message.sensor, message.getBool());
                                     }
                                     if (message.sender == 7) {                      //Message from WC remote
                                     stateWC = !stateWC;                             // toggle light state
                                     digitalWrite(5, stateWC?RELAY_ON:RELAY_OFF);    // 5 is RELAY_3 pin 
                                     // Store state in eeprom
                                      saveState(message.sensor, stateWC);
                                      send(msgWC.set(stateWC), false);             //Msg gateway aware of the change. No ack
                                     }
                                     if (message.sender == 8) {
                                      switch (message.sensor) {
                                        case 1:                                     //message for kitchen
                                          stateKei = !stateKei;
                                          digitalWrite(message.sensor, stateKei?RELAY_ON:RELAY_OFF);
                                          saveState(message.sensor, stateKei);
                                          send(msgKei.set(stateKei), false);             //Msg gateway aware of the change. No ack
                                          break;
                                        case 2:                                    //message for dining table
                                          stateRuo = !stateRuo;
                                          digitalWrite(message.sensor, stateRuo?RELAY_ON:RELAY_OFF);
                                          saveState(message.sensor, stateRuo);
                                          send(msgRuo.set(stateRuo), false);             //Msg gateway aware of the change. No ack
                                          break;
                                        }
                                      }
                                     }
                                  		digitalWrite(message.sensor-1+RELAY_1, message.getBool()?RELAY_ON:RELAY_OFF);
                                  		// Store state in eeprom
                                  		saveState(message.sensor, message.getBool());
                                  		// Write some debug info
                                  		Serial.print("Incoming change for sensor:");
                                  		Serial.print(message.sensor);
                                  		Serial.print(", New status: ");
                                  		Serial.println(message.getBool());
                                  	}
                                  
                                  
                                  

                                  To add, I would say there's nothing special in either serial output. I can elborate if nothing else appears.
                                  Thanks everybody!

                                  Boots33B Offline
                                  Boots33B Offline
                                  Boots33
                                  Hero Member
                                  wrote on last edited by
                                  #16

                                  @MasMat said in Momentary button to control lights:

                                  All right. Been banging my head at this all day again.
                                  I seem to be sending the message from the node OK, but the receiving node appears to have intermittent problems.

                                  Yes your send message should be ok. You are sending a V_STATUS message from node 7 sensor 3 to node 3 sensor 3

                                  And for some reason, my gateway reboots at some "combinations".

                                  Not sure what could be causing that but you will need to sort that out to get stability. I have not experienced any issues with my gateway using node to node.

                                  I have gone thru the send-node & receive-node code tens of times.
                                  Help & ideas appreciated. Plz excuse the finnish in the code

                                  You will need to add code to separate the incoming messages from your controller and remotes as they will need to be treated differently. Messages from your controller will have the gateway (node 0) as the sender so this can be used.

                                  You have a lot going on in your receive function so maybe just put the code for the one node you are trying at the moment so it is easier to troubleshoot.

                                  Try something like this

                                  void receive(const MyMessage &message)
                                  {
                                    if (message.type == V_STATUS) {
                                     if (message.sender == 0) {                                        // check if message is from gateway (node 0)
                                      switch (message.sensor) {
                                          case 3:                                                      //incoming message is for WC relay (sensor 3) 
                                            stateWC = message.getBool();                               // get the new state
                                            digitalWrite(5, stateWC ? RELAY_ON : RELAY_OFF);           // 5 is RELAY_3 pin
                                            saveState(message.sensor, stateWC);                        // save sensor state
                                            break;
                                            
                                          /*-----Add case statements for other realys as needed ----*/
                                          
                                        }
                                      }
                                    else  {                                                           // message is not from gateway so must be from a remote
                                      switch (message.sender) {
                                          case 7:                                                     //incoming message is from WC remote (node 7)  
                                            stateWC = !stateWC;                                       // toggle light state
                                            digitalWrite(5, stateWC?RELAY_ON:RELAY_OFF);              // 5 is RELAY_3 pin         
                                            saveState(message.sensor, stateWC);                       // Store state in eeprom
                                            send(msgWC.set(stateWC), false);                          //Msg gateway aware of the change. No ack
                                            break;
                                            
                                          /*-----Add case statements for other remote nodes as needed ----*/
                                         
                                        }
                                      }
                                  
                                      // Write some debug info
                                      #ifdef MY_DEBUG
                                      Serial.print("Incoming change for sensor:");
                                      Serial.println(message.sensor);
                                      Serial.print("from node:");
                                      Serial.println(message.sender);
                                      Serial.print(" New status: ");
                                      Serial.println(message.getBool());
                                      #endif
                                    }
                                  }
                                  
                                  MasMatM 3 Replies Last reply
                                  0
                                  • Boots33B Boots33

                                    @MasMat said in Momentary button to control lights:

                                    All right. Been banging my head at this all day again.
                                    I seem to be sending the message from the node OK, but the receiving node appears to have intermittent problems.

                                    Yes your send message should be ok. You are sending a V_STATUS message from node 7 sensor 3 to node 3 sensor 3

                                    And for some reason, my gateway reboots at some "combinations".

                                    Not sure what could be causing that but you will need to sort that out to get stability. I have not experienced any issues with my gateway using node to node.

                                    I have gone thru the send-node & receive-node code tens of times.
                                    Help & ideas appreciated. Plz excuse the finnish in the code

                                    You will need to add code to separate the incoming messages from your controller and remotes as they will need to be treated differently. Messages from your controller will have the gateway (node 0) as the sender so this can be used.

                                    You have a lot going on in your receive function so maybe just put the code for the one node you are trying at the moment so it is easier to troubleshoot.

                                    Try something like this

                                    void receive(const MyMessage &message)
                                    {
                                      if (message.type == V_STATUS) {
                                       if (message.sender == 0) {                                        // check if message is from gateway (node 0)
                                        switch (message.sensor) {
                                            case 3:                                                      //incoming message is for WC relay (sensor 3) 
                                              stateWC = message.getBool();                               // get the new state
                                              digitalWrite(5, stateWC ? RELAY_ON : RELAY_OFF);           // 5 is RELAY_3 pin
                                              saveState(message.sensor, stateWC);                        // save sensor state
                                              break;
                                              
                                            /*-----Add case statements for other realys as needed ----*/
                                            
                                          }
                                        }
                                      else  {                                                           // message is not from gateway so must be from a remote
                                        switch (message.sender) {
                                            case 7:                                                     //incoming message is from WC remote (node 7)  
                                              stateWC = !stateWC;                                       // toggle light state
                                              digitalWrite(5, stateWC?RELAY_ON:RELAY_OFF);              // 5 is RELAY_3 pin         
                                              saveState(message.sensor, stateWC);                       // Store state in eeprom
                                              send(msgWC.set(stateWC), false);                          //Msg gateway aware of the change. No ack
                                              break;
                                              
                                            /*-----Add case statements for other remote nodes as needed ----*/
                                           
                                          }
                                        }
                                    
                                        // Write some debug info
                                        #ifdef MY_DEBUG
                                        Serial.print("Incoming change for sensor:");
                                        Serial.println(message.sensor);
                                        Serial.print("from node:");
                                        Serial.println(message.sender);
                                        Serial.print(" New status: ");
                                        Serial.println(message.getBool());
                                        #endif
                                      }
                                    }
                                    
                                    MasMatM Offline
                                    MasMatM Offline
                                    MasMat
                                    wrote on last edited by
                                    #17

                                    @Boots33 That looks really clean. And you're right I have to comment out the stuff that's pre-prepared.
                                    The node is installed in a really tricky place and reprogramming is difficult (hence trying to solve everything beforehand). One day I'll learn to build & test first, install second...

                                    This morning I tested the setup again, with old settings and noticed the correct relay "fires" but doesnt really toggle. If I switch it off, it will come on but stay on regardless of presses. So the right node is receiving.

                                    I'll revise the code and re-test in a few...

                                    1 Reply Last reply
                                    0
                                    • Boots33B Boots33

                                      @MasMat said in Momentary button to control lights:

                                      All right. Been banging my head at this all day again.
                                      I seem to be sending the message from the node OK, but the receiving node appears to have intermittent problems.

                                      Yes your send message should be ok. You are sending a V_STATUS message from node 7 sensor 3 to node 3 sensor 3

                                      And for some reason, my gateway reboots at some "combinations".

                                      Not sure what could be causing that but you will need to sort that out to get stability. I have not experienced any issues with my gateway using node to node.

                                      I have gone thru the send-node & receive-node code tens of times.
                                      Help & ideas appreciated. Plz excuse the finnish in the code

                                      You will need to add code to separate the incoming messages from your controller and remotes as they will need to be treated differently. Messages from your controller will have the gateway (node 0) as the sender so this can be used.

                                      You have a lot going on in your receive function so maybe just put the code for the one node you are trying at the moment so it is easier to troubleshoot.

                                      Try something like this

                                      void receive(const MyMessage &message)
                                      {
                                        if (message.type == V_STATUS) {
                                         if (message.sender == 0) {                                        // check if message is from gateway (node 0)
                                          switch (message.sensor) {
                                              case 3:                                                      //incoming message is for WC relay (sensor 3) 
                                                stateWC = message.getBool();                               // get the new state
                                                digitalWrite(5, stateWC ? RELAY_ON : RELAY_OFF);           // 5 is RELAY_3 pin
                                                saveState(message.sensor, stateWC);                        // save sensor state
                                                break;
                                                
                                              /*-----Add case statements for other realys as needed ----*/
                                              
                                            }
                                          }
                                        else  {                                                           // message is not from gateway so must be from a remote
                                          switch (message.sender) {
                                              case 7:                                                     //incoming message is from WC remote (node 7)  
                                                stateWC = !stateWC;                                       // toggle light state
                                                digitalWrite(5, stateWC?RELAY_ON:RELAY_OFF);              // 5 is RELAY_3 pin         
                                                saveState(message.sensor, stateWC);                       // Store state in eeprom
                                                send(msgWC.set(stateWC), false);                          //Msg gateway aware of the change. No ack
                                                break;
                                                
                                              /*-----Add case statements for other remote nodes as needed ----*/
                                             
                                            }
                                          }
                                      
                                          // Write some debug info
                                          #ifdef MY_DEBUG
                                          Serial.print("Incoming change for sensor:");
                                          Serial.println(message.sensor);
                                          Serial.print("from node:");
                                          Serial.println(message.sender);
                                          Serial.print(" New status: ");
                                          Serial.println(message.getBool());
                                          #endif
                                        }
                                      }
                                      
                                      MasMatM Offline
                                      MasMatM Offline
                                      MasMat
                                      wrote on last edited by
                                      #18
                                      This post is deleted!
                                      1 Reply Last reply
                                      0
                                      • Boots33B Boots33

                                        @MasMat said in Momentary button to control lights:

                                        All right. Been banging my head at this all day again.
                                        I seem to be sending the message from the node OK, but the receiving node appears to have intermittent problems.

                                        Yes your send message should be ok. You are sending a V_STATUS message from node 7 sensor 3 to node 3 sensor 3

                                        And for some reason, my gateway reboots at some "combinations".

                                        Not sure what could be causing that but you will need to sort that out to get stability. I have not experienced any issues with my gateway using node to node.

                                        I have gone thru the send-node & receive-node code tens of times.
                                        Help & ideas appreciated. Plz excuse the finnish in the code

                                        You will need to add code to separate the incoming messages from your controller and remotes as they will need to be treated differently. Messages from your controller will have the gateway (node 0) as the sender so this can be used.

                                        You have a lot going on in your receive function so maybe just put the code for the one node you are trying at the moment so it is easier to troubleshoot.

                                        Try something like this

                                        void receive(const MyMessage &message)
                                        {
                                          if (message.type == V_STATUS) {
                                           if (message.sender == 0) {                                        // check if message is from gateway (node 0)
                                            switch (message.sensor) {
                                                case 3:                                                      //incoming message is for WC relay (sensor 3) 
                                                  stateWC = message.getBool();                               // get the new state
                                                  digitalWrite(5, stateWC ? RELAY_ON : RELAY_OFF);           // 5 is RELAY_3 pin
                                                  saveState(message.sensor, stateWC);                        // save sensor state
                                                  break;
                                                  
                                                /*-----Add case statements for other realys as needed ----*/
                                                
                                              }
                                            }
                                          else  {                                                           // message is not from gateway so must be from a remote
                                            switch (message.sender) {
                                                case 7:                                                     //incoming message is from WC remote (node 7)  
                                                  stateWC = !stateWC;                                       // toggle light state
                                                  digitalWrite(5, stateWC?RELAY_ON:RELAY_OFF);              // 5 is RELAY_3 pin         
                                                  saveState(message.sensor, stateWC);                       // Store state in eeprom
                                                  send(msgWC.set(stateWC), false);                          //Msg gateway aware of the change. No ack
                                                  break;
                                                  
                                                /*-----Add case statements for other remote nodes as needed ----*/
                                               
                                              }
                                            }
                                        
                                            // Write some debug info
                                            #ifdef MY_DEBUG
                                            Serial.print("Incoming change for sensor:");
                                            Serial.println(message.sensor);
                                            Serial.print("from node:");
                                            Serial.println(message.sender);
                                            Serial.print(" New status: ");
                                            Serial.println(message.getBool());
                                            #endif
                                          }
                                        }
                                        
                                        MasMatM Offline
                                        MasMatM Offline
                                        MasMat
                                        wrote on last edited by
                                        #19

                                        @Boots33 So, added some tuff to keep the other relays working.
                                        The issue now is bouncing apparently.
                                        The send-node has delay but seems to fire a bunch of 1's (and 0's for some reason...?).
                                        Here's the lastest on the receiving end:

                                        void receive(const MyMessage &message)
                                        {
                                          if (message.type == V_STATUS) {
                                           if (message.sender == 0) {                                        // check if message is from gateway (node 0)
                                            switch (message.sensor) {
                                                case 3:                                                      //incoming message is for WC relay (sensor 3) 
                                                  stateWC = message.getBool();                               // get the new state
                                                  digitalWrite(5, stateWC ? RELAY_ON : RELAY_OFF);           // 5 is RELAY_3 pin
                                                  saveState(message.sensor, stateWC);                        // save sensor state
                                                  break;
                                                case 7:
                                                  digitalWrite(RELAY_7, message.getBool()?RELAY_ON:RELAY_OFF); //Write to A0
                                                  saveState(message.sensor, message.getBool());
                                                  break;
                                                case 8:
                                                  digitalWrite(RELAY_8, message.getBool()?RELAY_ON:RELAY_OFF); //Write to A1
                                                  saveState(message.sensor, message.getBool());
                                                  break;
                                                default:
                                                  digitalWrite(message.sensor-1+RELAY_1, message.getBool()?RELAY_ON:RELAY_OFF);
                                                  saveState(message.sensor, message.getBool());
                                                  break;
                                                /*-----Add case statements for other realys as needed ----*/
                                                
                                              }
                                            }
                                          else  {                                                           // message is not from gateway so must be from a remote
                                            switch (message.sender) {
                                                case 7:                                                     //incoming message is from WC remote (node 7)  
                                                  stateWC = !stateWC;                                       // toggle light state
                                                  digitalWrite(5, stateWC?RELAY_ON:RELAY_OFF);              // 5 is RELAY_3 pin         
                                                  saveState(message.sensor, stateWC);                       // Store state in eeprom
                                                  send(msgWC.set(stateWC), false);                          //Msg gateway aware of the change. No ack
                                                  break;
                                                  
                                                /*-----Add case statements for other remote nodes as needed ----*/
                                               
                                              }
                                            }
                                        
                                            // Write some debug info
                                            #ifdef MY_DEBUG
                                            Serial.print("Incoming change for sensor:");
                                            Serial.println(message.sensor);
                                            Serial.print("from node:");
                                            Serial.println(message.sender);
                                            Serial.print(" New status: ");
                                            Serial.println(message.getBool());
                                            #endif
                                          }
                                        }
                                        

                                        The send-node is still

                                        #define MY_DEBUG
                                        
                                        // Enable and select radio type attached
                                        #define MY_RADIO_NRF24
                                        #define MY_NODE_ID 7
                                        
                                        #include <MySensors.h>
                                        
                                        //destination specs
                                        #define WC_SENSOR_ID 3
                                        #define WC_NODE_ID 3
                                        
                                        int BATTERY_SENSE_PIN = A0;  // select the input pin for the battery sense point
                                        int oldBatteryPcnt = 0;
                                        
                                        #define CHILD_ID_BUTTON1 3
                                        #define BUTTON_PIN 2   //pin for button
                                        //#define INTERRUPT BUTTON_PIN
                                        
                                        MyMessage msg(CHILD_ID_BUTTON1, V_STATUS);
                                        
                                        int sentCounter = 0;
                                        
                                        int reading;           // the current reading from the input pin
                                        int previous = HIGH;    // the previous reading from the input pin 
                                        
                                        void setup()
                                        {
                                        	// Setup the buttons
                                        	pinMode(BUTTON_PIN, INPUT);
                                        
                                        	// Activate internal pull-ups
                                        	digitalWrite(BUTTON_PIN, HIGH);
                                        
                                          // use the 1.1 V internal reference
                                          #if defined(__AVR_ATmega2560__)
                                          analogReference(INTERNAL1V1);
                                          #else
                                          analogReference(INTERNAL);
                                          #endif
                                        }
                                        
                                        void presentation()
                                        {
                                          sendSketchInfo("WCNappiBAT", "v290717");
                                        	present(CHILD_ID_BUTTON1, S_BINARY);
                                        }
                                        
                                        void loop()
                                        {
                                        reading = digitalRead(BUTTON_PIN);
                                          if (reading == LOW && previous == HIGH) {
                                            send(MyMessage(CHILD_ID_BUTTON1, V_STATUS).setSensor(WC_SENSOR_ID).setDestination(WC_NODE_ID).set("1"));
                                            Serial.println("Toggling remote node ");
                                            Serial.print(WC_NODE_ID);
                                            Serial.print(", sensor ");
                                            Serial.println(WC_SENSOR_ID);
                                            sentCounter++;
                                            }
                                        
                                        previous = reading;
                                        
                                        if (sentCounter % 10 == 0) {
                                            
                                         int sensorValue = analogRead(BATTERY_SENSE_PIN);
                                        
                                          // 3.44/1023 = Volts per bit = 0.003363075
                                        
                                          int batteryPcnt = sensorValue / 10;
                                        
                                          float batteryV  = sensorValue * 0.003363075;
                                          Serial.print("Battery Voltage: ");
                                          Serial.print(batteryV);
                                          Serial.println(" V");
                                        
                                          Serial.print("Battery percent: ");
                                          Serial.print(batteryPcnt);
                                          Serial.println(" %");
                                        
                                          sendBatteryLevel(batteryPcnt);
                                          }
                                          
                                          delay (400);
                                          
                                            // Sleep until something happens with the sensor
                                          sleep(0, CHANGE, 0);
                                        }
                                        
                                        Boots33B 1 Reply Last reply
                                        0
                                        • MasMatM MasMat

                                          @Boots33 So, added some tuff to keep the other relays working.
                                          The issue now is bouncing apparently.
                                          The send-node has delay but seems to fire a bunch of 1's (and 0's for some reason...?).
                                          Here's the lastest on the receiving end:

                                          void receive(const MyMessage &message)
                                          {
                                            if (message.type == V_STATUS) {
                                             if (message.sender == 0) {                                        // check if message is from gateway (node 0)
                                              switch (message.sensor) {
                                                  case 3:                                                      //incoming message is for WC relay (sensor 3) 
                                                    stateWC = message.getBool();                               // get the new state
                                                    digitalWrite(5, stateWC ? RELAY_ON : RELAY_OFF);           // 5 is RELAY_3 pin
                                                    saveState(message.sensor, stateWC);                        // save sensor state
                                                    break;
                                                  case 7:
                                                    digitalWrite(RELAY_7, message.getBool()?RELAY_ON:RELAY_OFF); //Write to A0
                                                    saveState(message.sensor, message.getBool());
                                                    break;
                                                  case 8:
                                                    digitalWrite(RELAY_8, message.getBool()?RELAY_ON:RELAY_OFF); //Write to A1
                                                    saveState(message.sensor, message.getBool());
                                                    break;
                                                  default:
                                                    digitalWrite(message.sensor-1+RELAY_1, message.getBool()?RELAY_ON:RELAY_OFF);
                                                    saveState(message.sensor, message.getBool());
                                                    break;
                                                  /*-----Add case statements for other realys as needed ----*/
                                                  
                                                }
                                              }
                                            else  {                                                           // message is not from gateway so must be from a remote
                                              switch (message.sender) {
                                                  case 7:                                                     //incoming message is from WC remote (node 7)  
                                                    stateWC = !stateWC;                                       // toggle light state
                                                    digitalWrite(5, stateWC?RELAY_ON:RELAY_OFF);              // 5 is RELAY_3 pin         
                                                    saveState(message.sensor, stateWC);                       // Store state in eeprom
                                                    send(msgWC.set(stateWC), false);                          //Msg gateway aware of the change. No ack
                                                    break;
                                                    
                                                  /*-----Add case statements for other remote nodes as needed ----*/
                                                 
                                                }
                                              }
                                          
                                              // Write some debug info
                                              #ifdef MY_DEBUG
                                              Serial.print("Incoming change for sensor:");
                                              Serial.println(message.sensor);
                                              Serial.print("from node:");
                                              Serial.println(message.sender);
                                              Serial.print(" New status: ");
                                              Serial.println(message.getBool());
                                              #endif
                                            }
                                          }
                                          

                                          The send-node is still

                                          #define MY_DEBUG
                                          
                                          // Enable and select radio type attached
                                          #define MY_RADIO_NRF24
                                          #define MY_NODE_ID 7
                                          
                                          #include <MySensors.h>
                                          
                                          //destination specs
                                          #define WC_SENSOR_ID 3
                                          #define WC_NODE_ID 3
                                          
                                          int BATTERY_SENSE_PIN = A0;  // select the input pin for the battery sense point
                                          int oldBatteryPcnt = 0;
                                          
                                          #define CHILD_ID_BUTTON1 3
                                          #define BUTTON_PIN 2   //pin for button
                                          //#define INTERRUPT BUTTON_PIN
                                          
                                          MyMessage msg(CHILD_ID_BUTTON1, V_STATUS);
                                          
                                          int sentCounter = 0;
                                          
                                          int reading;           // the current reading from the input pin
                                          int previous = HIGH;    // the previous reading from the input pin 
                                          
                                          void setup()
                                          {
                                          	// Setup the buttons
                                          	pinMode(BUTTON_PIN, INPUT);
                                          
                                          	// Activate internal pull-ups
                                          	digitalWrite(BUTTON_PIN, HIGH);
                                          
                                            // use the 1.1 V internal reference
                                            #if defined(__AVR_ATmega2560__)
                                            analogReference(INTERNAL1V1);
                                            #else
                                            analogReference(INTERNAL);
                                            #endif
                                          }
                                          
                                          void presentation()
                                          {
                                            sendSketchInfo("WCNappiBAT", "v290717");
                                          	present(CHILD_ID_BUTTON1, S_BINARY);
                                          }
                                          
                                          void loop()
                                          {
                                          reading = digitalRead(BUTTON_PIN);
                                            if (reading == LOW && previous == HIGH) {
                                              send(MyMessage(CHILD_ID_BUTTON1, V_STATUS).setSensor(WC_SENSOR_ID).setDestination(WC_NODE_ID).set("1"));
                                              Serial.println("Toggling remote node ");
                                              Serial.print(WC_NODE_ID);
                                              Serial.print(", sensor ");
                                              Serial.println(WC_SENSOR_ID);
                                              sentCounter++;
                                              }
                                          
                                          previous = reading;
                                          
                                          if (sentCounter % 10 == 0) {
                                              
                                           int sensorValue = analogRead(BATTERY_SENSE_PIN);
                                          
                                            // 3.44/1023 = Volts per bit = 0.003363075
                                          
                                            int batteryPcnt = sensorValue / 10;
                                          
                                            float batteryV  = sensorValue * 0.003363075;
                                            Serial.print("Battery Voltage: ");
                                            Serial.print(batteryV);
                                            Serial.println(" V");
                                          
                                            Serial.print("Battery percent: ");
                                            Serial.print(batteryPcnt);
                                            Serial.println(" %");
                                          
                                            sendBatteryLevel(batteryPcnt);
                                            }
                                            
                                            delay (400);
                                            
                                              // Sleep until something happens with the sensor
                                            sleep(0, CHANGE, 0);
                                          }
                                          
                                          Boots33B Offline
                                          Boots33B Offline
                                          Boots33
                                          Hero Member
                                          wrote on last edited by
                                          #20

                                          @MasMat You could try increasing your delay time out to several seconds to see what happens (probably should use wait instead of delay as well) and maybe comment out the sleep line too. This may at least give you an idea of where to start.

                                          perhaps post some of the serial monitor output from the node.

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


                                          24

                                          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