Operate two relays with one node individually + with a button?



  • I have been trying to control a two relay module using MQTT and openhab. So far I was able to control them individually. I can turn on relay one or turn off relay two and so on but I want to implement a single button which would control both also, in-case I want to turn on a light/device physically. Example: 1 press will trun on relay1, second press will turn on relay2 and third press will turn all relays off. or something like this.

    I'm not very good at programming and still learning. Below is my code:
    Note: my relay module is weird. Its Off on 1 (the led turns Off) and ON on 0 (LED turn On).

    
    #include <MySensor.h>
    #include <SPI.h>
    #include <Bounce2.h>
    
    #define SN "Relay Outlet"
    #define SV "1.0"
    #define NODE_ID 22
    
    #define RELAY_PIN_1  4  // Arduino Digital I/O pin number for first relay (second on pin+1 etc)
    #define RELAY_PIN_2  6  // Arduino Digital I/O pin number for first relay (second on pin+1 etc)
    #define BUTTON_PIN  3  // Arduino Digital I/O pin number for button 
    
    #define RELAY_1_CHILD 0
    #define RELAY_2_CHILD 1
    
    //#define NUMBER_OF_RELAYS 2 // 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
    
    Bounce debouncer = Bounce(); //for Button
    int oldValue=1;
    bool state;
    
    MySensor gw;
    
    MyMessage msg(RELAY_1_CHILD,V_LIGHT);
    MyMessage msg2(RELAY_2_CHILD,V_LIGHT);
    
    void setup()  
    {   
      // Initialize library and add callback for incoming messages
      gw.begin(incomingMessage, NODE_ID);
      // Send the sketch version information to the gateway and Controller
      gw.sendSketchInfo(SN, SV);
    
    // Setup the button
      pinMode(BUTTON_PIN,INPUT);
      // Activate internal pull-up
      digitalWrite(BUTTON_PIN,HIGH);
      
      // After setting up the button, setup debouncer
      debouncer.attach(BUTTON_PIN);
      debouncer.interval(5);
      
      // Register all sensors to gw (they will be created as child devices)
      gw.present(RELAY_1_CHILD, S_LIGHT);
      gw.present(RELAY_2_CHILD, S_LIGHT);
      // Make sure relays are off when starting up
      digitalWrite(RELAY_PIN_1, RELAY_OFF);
      digitalWrite(RELAY_PIN_2, RELAY_OFF);
      
      // Then set relay pins in output mode
      pinMode(RELAY_PIN_1, OUTPUT);   
      pinMode(RELAY_PIN_2, OUTPUT);   
    
    }
    
    void loop() 
    {
      // Alway process incoming messages whenever possible
      gw.process();
    
    debouncer.update();
      // Get the update value
      int value = debouncer.read();
      if (value != oldValue && value==1) {
          gw.send(msg.set(state?false:true), true); // Send new state and request ack back
          gw.send(msg2.set(state?false:true), true); // Send new state and request ack back
    
      }
      oldValue = value;
    
    }
    
    void incomingMessage(const MyMessage &message) 
    {
    // We only expect one type of message from controller. But we better check anyway.
      if (message.isAck()) 
      {
         Serial.println("This is an ack from gateway");
      } 
    
      if (message.sensor == RELAY_1_CHILD)
        {
          if (message.type == V_LIGHT && strlen(msg.getString()) != 1) 
          {
            // Change relay state
            state = message.getBool();
            digitalWrite(RELAY_PIN_1, state ? RELAY_ON : RELAY_OFF);
            // Store state in eeprom
            gw.saveState(RELAY_1_CHILD, state);
    
            // Write some debug info
            Serial.print("Incoming change for sensor:");
            Serial.print(message.sensor);
            Serial.print(", New status: ");
            Serial.println(message.getBool());
          }
    
          if (message.type == V_LIGHT) 
          {
            // Change relay state
            state = message.getBool();
            digitalWrite(RELAY_PIN_1, state ? RELAY_ON : RELAY_OFF);
            // Store state in eeprom
            gw.saveState(RELAY_1_CHILD, state);
    
            // Write some debug info
            Serial.print("Incoming change for sensor:");
            Serial.print(message.sensor);
            Serial.print(", New status: ");
            Serial.println(message.getBool());
          }
        }
        
    if (message.sensor == RELAY_2_CHILD)
        {
          if (message.type == V_LIGHT && strlen(msg2.getString()) != 1) 
          {
            // Change relay state
            state = message.getBool();
            digitalWrite(RELAY_PIN_2, state ? RELAY_ON : RELAY_OFF);
            // Store state in eeprom
            gw.saveState(RELAY_2_CHILD, state);
    
            // Write some debug info
            Serial.print("Incoming change for sensor:");
            Serial.print(message.sensor);
            Serial.print(", New status: ");
            Serial.println(message.getBool());
          }
    
          if (message.type == V_LIGHT) 
          {
            // Change relay state
            state = message.getBool();
            digitalWrite(RELAY_PIN_2, state ? RELAY_ON : RELAY_OFF);
            // Store state in eeprom
            gw.saveState(RELAY_2_CHILD, state);
    
            // Write some debug info
            Serial.print("Incoming change for sensor:");
            Serial.print(message.sensor);
            Serial.print(", New status: ");
            Serial.println(message.getBool());
          }
        }
    }
    

    I would really appreciate any help you can give me. Thank You 🙂



  • you should use eeprom to store button value, I think you can't use bounce for something like that as far I know. and better for you to use at least 2 button, one for control and another to reset value



  • @raditv can you please elaborate on using eeprom to store button value? Any example link may be? Thanks!





  • @raditv Thanks alot. I will look into it and get back with results.


 

239
Online

8.5k
Users

9.3k
Topics

98.5k
Posts