Upgrading to 2.0 sketch dificulty



  • Hi all,

    i've been trying for the last few hours to convert a multirelaywithbutton actuator to 2.0 with no sucess...

    the most i get is a "random" id of the relays in domoticz, and the buttons dont work properly..

    As so, i've founded an example in 2.0 but to a single relay.
    the sketch i've found in examples is:

    /**
     * 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 <MySensors.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 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());
       } 
    }
    

    Can anyone help geting this so i can have:
    4 relays
    4 buttons
    domoticz also controling each one?

    Many thanks in advance.


  • Mod

    @andmaster use the relay example for MySensors 2.0 (which is included with the library) and follow the instructions in the code comments and you should be all set.



  • @mfalkvidd this is the example 😃


  • Mod

    @andmaster no.

    The sketch you posted does not have these instructions:

    #define RELAY_1  3  // Arduino Digital I/O pin number for first relay (second on pin+1 etc)
    #define NUMBER_OF_RELAYS 1 // Total number of attached relays
    


  • @mfalkvidd the example is provided here: https://github.com/mysensors/MySensorsArduinoExamples/blob/master/examples/RelayWithButtonActuator/RelayWithButtonActuator.ino

    what you are mentioning is the example where you can put multiple relays, but without any button actuator.

    Thanks


  • Hardware Contributor

    @andmaster
    in fact @mfalkvidd is right, you have to "mix" the two sketch if you want multi relay with multiple buttons.
    could be fast to do, but i have no time.
    if you want show us your non working sketch, so we can tell what to do 😉



  • @andmaster

    I've used below sketch with 1.6 development version; it compiles also with 2.0.0 but I have not tested it. This sketch uses toggle buttons.

    //MultiRelayButton Sketch, MySensors 1.6, toggle switch
    
    #define MY_RADIO_NRF24
    
    #define MY_REPEATER_FEATURE
    
    #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                     // switch around for ACTIVE LOW / ACTIVE HIGH relay
    //
    
    #define noRelays 4                     //2-4, define number of relays
    const int relayPin[] = {14,15,16,17};          //  relay pins - should match noRelays
    const int buttonPin[] = {3,4,5,6};      //  button pins - should match noRelays
    
    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);
    }
    


  • hi @niccodemi that did the trick.

    I've made a quick comparison and i guess the issue was that i've defined my button without a proper array.

    this also has a change i think is important. i had a push button, and i wanted a toggle 🙂

    Just made a change. i want relay on to be 1 (high) and off to be 0 (low).
    This way, it starts every time at 0

    many thanks!!



  • @niccodemi

    Hi, I know that this is quite old topic, but only now I´m updating my home from version 1.5.4 to 2.*, most because reability issues. One thing I notice with you skecth is that if by any chance the gateway is not present the nodes can´t be used anymore after a power loss, I mean, one can not use the fisical buttons to switch the relays, because they will not respond. My question is if there is a way to keep the node up with out the gateway, in case it dies?

    Thanks


  • Hero Member

    @andredts As you have discovered version 2.1 nodes while booting will not proceed to the loop part of the sketch if the gateway is not found. You can however force them to move on. The line of code you need is...

    #define MY_TRANSPORT_WAIT_READY_MS 3000
    

    This code tells the node how long to wait for the uplink to be established before moving on to the rest of the sketch. The number at the end is how long to wait in milliseconds, in this case 3000ms (3 seconds). You can set this to a time of your choosing.

    if the node establishes the uplink it will move on without any delay.

    The above line is placed near the top of your sketch somewhere before

    #include <MySensors.h>
    

    have a look at these for a bit more detail....

    MY_TRANSPORT_DONT_CARE_MODE

    Synchronising Light switch



  • @Boots33 Thanks, that was exactly what I needed. Synchronizing was a great bonus.


Log in to reply
 

Suggested Topics

  • 3
  • 3
  • 4
  • 15
  • 10
  • 24

0
Online

11.2k
Users

11.1k
Topics

112.5k
Posts