Relay_Actuator add second relay?



  • I have just got the 110v-230v AC to Mysensors PCB board working but I want to add another raley to PIN 5, how do I do that?

    /**
     * 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 for a "light switch" where you can control light or something 
     * else from both HA controller and a local physical button 
     * (connected between digital pin 3 and GND).
     * This node also works as a repeader for other nodes
     * http://www.mysensors.org/build/relay
     */ 
    
    // Enable debug prints to serial monitor
    #define MY_DEBUG 
    
    // Enable and select radio type attached
    #define MY_RADIO_NRF24
    //#define MY_RADIO_RFM69
    
    // Enabled repeater feature for this node
    #define MY_REPEATER_FEATURE
    
    #include <SPI.h>
    #include <MySensor.h>
    #include <Bounce2.h>
    
    #define RELAY_PIN  3  // Arduino Digital I/O pin number for relay 
    #define BUTTON_PIN  4  // Arduino Digital I/O pin number for button 
    #define CHILD_ID 1   // Id of the sensor child
    #define RELAY_ON 1
    #define RELAY_OFF 0
    
    Bounce debouncer = Bounce(); 
    int oldValue=0;
    bool state;
    
    MyMessage msg(CHILD_ID,V_LIGHT);
    
    void setup()  
    {  
      // 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);
    
      // Make sure relays are off when starting up
      digitalWrite(RELAY_PIN, RELAY_OFF);
      // Then set relay pins in output mode
      pinMode(RELAY_PIN, OUTPUT);   
          
      // Set relay to last known state (using eeprom storage) 
      state = loadState(CHILD_ID);
      digitalWrite(RELAY_PIN, state?RELAY_ON:RELAY_OFF);
    }
    
    void presentation()  {
      // Send the sketch version information to the gateway and Controller
      sendSketchInfo("Relay & Button", "1.0");
    
      // Register all sensors to gw (they will be created as child devices)
      present(CHILD_ID, S_LIGHT);
    }
    
    /*
    *  Example on how to asynchronously check for new messages from gw
    */
    void loop() 
    {
      debouncer.update();
      // Get the update value
      int value = debouncer.read();
      if (value != oldValue && value==0) {
          send(msg.set(state?false:true), true); // Send new state and request ack back
      }
      oldValue = value;
    } 
     
    void receive(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.type == V_LIGHT) {
         // Change relay state
         state = message.getBool();
         digitalWrite(RELAY_PIN, state?RELAY_ON:RELAY_OFF);
         // Store state in eeprom
         saveState(CHILD_ID, state);
        
         // Write some debug info
         Serial.print("Incoming change for sensor:");
         Serial.print(message.sensor);
         Serial.print(", New status: ");
         Serial.println(message.getBool());
       } 
    }
    


  • I Started experementing with:

    // Enable debug prints to serial monitor
    #define MY_DEBUG 
    
    // Enable and select radio type attached
    #define MY_RADIO_NRF24
    //#define MY_RADIO_RFM69
    
    // Enabled repeater feature for this node
    #define MY_REPEATER_FEATURE
    
    #include <SPI.h>
    #include <MySensor.h>
    #include <Bounce2.h>
    
    #define RELAY1_PIN  4  // Arduino Digital I/O pin number for relay 
    #define RELAY2_PIN  5  // Arduino Digital I/O pin number for relay 
    #define BUTTON_PIN  3  // Arduino Digital I/O pin number for button 
    #define CHILD1_ID 1   // Id of the sensor child
    #define CHILD2_ID 2
    #define RELAY1_ON 1
    #define RELAY1_OFF 0
    #define RELAY2_ON 1
    #define RELAY2_OFF 0
    Bounce debouncer = Bounce(); 
    int oldValue=0;
    bool state;
    
    MyMessage msg(CHILD1_ID,V_LIGHT);
    MyMessage msg(CHILD2_ID,V_LIGHT);
    
    void setup()  
    {  
      // 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);
    
      // Make sure relays are off when starting up
      digitalWrite(RELAY1_PIN, RELAY1_OFF);
      // Then set relay pins in output mode
      pinMode(RELAY1_PIN, OUTPUT);   
      // Make sure relays are off when starting up
      digitalWrite(RELAY2_PIN, RELAY2_OFF);
      // Then set relay pins in output mode
      pinMode(RELAY2_PIN, OUTPUT); 
          
      // Set relay to last known state (using eeprom storage) 
      state = loadState(CHILD1_ID);
      digitalWrite(RELAY1_PIN, state?RELAY1_ON:RELAY1_OFF);
       state = loadState(CHILD2_ID);
      digitalWrite(RELAY2_PIN, state?RELAY2_ON:RELAY2_OFF);
    }
    
    void presentation()  {
      // Send the sketch version information to the gateway and Controller
      sendSketchInfo("Relays & Button", "1.0");
    
      // Register all sensors to gw (they will be created as child devices)
      present(CHILD1_ID, S_LIGHT);
      present(CHILD2_ID, S_LIGHT);
    }
    
    /*
    *  Example on how to asynchronously check for new messages from gw
    */
    void loop() 
    {
      debouncer.update();
      // Get the update value
      int value = debouncer.read();
      if (value != oldValue && value==0) {
          send(msg.set(state?false:true), true); // Send new state and request ack back
      }
      oldValue = value;
    } 
     
    void receive(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.type == V_LIGHT) {
         // Change relay state
         state = message.getBool();
         digitalWrite(RELAY_PIN, state?RELAY_ON:RELAY_OFF);
         // Store state in eeprom
         saveState(CHILD_ID, state);
        
         // Write some debug info
         Serial.print("Incoming change for sensor:");
         Serial.print(message.sensor);
         Serial.print(", New status: ");
         Serial.println(message.getBool());
       } 
    }
    

    But first of all I dont know what do do with the button, I want to be able to control one of the relays with the button. Second is this part at the end:

    void receive(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.type == V_LIGHT) {
         // Change relay state
         state = message.getBool();
         digitalWrite(RELAY_PIN, state?RELAY_ON:RELAY_OFF);
         // Store state in eeprom
         saveState(CHILD_ID, state);
        
         // Write some debug info
         Serial.print("Incoming change for sensor:");
         Serial.print(message.sensor);
         Serial.print(", New status: ");
         Serial.println(message.getBool());
       } 
    

    How would I adapt that to the usage of two relays?



  • Check this thread



  • Optimus Prime Solution

    #include <MySensor.h>
    #include <SPI.h>
    #include <Bounce2.h>
    //#include "Bounce2.h"
    
    
    #define RELAY_ON 0                      // switch around for realy HIGH/LOW state
    #define RELAY_OFF 1
    
    //
    MySensor gw;
    
    #define RADIO_ID 13           // radio Id, whatever channel you assigned to 
    #define noRelays 2
    const int relayPin[] = {4,5};          //  switch around pins to your desire
    const int buttonPin[] = {6,7};      //  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
      byte oldValue;                    // last Values for key (debounce)
      boolean relayState;               // relay status (also stored in EEPROM)
    };
    
    Relay Relays[noRelays]; 
    Bounce debouncer[noRelays];
    MyMessage msg[noRelays];
    
    void setup(){
        gw.begin(incomingMessage, RADIO_ID, true);
        delay(250);
        gw.sendSketchInfo("Multy-Relay&Pulsanti", "0.");
        delay(250);
    
        // 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;
        debouncer[i] = Bounce();                        // initialize debouncer
        debouncer[i].attach(buttonPin[i]);
        debouncer[i].interval(5);
        pinMode(Relays[i].buttonPin, INPUT_PULLUP);
        pinMode(Relays[i].relayPin, OUTPUT);
        Relays[i].relayState = gw.loadState(i);                                   // retrieve last values from EEPROM
        digitalWrite(Relays[i].relayPin, Relays[i].relayState? RELAY_ON:RELAY_OFF);   // and set relays accordingly
        gw.send(msg[i].set(Relays[i].relayState? true : false));                  // make controller aware of last status
        gw.present(i, S_LIGHT);    // present sensor to gateway
        delay(250);
    
        }
    }
    
    void loop()
        {
        gw.process();
        for (byte i = 0; i < noRelays; i++){
        debouncer[i].update();
        byte value = debouncer[i].read();
        if (value != Relays[i].oldValue && value == 0){
        Relays[i].relayState = !Relays[i].relayState;
        digitalWrite(Relays[i].relayPin, Relays[i].relayState?RELAY_ON:RELAY_OFF);
        gw.send(msg[i].set(Relays[i].relayState? true : false));
        gw.saveState( i, Relays[i].relayState );}                 // save sensor state in EEPROM (location == sensor number)
        
            Relays[i].oldValue = value;
            
        }
    }
    
    // process incoming message 
    void incomingMessage(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
            gw.saveState( message.sensor, Relays[message.sensor].relayState ); // save sensor state in EEPROM (location == sensor number)
            }
        }
    }
    


  • @Michel--
    Many Kudos.
    i tried your code modified for my single relay and button pushes successfully trigger the relay! I'm also reading status correctly in Vera. 🙂

    I am having some trouble controlling the relay from Vera. It appears as if the msgs from Vera aren't a) being received by the node, b ) not interpreting the node

    I'm new to programming and not too sure of where to look.
    Any Suggestions?

    /**
     * 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 for a "light switch" where you can control light or something 
     * else from both HA controller and a local physical button 
     * (connected between digital pin 3 and GND).
     * This node also works as a repeader for other nodes
     * http://www.mysensors.org/build/relay
     */ 
    
    #include <MySensor.h>
    #include <SPI.h>
    #include <Bounce2.h>
    
    #define RELAY_PIN  4  // Arduino Digital I/O pin number for relay 
    #define BUTTON_PIN  3  // Arduino Digital I/O pin number for button 
    #define CHILD_ID 1   // Id of the sensor child
    #define RELAY_ON 0
    #define RELAY_OFF 1
    
    Bounce debouncer = Bounce(); 
    int oldValue=0;
    bool state;
    MySensor gw;
    MyMessage msg(CHILD_ID,V_LIGHT);
    
    void setup()  
    {  
      gw.begin();
    
      // Send the sketch version information to the gateway and Controller
      gw.sendSketchInfo("Relay & Button", "1.0");
    
     // 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(CHILD_ID, S_LIGHT);
    
      // Make sure relays are off when starting up
      digitalWrite(RELAY_PIN, RELAY_OFF);
      // Then set relay pins in output mode
      pinMode(RELAY_PIN, OUTPUT);   
          
      // Set relay to last known state (using eeprom storage) 
      state = gw.loadState(CHILD_ID);
      digitalWrite(RELAY_PIN, state?RELAY_ON:RELAY_OFF);
    }
    
    
    /*
    *  Example on how to asynchronously check for new messages from gw
    */
    void loop() 
    {
      gw.process();
      debouncer.update();
      // Get the update value
      int value = debouncer.read();
      if (value != oldValue && value==0) {
          gw.send(msg.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.type == V_LIGHT) {
         // Change relay state
         state = message.getBool();
         digitalWrite(RELAY_PIN, state?RELAY_ON:RELAY_OFF);
         // Store state in eeprom
         gw.saveState(CHILD_ID, state);
        
         // Write some debug info
         Serial.print("Incoming change for sensor:");
         Serial.print(message.sensor);
         Serial.print(", New status: ");
         Serial.println(message.getBool());
       } 
    }
    


  • I wanted to clarify that i got it working.

    I was browsing through the MySensors API and came across the Processing incomming messages section.

    What I interpreted out of the explanation there is that a node acting as a relay actuator NEEDS to be configured as a repeater node in order to run the code needed to interpret incoming messages.

    I kept removing the parameters in gw.begin() to make the node a non repeater because i have such a short range between my gateway and the node. Once i updated my sketch to configure the node as a repeater... BOOM! we're up and running!

    I did notice when configuring this node in Vera, that i needed to cycle the sensor 3 times to be fully operational. My steps were as follows:

    1. Delete node and light objects from vera. then Reload Vera.
    2. Run inclusion on gateway
    3. turn on node
    4. power cycle node to auto configure light object in vera to display on/off buttons and get sketch name and node details.
    5. power cycle node one more time. this seemed to get the sensor and Vera to sync up and report state properly back to UI5. after this everything was working wicked smooth.

    Now i need to work on adding in my DIY soil sensor in.

    I hope my resolution may help any other newbies in the world of this wonderful MySensors journey!

    Cheers


  • Plugin Developer

    @rchamp

    Calling gw.process in the loop and not sleeping should be sufficient for a relay. It shouldn't have to be configured as a repeater.



  • @martinhjelmare

    thank you. i corrected my code to not enable as a repeater




Log in to reply
 

Suggested Topics

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

18
Online

11.4k
Users

11.1k
Topics

112.7k
Posts