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. Relay control - bistable switch instead of monostable.

Relay control - bistable switch instead of monostable.

Scheduled Pinned Locked Moved Troubleshooting
8 Posts 3 Posters 3.1k Views 5 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.
  • PlantexP Offline
    PlantexP Offline
    Plantex
    wrote on last edited by
    #1

    Hello

    I'm using modified my-sensors sketch to control few relays. Arduino is connected via usb cable with Domoticz.

    Everything works fine but the sketch is designed for monostable switch (doorbell type)

    Point is I would like to use standard (bistable) switch instead of (monostable) doorbell switch.

    Could You please help me with modifying the sketch ?!?

    Thank You in advance.
    Below the code.

    
    
    // Enable debug prints to serial monitor
    #define MY_DEBUG 
    
    
    // Enable and select radio type attached
    //#define MY_RADIO_NRF24
    //#define MY_RADIO_RFM69
    
    // Set LOW transmit power level as default, if you have an amplified NRF-module and
    // power your radio separately with a good regulator you can turn up PA level. 
    //#define MY_RF24_PA_LEVEL RF24_PA_LOW
    
    // Enable serial gateway
    #define MY_GATEWAY_SERIAL
    
    // Define a lower baud rate for Arduino's running on 8 MHz (Arduino Pro Mini 3.3V & SenseBender)
    #if F_CPU == 8000000L
    #define MY_BAUD_RATE 38400
    #endif
    
    // Flash leds on rx/tx/err
    // #define MY_LEDS_BLINKING_FEATURE
    // Set blinking period
    // #define MY_DEFAULT_LED_BLINK_PERIOD 300
    
    // Inverses the behavior of leds
    // #define MY_WITH_LEDS_BLINKING_INVERSE
    
    // Enable inclusion mode
    #define MY_INCLUSION_MODE_FEATURE
    // Enable Inclusion mode button on gateway
    #define MY_INCLUSION_BUTTON_FEATURE
    
    // Inverses behavior of inclusion button (if using external pullup)
    //#define MY_INCLUSION_BUTTON_EXTERNAL_PULLUP
    
    // Set inclusion mode duration (in seconds)
    #define MY_INCLUSION_MODE_DURATION 60 
    // Digital pin used for inclusion mode button
    #define MY_INCLUSION_MODE_BUTTON_PIN  3 
    
    // Uncomment to override default HW configurations
    //#define MY_DEFAULT_ERR_LED_PIN 4  // Error led pin
    //#define MY_DEFAULT_RX_LED_PIN  6  // Receive led pin
    //#define MY_DEFAULT_TX_LED_PIN  5  // the PCB, on board LED
    
    #include <SPI.h>
    #include <MySensors.h>  
    #include <Bounce2.h>
    
    // Enable repeater functionality for this node
    // #define MY_REPEATER_FEATURE
    
    
    #define RELAY_1  4  // Arduino Digital I/O pin number for first relay (second on pin+1 etc)
    #define RELAY_2  5
    #define RELAY_3  6
    #define RELAY_4  7
    
    
    #define NUMBER_OF_RELAYS 4 // 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 BUTTON_PIN A1
    #define BUTTON2_PIN A2
    #define BUTTON3_PIN A3
    #define BUTTON4_PIN A4
    
    
    
    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);
      }
    }
    Bounce debouncer = Bounce();
    Bounce debouncer2 = Bounce();
    Bounce debouncer3 = Bounce();
    Bounce debouncer4 = Bounce();
    
    void setup() { 
      // Setup locally attached sensors
      delay(10000);
       // Setup the button.
      pinMode(BUTTON_PIN, INPUT_PULLUP);
      pinMode(BUTTON2_PIN, INPUT_PULLUP);
      pinMode(BUTTON3_PIN, INPUT_PULLUP);
      pinMode(BUTTON4_PIN, INPUT_PULLUP);
    
      
      // After setting up the button, setup debouncer.
      debouncer.attach(BUTTON_PIN);
      debouncer.interval(5);
      debouncer2.attach(BUTTON2_PIN);
      debouncer2.interval(5);
      debouncer3.attach(BUTTON3_PIN);
      debouncer3.interval(5);
      debouncer4.attach(BUTTON4_PIN);
      debouncer4.interval(5);
    
      
    
      //presentation();
    }
    void presentation()  
    {   
      // Send the sketch version information to the gateway and Controller
      sendSketchInfo("Relay", "1.0");
    
      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_LIGHT);
      }
    }
    
    MyMessage msg(1, V_LIGHT);
    MyMessage msg2(2, V_LIGHT);
    MyMessage msg3(3, V_LIGHT);
    MyMessage msg4(4, V_LIGHT);
    
    
    void loop() { 
      // Send locally attached sensor data here 
      if (debouncer.update()) {
        // Get the update value.
        int value = debouncer.read();
        // Send in the new value.
        if(value == LOW){
             saveState(1, !loadState(1));
             digitalWrite(RELAY_1, loadState(1)?RELAY_ON:RELAY_OFF);
             send(msg.set(loadState(1)));
             }
      }
      if (debouncer2.update()) {
          int value2 = debouncer2.read();
        if(value2 == LOW){
             saveState(2, !loadState(2));
             digitalWrite(RELAY_2, loadState(2)?RELAY_ON:RELAY_OFF);
             send(msg2.set(loadState(2)));
             }
      }
    
    if (debouncer3.update()) {
          int value3 = debouncer3.read();
        if(value3 == LOW){
             saveState(3, !loadState(3));
             digitalWrite(RELAY_3, loadState(3)?RELAY_ON:RELAY_OFF);
             send(msg3.set(loadState(3)));
             }
      }
    
    if (debouncer4.update()) {
          int value4 = debouncer4.read();
        if(value4 == LOW){
             saveState(4, !loadState(4));
             digitalWrite(RELAY_4, loadState(4)?RELAY_ON:RELAY_OFF);
             send(msg4.set(loadState(4)));
             }
      }
    }
    
    
    void receive(const MyMessage &message) {
      // We only expect one type of message from controller. But we better check anyway.
      if (message.type==V_LIGHT) {
         // Change relay state
         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());
       } 
    }
    
    
    
    
    
    dbemowskD 1 Reply Last reply
    0
    • PlantexP Plantex

      Hello

      I'm using modified my-sensors sketch to control few relays. Arduino is connected via usb cable with Domoticz.

      Everything works fine but the sketch is designed for monostable switch (doorbell type)

      Point is I would like to use standard (bistable) switch instead of (monostable) doorbell switch.

      Could You please help me with modifying the sketch ?!?

      Thank You in advance.
      Below the code.

      
      
      // Enable debug prints to serial monitor
      #define MY_DEBUG 
      
      
      // Enable and select radio type attached
      //#define MY_RADIO_NRF24
      //#define MY_RADIO_RFM69
      
      // Set LOW transmit power level as default, if you have an amplified NRF-module and
      // power your radio separately with a good regulator you can turn up PA level. 
      //#define MY_RF24_PA_LEVEL RF24_PA_LOW
      
      // Enable serial gateway
      #define MY_GATEWAY_SERIAL
      
      // Define a lower baud rate for Arduino's running on 8 MHz (Arduino Pro Mini 3.3V & SenseBender)
      #if F_CPU == 8000000L
      #define MY_BAUD_RATE 38400
      #endif
      
      // Flash leds on rx/tx/err
      // #define MY_LEDS_BLINKING_FEATURE
      // Set blinking period
      // #define MY_DEFAULT_LED_BLINK_PERIOD 300
      
      // Inverses the behavior of leds
      // #define MY_WITH_LEDS_BLINKING_INVERSE
      
      // Enable inclusion mode
      #define MY_INCLUSION_MODE_FEATURE
      // Enable Inclusion mode button on gateway
      #define MY_INCLUSION_BUTTON_FEATURE
      
      // Inverses behavior of inclusion button (if using external pullup)
      //#define MY_INCLUSION_BUTTON_EXTERNAL_PULLUP
      
      // Set inclusion mode duration (in seconds)
      #define MY_INCLUSION_MODE_DURATION 60 
      // Digital pin used for inclusion mode button
      #define MY_INCLUSION_MODE_BUTTON_PIN  3 
      
      // Uncomment to override default HW configurations
      //#define MY_DEFAULT_ERR_LED_PIN 4  // Error led pin
      //#define MY_DEFAULT_RX_LED_PIN  6  // Receive led pin
      //#define MY_DEFAULT_TX_LED_PIN  5  // the PCB, on board LED
      
      #include <SPI.h>
      #include <MySensors.h>  
      #include <Bounce2.h>
      
      // Enable repeater functionality for this node
      // #define MY_REPEATER_FEATURE
      
      
      #define RELAY_1  4  // Arduino Digital I/O pin number for first relay (second on pin+1 etc)
      #define RELAY_2  5
      #define RELAY_3  6
      #define RELAY_4  7
      
      
      #define NUMBER_OF_RELAYS 4 // 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 BUTTON_PIN A1
      #define BUTTON2_PIN A2
      #define BUTTON3_PIN A3
      #define BUTTON4_PIN A4
      
      
      
      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);
        }
      }
      Bounce debouncer = Bounce();
      Bounce debouncer2 = Bounce();
      Bounce debouncer3 = Bounce();
      Bounce debouncer4 = Bounce();
      
      void setup() { 
        // Setup locally attached sensors
        delay(10000);
         // Setup the button.
        pinMode(BUTTON_PIN, INPUT_PULLUP);
        pinMode(BUTTON2_PIN, INPUT_PULLUP);
        pinMode(BUTTON3_PIN, INPUT_PULLUP);
        pinMode(BUTTON4_PIN, INPUT_PULLUP);
      
        
        // After setting up the button, setup debouncer.
        debouncer.attach(BUTTON_PIN);
        debouncer.interval(5);
        debouncer2.attach(BUTTON2_PIN);
        debouncer2.interval(5);
        debouncer3.attach(BUTTON3_PIN);
        debouncer3.interval(5);
        debouncer4.attach(BUTTON4_PIN);
        debouncer4.interval(5);
      
        
      
        //presentation();
      }
      void presentation()  
      {   
        // Send the sketch version information to the gateway and Controller
        sendSketchInfo("Relay", "1.0");
      
        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_LIGHT);
        }
      }
      
      MyMessage msg(1, V_LIGHT);
      MyMessage msg2(2, V_LIGHT);
      MyMessage msg3(3, V_LIGHT);
      MyMessage msg4(4, V_LIGHT);
      
      
      void loop() { 
        // Send locally attached sensor data here 
        if (debouncer.update()) {
          // Get the update value.
          int value = debouncer.read();
          // Send in the new value.
          if(value == LOW){
               saveState(1, !loadState(1));
               digitalWrite(RELAY_1, loadState(1)?RELAY_ON:RELAY_OFF);
               send(msg.set(loadState(1)));
               }
        }
        if (debouncer2.update()) {
            int value2 = debouncer2.read();
          if(value2 == LOW){
               saveState(2, !loadState(2));
               digitalWrite(RELAY_2, loadState(2)?RELAY_ON:RELAY_OFF);
               send(msg2.set(loadState(2)));
               }
        }
      
      if (debouncer3.update()) {
            int value3 = debouncer3.read();
          if(value3 == LOW){
               saveState(3, !loadState(3));
               digitalWrite(RELAY_3, loadState(3)?RELAY_ON:RELAY_OFF);
               send(msg3.set(loadState(3)));
               }
        }
      
      if (debouncer4.update()) {
            int value4 = debouncer4.read();
          if(value4 == LOW){
               saveState(4, !loadState(4));
               digitalWrite(RELAY_4, loadState(4)?RELAY_ON:RELAY_OFF);
               send(msg4.set(loadState(4)));
               }
        }
      }
      
      
      void receive(const MyMessage &message) {
        // We only expect one type of message from controller. But we better check anyway.
        if (message.type==V_LIGHT) {
           // Change relay state
           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());
         } 
      }
      
      
      
      
      
      dbemowskD Offline
      dbemowskD Offline
      dbemowsk
      wrote on last edited by
      #2

      @Plantex By bistable switch, are you talking a standard on/off switch?

      Vera Plus running UI7 with MySensors, Sonoffs and 1-Wire devices
      Visit my website for more Bits, Bytes and Ramblings from me: http://dan.bemowski.info/

      1 Reply Last reply
      0
      • PlantexP Offline
        PlantexP Offline
        Plantex
        wrote on last edited by
        #3

        Yes, standard on/off switch

        dbemowskD 1 Reply Last reply
        0
        • PlantexP Plantex

          Yes, standard on/off switch

          dbemowskD Offline
          dbemowskD Offline
          dbemowsk
          wrote on last edited by
          #4

          @Plantex For a bistable switch, my guess is that you would not want to just use the on/off state of the switch. I would think that you would want to look to see when the switch changes state, either from off to on, or from on to off. The reason for this is simple. If you have the switch set so that when contact is on, the relay is on, then you are stuck in that state. If a command comes in to the node to turn it off, it will be stuck on because the switch will continue to tell it that it is on. By checking the state change of the switch, you can just have it invert the state of the relay when that state change occurs.

          For the hardware, just connect the common and 1 pole of a switch to the same connections as the push button switches. When the switch is flipped, the value of BUTTONx_PIN will either be high or low.

          As far as the code for this, I would add 4 new variables to save the last state of each switch. Lets just name them last_state1 - last_state4.

          ~~~~~~~~
          #define BUTTON4_PIN A4
          
          boolean last_state1 = LOW;
          boolean last_state2 = LOW;
          boolean last_state3 = LOW;
          boolean last_state4 = LOW;
          ~~~~~~~~
          

          Next, we'll change the IF statement for each debouncer from this:

          if(valueX == LOW){
          

          to this

          if(valueX != last_stateX){
          

          And then after each IF check of the state, update the last_stateX:

          
              if(valueX != last_stateX){
                   saveState(X !loadState(X));
                   digitalWrite(RELAY_X, loadState(X)?RELAY_ON:RELAY_OFF);
                   send(msgX.set(loadState(X)));
                   }
            last_stateX = valueX;
          

          Obviously, in all the above code, replace X with the number of the relay that you are working on, so for relay 3, the last bit of code would look like this:

              if(value3 != last_state3){
                   saveState(3, !loadState(3));
                   digitalWrite(RELAY_3, loadState(3)?RELAY_ON:RELAY_OFF);
                   send(msg3.set(loadState(3)));
                   }
            last_state3 = value3;
          

          Using this method will cause the switch to act like other 3-way switches in that the standard up is on, down is off will not apply.

          Vera Plus running UI7 with MySensors, Sonoffs and 1-Wire devices
          Visit my website for more Bits, Bytes and Ramblings from me: http://dan.bemowski.info/

          1 Reply Last reply
          0
          • N Offline
            N Offline
            niccodemi
            wrote on last edited by
            #5

            I am using below sketch; make sure that number of relays matches number of relayPins and buttonPins.

            //MultiRelayButton Sketch, MySensors 1.6, toggle switch
            
            #define MY_RADIO_NRF24
            
            #define MY_REPEATER_FEATURE
            
            //Set Static node id
            //#define MY_NODE_ID 250
            
            #include <MySensors.h>
            #include <SPI.h>
            #include <Bounce2.h>
            #define RELAY_ON 0                      // switch around for ACTIVE LOW / ACTIVE HIGH relay
            #define RELAY_OFF 1
            //
            
            #define noRelays 2                     //2-4
            const int relayPin[] = {14,15};          //  switch around pins to your desire
            const int buttonPin[] = {3,4};      //  switch around pins to your desire
            
            class Relay             // relay class, store all relevant data (equivalent to struct)
            {
            public:                                      
              int buttonPin;                   // physical pin number of button
              int relayPin;             // physical pin number of relay
              boolean relayState;               // relay status (also stored in EEPROM)
            };
            
            Relay Relays[noRelays]; 
            Bounce debouncer[noRelays];
            MyMessage msg[noRelays];
            
            void setup(){
                sendHeartbeat();
                wait(100);
                // Initialize Relays with corresponding buttons
                for (int i = 0; i < noRelays; i++){
                Relays[i].buttonPin = buttonPin[i];              // assign physical pins
                Relays[i].relayPin = relayPin[i];
                msg[i].sensor = i;                                   // initialize messages
                msg[i].type = V_LIGHT;   
                pinMode(Relays[i].buttonPin, INPUT_PULLUP);
                wait(100);
                pinMode(Relays[i].relayPin, OUTPUT);
                Relays[i].relayState = loadState(i);                               // retrieve last values from EEPROM
                digitalWrite(Relays[i].relayPin, Relays[i].relayState? RELAY_ON:RELAY_OFF);   // and set relays accordingly
                send(msg[i].set(Relays[i].relayState? true : false));                  // make controller aware of last status  
                wait(50);
                debouncer[i] = Bounce();                        // initialize debouncer
                debouncer[i].attach(buttonPin[i]);
                debouncer[i].interval(20);
                wait(50);
                }
            }
            void presentation()  {
                  sendSketchInfo("MultiRelayButton", "1.0");
                  wait(100);
                  for (int i = 0; i < noRelays; i++)
                  present(i, S_LIGHT);                               // present sensor to gateway
                  wait(100);
            }
            void loop()
            {
                for (byte i = 0; i < noRelays; i++) {
                    if (debouncer[i].update()) {
                        Relays[i].relayState = !Relays[i].relayState;
                        digitalWrite(Relays[i].relayPin, Relays[i].relayState?RELAY_ON:RELAY_OFF);
                        send(msg[i].set(Relays[i].relayState? true : false));
                        // save sensor state in EEPROM (location == sensor number)
                        saveState( i, Relays[i].relayState );
                    }                 
                }
                wait(20);
            }
            // process incoming message 
            void receive(const MyMessage &message){        
               if (message.type == V_LIGHT){ 
               if (message.sensor <noRelays){            // check if message is valid for relays..... previous line  [[[ if (message.sensor <=noRelays){ ]]]
               Relays[message.sensor].relayState = message.getBool(); 
               digitalWrite(Relays[message.sensor].relayPin, Relays[message.sensor].relayState? RELAY_ON:RELAY_OFF); // and set relays accordingly
               saveState( message.sensor, Relays[message.sensor].relayState ); // save sensor state in EEPROM (location == sensor number)
               }
              }
              wait(20);
            }
            1 Reply Last reply
            0
            • N Offline
              N Offline
              niccodemi
              wrote on last edited by
              #6
              This post is deleted!
              dbemowskD 1 Reply Last reply
              0
              • N niccodemi

                This post is deleted!

                dbemowskD Offline
                dbemowskD Offline
                dbemowsk
                wrote on last edited by
                #7

                @niccodemi Though I agree that that is a better cleaner approach to the original sketch, it doesn't answer the OPs question. Maybe convert it using the info that I posted to make it relevant to the OPs question.

                Vera Plus running UI7 with MySensors, Sonoffs and 1-Wire devices
                Visit my website for more Bits, Bytes and Ramblings from me: http://dan.bemowski.info/

                1 Reply Last reply
                0
                • PlantexP Offline
                  PlantexP Offline
                  Plantex
                  wrote on last edited by
                  #8

                  Thank You. Works perfect and reporting to Domoticz/Imperi Home.

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


                  19

                  Online

                  11.7k

                  Users

                  11.2k

                  Topics

                  113.1k

                  Posts


                  Copyright 2025 TBD   |   Forum Guidelines   |   Privacy Policy   |   Terms of Service
                  • Login

                  • Don't have an account? Register

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