writing a code for 2 relays with 2 buttons and actuators



  • i want to add two buttons and two relays, i dont understand on how to combine them.

    I am having trouble with the incomingMessage function. The relay with Actuator example works fine but it does not have a button, what if i want a button or if i have relays on non-consecutive pins.

    i tried writing two functions for incoming message and it was just a foolish idea and i'm stuck.

    how do i get it to work.. please help..


  • Contest Winner

    @SandeshHs94 The MySensors library RelayActuator example shows how to handle 2 (or more) child node messages. There is no need to change this incommingMessage function when adding a button. Adding button requires read functionality in the loop()

    This sketch should work with 2 buttons (attached to pin 6 and 7)

    /**
     * The MySensors Arduino library handles the wireless radio link and protocol
     * between your home built sensors/actuators and HA controller of choice.
     * The sensors forms a self healing radio network with optional repeaters. Each
     * repeater and gateway builds a routing tables in EEPROM which keeps track of the
     * network topology allowing messages to be routed to nodes.
     *
     * Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
     * Copyright (C) 2013-2015 Sensnology AB
     * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
     *
     * Documentation: http://www.mysensors.org
     * Support Forum: http://forum.mysensors.org
     *
     * This program is free software; you can redistribute it and/or
     * modify it under the terms of the GNU General Public License
     * version 2 as published by the Free Software Foundation.
     *
     *******************************
     *
     * REVISION HISTORY
     * Version 1.0 - Henrik Ekblad
     * 
     * DESCRIPTION
     * Example sketch showing how to control physical relays. 
     * This example will remember relay state after power failure.
     * http://www.mysensors.org/build/relay
     */ 
    
    #include <MySigningNone.h>
    #include <MyTransportNRF24.h>
    #include <MyTransportRFM69.h>
    #include <MyHwATMega328.h>
    #include <MySensor.h>
    #include <SPI.h>
    #include <Bounce2.h>
    
    #define RELAY_1  3  // Arduino Digital I/O pin number for first relay (second on pin+1 etc)
    #define NUMBER_OF_RELAYS 2 // Total number of attached relays
    #define RELAY_ON 1  // GPIO value to write to turn on attached relay
    #define RELAY_OFF 0 // GPIO value to write to turn off attached relay
    #define BUTTON_PIN_1 6
    
    // NRFRF24L01 radio driver (set low transmit power by default) 
    MyTransportNRF24 radio(RF24_CE_PIN, RF24_CS_PIN, RF24_PA_LEVEL_GW);  
    //MyTransportRFM69 radio;
    // Message signing driver (none default)
    //MySigningNone signer;
    // Select AtMega328 hardware profile
    MyHwATMega328 hw;
    // Construct MySensors library
    MySensor gw(radio, hw);
    
    MyMessage msg[NUMBER_OF_RELAYS] = { MyMessage(1, V_LIGHT), MyMessage(2, V_LIGHT) } ;
    Bounce debouncer[NUMBER_OF_RELAYS] = { Bounce(), Bounce() }; 
    
    void setup()  
    {   
      // Initialize library and add callback for incoming messages
      gw.begin(incomingMessage, AUTO, true);
      // Send the sketch version information to the gateway and Controller
      gw.sendSketchInfo("Relay", "1.0");
    
      // Fetch relay status
      for (int sensor=1, pin=RELAY_1, swpin=BUTTON_PIN_1; sensor <= NUMBER_OF_RELAYS;sensor++, pin++, swpin++) {
        // Register all sensors to gw (they will be created as child devices)
        gw.present(sensor, S_LIGHT);
        // Then set relay pins in output mode
        pinMode(pin, OUTPUT);   
        // Set relay to last known state (using eeprom storage) 
        digitalWrite(pin, gw.loadState(sensor)?RELAY_ON:RELAY_OFF);
        
        // Setup the button
        pinMode(swpin, INPUT);
        // Activate internal pull-up
        digitalWrite(swpin, HIGH);
      
        // After setting up the button, setup debouncer
        debouncer[sensor-1].attach(swpin);
        debouncer[sensor-1].interval(5);
      }
    }
    
    
    void loop() 
    {
      // Alway process incoming messages whenever possible
      gw.process();
      
      for (int sensor = 0; sensor < NUMBER_OF_RELAYS; sensor++) {
          if (debouncer[sensor].update() && debouncer[sensor].read()) {
             gw.send(msg[sensor].set( (gw.loadState(sensor+1) ? RELAY_OFF : RELAY_ON)), true);
          }
      }
    }
    
    void incomingMessage(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
         gw.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());
       } 
    }
    


  • amazing.. thanks a lot but what about if i have to combine relayActuatorWithButton and
    relayActuator..
    do you have any code for that?
    and please explain what this line means and how it works..
    digitalWrite(message.sensor-1+RELAY_1, message.getBool()?RELAY_ON:RELAY_OFF);

    and how i can make the combination work without a for loop

    Thank you


  • Contest Winner

    @SandeshHs94 The sketch exactly is that: a combination of the relayActuatorWithButton and
    relayActuator.. examples

    This line does several things

    digitalWrite(message.sensor-1+RELAY_1, message.getBool()?RELAY_ON:RELAY_OFF);
    

    message.getBool() --> gets the "payload of the message" in this case 1=ON or 0=OFF
    message.sensor --> gives the node id for which the message is meant for
    RELAY_1 --> is the first pin definition (for this sketch 3)
    RELAY_ON --> equals pin HIGH
    RELAY_OFF --> equals pin LOW

    digitalWrite(pin, value); --> sets an output pin in this case pin: message.sensor-1+RELAY_1 (so either pin 3 for node 1 or pin 4 for node 2 messages)
    The ? is a short notation for an if statement so when the message.getBool() = 1 the pin is set to HIGH and when 0 the pin is set to LOW

    I'm not sure why you want no "for-loop", but the sketch would look like this example

    /**
     * The MySensors Arduino library handles the wireless radio link and protocol
     * between your home built sensors/actuators and HA controller of choice.
     * The sensors forms a self healing radio network with optional repeaters. Each
     * repeater and gateway builds a routing tables in EEPROM which keeps track of the
     * network topology allowing messages to be routed to nodes.
     *
     * Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
     * Copyright (C) 2013-2015 Sensnology AB
     * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
     *
     * Documentation: http://www.mysensors.org
     * Support Forum: http://forum.mysensors.org
     *
     * This program is free software; you can redistribute it and/or
     * modify it under the terms of the GNU General Public License
     * version 2 as published by the Free Software Foundation.
     *
     *******************************
     *
     * REVISION HISTORY
     * Version 1.0 - Henrik Ekblad
     * 
     * DESCRIPTION
     * Example sketch showing how to control physical relays. 
     * This example will remember relay state after power failure.
     * http://www.mysensors.org/build/relay
     */ 
    
    #include <MySigningNone.h>
    #include <MyTransportNRF24.h>
    #include <MyTransportRFM69.h>
    #include <MyHwATMega328.h>
    #include <MySensor.h>
    #include <SPI.h>
    #include <Bounce2.h>
    
    #define RELAY_1  3  // Arduino Digital I/O pin number for first relay (second on pin+1 etc)
    #define RELAY_2  4  // Arduino Digital I/O pin number for first relay (second on pin+1 etc)
    #define RELAY_ON 1  // GPIO value to write to turn on attached relay
    #define RELAY_OFF 0 // GPIO value to write to turn off attached relay
    #define BUTTON_PIN_1 6
    #define BUTTON_PIN_2 7
    
    // NRFRF24L01 radio driver (set low transmit power by default) 
    MyTransportNRF24 radio(RF24_CE_PIN, RF24_CS_PIN, RF24_PA_LEVEL_GW);  
    //MyTransportRFM69 radio;
    // Message signing driver (none default)
    //MySigningNone signer;
    // Select AtMega328 hardware profile
    MyHwATMega328 hw;
    // Construct MySensors library
    MySensor gw(radio, hw);
    
    MyMessage msg1(1, V_LIGHT);
    MyMessage msg2(2, V_LIGHT);
    Bounce debouncer1 = Bounce();
    Bounce debouncer2 = Bounce(); 
    
    void setup()  
    {   
      // Initialize library and add callback for incoming messages
      gw.begin(incomingMessage, AUTO, true);
      // Send the sketch version information to the gateway and Controller
      gw.sendSketchInfo("Relay", "1.0");
    
      // Register all sensors to gw (they will be created as child devices)
      gw.present(1, S_LIGHT);
      // Then set relay pins in output mode
      pinMode(RELAY_1, OUTPUT);   
      // Set relay to last known state (using eeprom storage) 
      digitalWrite(RELAY_1, gw.loadState(1)?RELAY_ON:RELAY_OFF);
      // Setup the button
      pinMode(BUTTON_PIN_1, INPUT);
      // Activate internal pull-up
      digitalWrite(BUTTON_PIN_1, HIGH);
      // After setting up the button, setup debouncer
      debouncer1.attach(BUTTON_PIN_1);
      debouncer1.interval(5);
      
      // Register all sensors to gw (they will be created as child devices)
      gw.present(2, S_LIGHT);
      // Then set relay pins in output mode
      pinMode(RELAY_2, OUTPUT);   
      // Set relay to last known state (using eeprom storage) 
      digitalWrite(RELAY_2, gw.loadState(2)?RELAY_ON:RELAY_OFF);
      // Setup the button
      pinMode(BUTTON_PIN_2, INPUT);
      // Activate internal pull-up
      digitalWrite(BUTTON_PIN_2, HIGH);
      // After setting up the button, setup debouncer
      debouncer2.attach(BUTTON_PIN_2);
      debouncer2.interval(5);
    }
    
    
    void loop() 
    {
      // Alway process incoming messages whenever possible
      gw.process();
      
      if (debouncer1.update() && debouncer1.read()) {
          gw.send(msg1.set( (gw.loadState(1) ? RELAY_OFF : RELAY_ON)), true);
      }
      if (debouncer2.update() && debouncer2.read()) {
          gw.send(msg2.set( (gw.loadState(2) ? RELAY_OFF : RELAY_ON)), true);
      }
    }
    
    void incomingMessage(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
         gw.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());
       } 
    }
    


  • I'm so sorry for such late reply... the reason i wanted no for loop was to see how the code for that would turn out...

    I have a project in mind with requires maybe 2 switches and if one is turned on then regardless of the message coming from controller for the second light it should stay off...


Log in to reply
 

Suggested Topics

  • 1
  • 5
  • 6
  • 1
  • 3
  • 1

0
Online

11.4k
Users

11.1k
Topics

112.7k
Posts