💬 AC-DC double solid state relay module



  • Hello!!, my name is Alejandro, I'm from Spain and I have been working on something quite similar to this project. I would like to contribute to reach a final design. What I have done until now is a prototype board similar than yours and I would like to add a top board with touch buttons to fit into Livolo glass panel switch.
    https://es.aliexpress.com/store/product/Free-Shipping-Livolo-Luxury-White-Pearl-Crystal-Glass-151mm-80mm-EU-standard-Double-Glass-Panel-VL/500715_1684198410.html?spm=2114.12010608.0.0.6cyWwJ

    And try to do something like this also including ws2812 rgb led for touchpad and a small speaker just to sound someting when touch the button.

    https://z-uno.z-wave.me/projects/sensor-wall-switch-based-on-livolo-glass/

    My development is based on ESP8266 without rf communication but as I have progressed I have checked that Wifi connection is a complex system compared to rf so I am thinking to change to arduino or esp + nrf.



  • Hi everyone . I managed to create my first module and it seems to working but why at my domoticz only one switch appears as new device???



  • I solved my last problem, but now i see that although both of the switches in Domoticz show off, i have power on the second one. What could be the problem? Faulty ssr?


  • Hardware Contributor

    What's happening if you switch it on then off in domoticz ?



  • Either pressing on or off in domoticz, i have always power on the second outpout.



  • @johnym30 Can you post your sketch?



  • This is my sketch

    // MySensor Debug
    #define MY_DEBUG
    
    // Enables repeater functionality (relays messages from other nodes)
    #define MY_REPEATER_FEATURE
    
    // Comment line below if you don't want to use the temperature sensor
    #define MY_RADIO_NRF24
    #define MY_TRANSPORT_WAIT_READY_MS
    #define MY_PARENT_NODE_ID 2
    #define MY_RADIO_NRF24
    #include <MySensors.h>
    #include <SPI.h>
    #include <Bounce2.h>
    
    #define RELAY_PIN_1   3  // Arduino Digital I/O pin number for relay 
    #define RELAY_PIN_2  5
    #define BUTTON_PIN_1  4  // Arduino Digital I/O pin number for button 
    #define BUTTON_PIN_2 7
    
    #define CHILD_ID_1 8 // Id of the sensor child for 1st relay
    #define CHILD_ID_2 9 // Id of the sensor child for 2nd relay
    
    // Relay status
    #define RELAY_ON 1
    #define RELAY_OFF 0
    
    // Source of state change (used when printing debug information)
    #define CHANGE_STATE_SOURCE_RADIO 0
    #define CHANGE_STATE_SOURCE_SWITCH 1
    
    
    
    Bounce debouncer1 = Bounce();
    int oldValue;
    bool state1;
    Bounce debouncer2 = Bounce();
    int oldValue2;
    bool state2;
    
    MyMessage msg(CHILD_ID_1, V_LIGHT);
    MyMessage msg2(CHILD_ID_2, V_LIGHT);
    
    
    
    void presentation() {
      // Send the sketch version information to the gateway and Controller
      sendSketchInfo("Double Relay & Button", "0.2");
      // Register all sensors to gw (they will be created as child devices)
      present(CHILD_ID_1, S_LIGHT);
      present(CHILD_ID_2, S_LIGHT);
    
    }
    
    void setup()
    {
      // Setup the button
      pinMode(BUTTON_PIN_1, INPUT);
      // Activate internal pull-up
      digitalWrite(BUTTON_PIN_1, HIGH);
    
      // Setup the button
      pinMode(BUTTON_PIN_2, INPUT);
      // Activate internal pull-up
      digitalWrite(BUTTON_PIN_2, HIGH);
    
      // After setting up the button, setup debouncer
      debouncer1.attach(BUTTON_PIN_1);
      debouncer1.interval(5);
    
      debouncer2.attach(BUTTON_PIN_2);
      debouncer2.interval(5);
    
      // Set the initial values of oldValue/oldValue2 variables from status of physical switches
      //  if this is not done the loop() will detect status change and switch the relays on or off
      debouncer1.update();
      debouncer2.update();
      oldValue = debouncer1.read();
      oldValue2 = debouncer2.read();
    
    
      // Make sure relays are off when starting up
      setRelayState(RELAY_PIN_1, RELAY_OFF);
      // Then set relay pins in output mode
      pinMode(RELAY_PIN_1, OUTPUT);
    
      digitalWrite(RELAY_PIN_2, RELAY_OFF);
      // Then set relay pins in output mode
      pinMode(RELAY_PIN_2, OUTPUT);
    
      // Set relay to last known state (using eeprom storage)
      state1 = loadState(CHILD_ID_1);
      setRelayState(RELAY_PIN_1, state1);
    
      state2 = loadState(CHILD_ID_2);
      setRelayState(RELAY_PIN_2, state2);
    }
    
    
    /*
       Example on how to asynchronously check for new messages from gw
    */
    void loop()
    {
      debouncer1.update();
      debouncer2.update();
      // Get the update value
      int value1 = debouncer1.read();
      int value2 = debouncer2.read();
    
      if (value1 != oldValue) {
        send(msg.set(state1 ? false : true), true); // Send new state and request ack back
        // Write some debug info
        printStateChangedDebug(CHANGE_STATE_SOURCE_SWITCH, CHILD_ID_1, value1);
      }
      oldValue = value1;
    
      if (value2 != oldValue2) {
        send(msg2.set(state2 ? false : true), true); // Send new state and request ack back
        // Write some debug info
        printStateChangedDebug(CHANGE_STATE_SOURCE_SWITCH, CHILD_ID_2, value2);
      }
      oldValue2 = value2;
    
    }
    
    void receive(const MyMessage &message) {
      // We only expect one type of message from controller. But we better check anyway.
      if (message.isAck()) {
    #ifdef MY_DEBUG
        Serial.println(F("This is an ack from gateway"));
    #endif
      }
      else if (message.type == V_LIGHT && message.sensor == CHILD_ID_1) {
        // Change relay state
        state1 = message.getBool();
        setRelayState(RELAY_PIN_1, state1);
        // Store state in eeprom
        saveState(CHILD_ID_1, state1);
        // Write some debug info
        printStateChangedDebug(CHANGE_STATE_SOURCE_RADIO, CHILD_ID_1, state1);
      }
      else if (message.type == V_LIGHT && message.sensor == CHILD_ID_2) {
        state2 = message.getBool();
        setRelayState(RELAY_PIN_2, state2);
        // Store state in eeprom
        saveState(CHILD_ID_2, state2);
        // Write some debug info
        printStateChangedDebug(CHANGE_STATE_SOURCE_RADIO, CHILD_ID_2, state2);
      }
    }
    
    // Set status of a relay pin
    void setRelayState(byte relayPin, bool value) {
      digitalWrite(relayPin, value ? RELAY_ON : RELAY_OFF);
    }
    
    // Print debug info, centralized in one place to minimize memory usage and have only one #ifdef MY_DEBUG for all state change messages
    void printStateChangedDebug(int source, int sensorID, bool value) {
    #ifdef MY_DEBUG
      Serial.print(F("Sensor value changed, source="));
      Serial.print(source == CHANGE_STATE_SOURCE_RADIO ? F("Radio") : F("Physical switch"));
      Serial.print(F(", Sensor="));
      Serial.print(sensorID);
      Serial.print(F(", New status: "));
      Serial.println(value);
    #endif
    }
    


  • @johnym30 Can't see anything wrong with the sketch that causes the 2 outputs toggle at the same time. However, I have 2 remarks:

    1. Don't you need to set the pins to output before you set them low?
    2. You are not updating your gateway when you toggle the output with the switch.


  • @stray the think is that the first relay is working normal and i see the updates in domoticz when i turn it on or off.It is just the second relay that gives me power either it is on or off in domoticz.That is why i am thinking maybe the second relay is broken



  • hmm im having a hard time fitting these modules behind my lamp buttoms couse its swedish standar 70mm holes and the nrfmodule sticks out to much anyone know a good mod?





  • Hi everyone.Its me again!!!!
    Everything seems to be working just fine when i am using domoticz interface, but when i am using the hardware switches the icons in domoticz update from off to on but my lights wont turn on. If i turn my hardware switch to off, the state in domoticz stays to on.What am i doing wrong????
    My sketch below .

    /**
     * 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.
     *
     *******************************
     *
     * DESCRIPTION
     *
     * Script for double SSR relay board by Aproxx
     * https://www.openhardware.io/view/77/AC-DC-double-solid-state-relay-module
     * https://forum.mysensors.org/topic/3671/ac-dc-double-solid-state-relay-module
     * Control 2 circuits either from controller or from physical buttons connected on pins 4 & 7
     * Optional DS18b20 is connected on pin 8
     * 
     *  HISTORY :
     * xx/xx/2016 original version by Aproxx
     * 08/02/2016 upgraded to MySensors 2.0 by mr_const
     * 08/30/2016 changes by Nca78 :
     *        - fixed initialization of physical buttons/debouncer status
     *        - centralized pin status change for relays in setRelayState method
     *        - centralized debug information for state changes in one method + added debug info when changed by physical switches
     *        - added #ifdef MY_DEBUG before each Serial.print (saves prog memory when not in debug mode) and F() macros for debug strings (saves RAM when in debug mode)
     *        - added #define USE_TEMP_SENSOR to make temperature sensor optional (not used if line is commented)
     *        - put back #define for repeater feature
     *        - add #define TEMPERATURE_ROUNDING for custom temperature rounding
    **/
    
    // MySensor Debug
    //#define MY_DEBUG
    
    // Enables repeater functionality (relays messages from other nodes)
    //#define MY_REPEATER_FEATURE
    
    // Comment line below if you don't want to use the temperature sensor
    #define USE_TEMP_SENSOR
    
    #define MY_RADIO_NRF24
    #include <MySensors.h>
    #include <SPI.h>
    #include <Bounce2.h>
    
    #define RELAY_PIN    3  // Arduino Digital I/O pin number for relay 
    #define RELAY_PIN_2  5
    #define BUTTON_PIN   4  // Arduino Digital I/O pin number for button 
    #define BUTTON_PIN_2 7
    
    #define CHILD_ID 8 // Id of the sensor child for 1st relay
    #define CHILD_ID_2 9 // Id of the sensor child for 2nd relay
    
    // Relay status
    #define RELAY_ON 1
    #define RELAY_OFF 0
    
    // Source of state change (used when printing debug information)
    #define CHANGE_STATE_SOURCE_RADIO 0
    #define CHANGE_STATE_SOURCE_SWITCH 1
    
    
    // Temperature sensor definitions
    #ifdef USE_TEMP_SENSOR
    #include <OneWire.h>
    #include <DallasTemperature.h>
    #define ONE_WIRE_BUS 8
    #define CHILD_DSB_ID 13 // Id of the sensor child for temperature sensor
    #define TEMPERATURE_ROUNDING 10.f   // Change value to change rounding of temperature value: 10.f for 0.1°C change, 5.f for 0.2°C change, 2.f for 0.5°C change
    #endif
    
    
    
    Bounce debouncer = Bounce();
    int oldValue;
    bool state;
    Bounce debouncer2 = Bounce();
    int oldValue2;
    bool state2;
    
    MyMessage msg(CHILD_ID, V_LIGHT);
    MyMessage msg2(CHILD_ID_2, V_LIGHT);
    
    #ifdef USE_TEMP_SENSOR
    MyMessage msgTemp(CHILD_DSB_ID, V_TEMP);
    OneWire oneWire(ONE_WIRE_BUS);
    DallasTemperature sensors(&oneWire); // Pass the oneWire reference to Dallas Temperature.
    #endif
    
    void presentation() {
      // Send the sketch version information to the gateway and Controller
      sendSketchInfo("Double Relay & Button", "0.2");
      // Register all sensors to gw (they will be created as child devices)
      present(CHILD_ID, S_LIGHT);
      present(CHILD_ID_2, S_LIGHT);
    #ifdef USE_TEMP_SENSOR
      present(CHILD_DSB_ID, S_TEMP);
    #endif
    }
    
    void setup()
    {
    #ifdef USE_TEMP_SENSOR
      sensors.begin();
      sensors.setWaitForConversion(false);
    #endif
    
      // Setup the button
      pinMode(BUTTON_PIN, INPUT);
      // Activate internal pull-up
      digitalWrite(BUTTON_PIN, HIGH);
    
      // Setup the button
      pinMode(BUTTON_PIN_2, INPUT);
      // Activate internal pull-up
      digitalWrite(BUTTON_PIN_2, HIGH);
    
      // After setting up the button, setup debouncer
      debouncer.attach(BUTTON_PIN);
      debouncer.interval(5);
    
      debouncer2.attach(BUTTON_PIN_2);
      debouncer2.interval(5);
    
      // Set the initial values of oldValue/oldValue2 variables from status of physical switches
      //  if this is not done the loop() will detect status change and switch the relays on or off
      debouncer.update();
      debouncer2.update();
      oldValue = debouncer.read();
      oldValue2 = debouncer2.read();
    
    
      // Make sure relays are off when starting up
      setRelayState(RELAY_PIN, RELAY_OFF);
      // Then set relay pins in output mode
      pinMode(RELAY_PIN, OUTPUT);
    
      digitalWrite(RELAY_PIN_2, RELAY_OFF);
      // Then set relay pins in output mode
      pinMode(RELAY_PIN_2, OUTPUT);
    
      // Set relay to last known state (using eeprom storage)
      state = loadState(CHILD_ID);
      setRelayState(RELAY_PIN, state);
    
      state2 = loadState(CHILD_ID_2);
      setRelayState(RELAY_PIN_2, state2);
    }
    
    
    /*
       Example on how to asynchronously check for new messages from gw
    */
    void loop()
    {
    #ifdef USE_TEMP_SENSOR
      static float prevTemp = 0;
    #endif
    
      debouncer.update();
      debouncer2.update();
      // Get the update value
      int value = debouncer.read();
      int value2 = debouncer2.read();
    
      if (value != oldValue) {
        send(msg.set(state ? false : true), true); // Send new state and request ack back
        // Write some debug info
        printStateChangedDebug(CHANGE_STATE_SOURCE_SWITCH, CHILD_ID, value);
      }
      oldValue = value;
    
      if (value2 != oldValue2) {
        send(msg2.set(state2 ? false : true), true); // Send new state and request ack back
        // Write some debug info
        printStateChangedDebug(CHANGE_STATE_SOURCE_SWITCH, CHILD_ID_2, value2);
      }
      oldValue2 = value2;
    
      // Fetch temperatures from Dallas sensors
    #ifdef USE_TEMP_SENSOR
      sensors.requestTemperatures();
      // Fetch and round temperature to one decimal
      float temperature = static_cast<float>(static_cast<int>(sensors.getTempCByIndex(0) * TEMPERATURE_ROUNDING)) / TEMPERATURE_ROUNDING;
    
      if (temperature != -127.00f && temperature != 85.00f && prevTemp != temperature) {
        // Send in the new temperature
        send(msgTemp.set(temperature, 1));
    #ifdef MY_DEBUG
        Serial.print("Sent temperature: ");
        Serial.println(temperature);
    #endif
        prevTemp = temperature;
      }
    #endif
    }
    
    void receive(const MyMessage &message) {
      // We only expect one type of message from controller. But we better check anyway.
      if (message.isAck()) {
    #ifdef MY_DEBUG
        Serial.println(F("This is an ack from gateway"));
    #endif
      }
      else if (message.type == V_LIGHT && message.sensor == CHILD_ID) {
        // Change relay state
        state = message.getBool();
        setRelayState(RELAY_PIN, state);
        // Store state in eeprom
        saveState(CHILD_ID, state);
        // Write some debug info
        printStateChangedDebug(CHANGE_STATE_SOURCE_RADIO, CHILD_ID, state);
      }
      else if (message.type == V_LIGHT && message.sensor == CHILD_ID_2) {
        state2 = message.getBool();
        setRelayState(RELAY_PIN_2, state2);
        // Store state in eeprom
        saveState(CHILD_ID_2, state2);
        // Write some debug info
        printStateChangedDebug(CHANGE_STATE_SOURCE_RADIO, CHILD_ID_2, state2);
      }
    }
    
    // Set status of a relay pin
    void setRelayState(byte relayPin, bool value) {
      digitalWrite(relayPin, value ? RELAY_ON : RELAY_OFF);
    }
    
    // Print debug info, centralized in one place to minimize memory usage and have only one #ifdef MY_DEBUG for all state change messages
    void printStateChangedDebug(int source, int sensorID, bool value) {
    #ifdef MY_DEBUG
      Serial.print(F("Sensor value changed, source="));
      Serial.print(source == CHANGE_STATE_SOURCE_RADIO ? F("Radio") : F("Physical switch"));
      Serial.print(F(", Sensor="));
      Serial.print(sensorID);
      Serial.print(F(", New status: "));
      Serial.println(value);
    #endif
    }
    


  • Anyone has the hardware switches working??? I can't make them work!!!! Help please!!!!!


  • Admin

    I doubt anyone can help you without debug logs from your node and gateway.

    You can also look at the logs yourself using this tool to see where messages get stuck or lost.



  • How do I wire if I have ''2 buttons on the same lamp'' and also want to connect '' 1buttom to 1lamp'' to the same module how do I wire 2button 1 lamp?



  • @hek the think is that the switch works using Domoticz, but when i use the pins for the hardware switch , i get the icons updated in domotics to on or off but my lights stay off


  • Hero Member

    @johnym30 It might be the way the code is written in your receive function.

    When you toggle the hardware switch a message is sent to your controller with the new state, so Domoticz will get this and change the icons accordingly. The message you sent also asks for an ack back, it is this returning ack that is used to switch the relay.

    The first If statement in your present code captures the ack and does a serial print but then does nothing else, so your ack is ignored by the rest of the code. So your relay will not be switched.

    I see no reason why you need to test for an ack so try the following code and see if it helps

    void receive(const MyMessage &message) { 
    if (message.type == V_STATUS) {
     switch (message.sensor) {
      case CHILD_ID:    
        state = message.getBool();          // Change relay state
        setRelayState(RELAY_PIN, state);    
        saveState(CHILD_ID, state);        // Store state in eeprom
        // Write some debug info
        printStateChangedDebug(CHANGE_STATE_SOURCE_RADIO, CHILD_ID, state);
        break; 
      case CHILD_ID_2:
        state2 = message.getBool();
        setRelayState(RELAY_PIN_2, state2);
        saveState(CHILD_ID_2, state2);     // Store state in eeprom
        // Write some debug info
        printStateChangedDebug(CHANGE_STATE_SOURCE_RADIO, CHILD_ID_2, state2);
        break;
      }
     }
    }
    

    You might also like to move the the lines that set oldvalue to new value. They probably should be inside the relevant if statement. In the original relay with button actuator code they are outside but that is using push buttons not toggle switches.

     if (value != oldValue) {
        send(msg.set(state ? false : true), true); // Send new state and request ack back
        // Write some debug info
        printStateChangedDebug(CHANGE_STATE_SOURCE_SWITCH, CHILD_ID, value);
        oldValue = value;
      }
      
    
      if (value2 != oldValue2) {
        send(msg2.set(state2 ? false : true), true); // Send new state and request ack back
        // Write some debug info
        printStateChangedDebug(CHANGE_STATE_SOURCE_SWITCH, CHILD_ID_2, value2);
        oldValue2 = value2;
      }
    

    The other thing you should note is that as the code relies on an ack from your gateway to switch the relay your hardware switches will not work if the gateway is not available. You will need to further modify the code to ensure the switches work at all times.



  • @Boots33 Thanks they are working now!!!!!!!
    Unfortunately i dont know about coding, i am more of a hardware guy, so i will just have to live with that.Hoping that in the future someone will write something and share it with us.
    Thank you once more.


  • Hero Member

    @johnym30 There are only a few changes to be made to make the hardware switches more reliable. @hek showed in this post some code that could be used.

    First you will need to add a line near the top of your sketch to allow the node to execute the loop part of the sketch even if no transport uplink is established. This code needs to be placed before #include <MySensors.h>

    #define MY_TRANSPORT_WAIT_READY_MS 3000     //set how long to wait for transport ready.
    

    The number at the end of the line is used to set how long to wait in milliseconds. I have found that my nodes will usually connect within 3 seconds.

    Then you need to modify the code in the loop part of your sketch.

    if (value != oldValue) {
        state =  !state;                                                  // Toggle the state
        send(msg.set(state), false);                          // send new state to controller, no ack requested
        setRelayState(RELAY_PIN, state);                // switch the relay to the new state
        saveState(CHILD_ID, state);        // Store state in eeprom
        // Write some debug info
        printStateChangedDebug(CHANGE_STATE_SOURCE_SWITCH, CHILD_ID, value);
        oldValue = value;
      }
      
    
      if (value2 != oldValue2) {
        state2 =  !state2;                                         // Toggle the state
        send(msg2.set(state2), false);                 // send new state to controller, no ack requested
        setRelayState(RELAY_PIN_2, state2);     // switch the relay to the new state
        saveState(CHILD_ID_2, state2);     // Store state in eeprom
        // Write some debug info
        printStateChangedDebug(CHANGE_STATE_SOURCE_SWITCH, CHILD_ID_2, value2);
        oldValue2 = value2;
      }
    


  • @Boots33 Will you please upload your complete code. It is difficult to see the finale solution then I read all the posts.


  • Hero Member

    @folkestorp I have no node to try it on but the code will look like this. perhaps you can test it and let us know if it works. I have just placed it in the original code of a few posts up

    /**
     * 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.
     *
     *******************************
     *
     * DESCRIPTION
     *
     * Script for double SSR relay board by Aproxx
     * https://www.openhardware.io/view/77/AC-DC-double-solid-state-relay-module
     * https://forum.mysensors.org/topic/3671/ac-dc-double-solid-state-relay-module
     * Control 2 circuits either from controller or from physical buttons connected on pins 4 & 7
     * Optional DS18b20 is connected on pin 8
     * 
     *  HISTORY :
     * xx/xx/2016 original version by Aproxx
     * 08/02/2016 upgraded to MySensors 2.0 by mr_const
     * 08/30/2016 changes by Nca78 :
     *        - fixed initialization of physical buttons/debouncer status
     *        - centralized pin status change for relays in setRelayState method
     *        - centralized debug information for state changes in one method + added debug info when changed by physical switches
     *        - added #ifdef MY_DEBUG before each Serial.print (saves prog memory when not in debug mode) and F() macros for debug strings (saves RAM when in debug mode)
     *        - added #define USE_TEMP_SENSOR to make temperature sensor optional (not used if line is commented)
     *        - put back #define for repeater feature
     *        - add #define TEMPERATURE_ROUNDING for custom temperature rounding
    **/
    
    // MySensor Debug
    //#define MY_DEBUG
    
    // Enables repeater functionality (relays messages from other nodes)
    //#define MY_REPEATER_FEATURE
    
    // Comment line below if you don't want to use the temperature sensor
    #define USE_TEMP_SENSOR
    #define MY_TRANSPORT_WAIT_READY_MS 3000     //set how long to wait for transport ready.
    #define MY_RADIO_NRF24
    #include <MySensors.h>
    #include <SPI.h>
    #include <Bounce2.h>
    
    #define RELAY_PIN    3  // Arduino Digital I/O pin number for relay 
    #define RELAY_PIN_2  5
    #define BUTTON_PIN   4  // Arduino Digital I/O pin number for button 
    #define BUTTON_PIN_2 7
    
    #define CHILD_ID 8 // Id of the sensor child for 1st relay
    #define CHILD_ID_2 9 // Id of the sensor child for 2nd relay
    
    // Relay status
    #define RELAY_ON 1
    #define RELAY_OFF 0
    
    // Source of state change (used when printing debug information)
    #define CHANGE_STATE_SOURCE_RADIO 0
    #define CHANGE_STATE_SOURCE_SWITCH 1
    
    
    // Temperature sensor definitions
    #ifdef USE_TEMP_SENSOR
    #include <OneWire.h>
    #include <DallasTemperature.h>
    #define ONE_WIRE_BUS 8
    #define CHILD_DSB_ID 13 // Id of the sensor child for temperature sensor
    #define TEMPERATURE_ROUNDING 10.f   // Change value to change rounding of temperature value: 10.f for 0.1°C change, 5.f for 0.2°C change, 2.f for 0.5°C change
    #endif
    
    
    
    Bounce debouncer = Bounce();
    int oldValue;
    bool state;
    Bounce debouncer2 = Bounce();
    int oldValue2;
    bool state2;
    
    MyMessage msg(CHILD_ID, V_LIGHT);
    MyMessage msg2(CHILD_ID_2, V_LIGHT);
    
    #ifdef USE_TEMP_SENSOR
    MyMessage msgTemp(CHILD_DSB_ID, V_TEMP);
    OneWire oneWire(ONE_WIRE_BUS);
    DallasTemperature sensors(&oneWire); // Pass the oneWire reference to Dallas Temperature.
    #endif
    
    void presentation() {
      // Send the sketch version information to the gateway and Controller
      sendSketchInfo("Double Relay & Button", "0.2");
      // Register all sensors to gw (they will be created as child devices)
      present(CHILD_ID, S_LIGHT);
      present(CHILD_ID_2, S_LIGHT);
    #ifdef USE_TEMP_SENSOR
      present(CHILD_DSB_ID, S_TEMP);
    #endif
    }
    
    void setup()
    {
    #ifdef USE_TEMP_SENSOR
      sensors.begin();
      sensors.setWaitForConversion(false);
    #endif
    
      // Setup the button
      pinMode(BUTTON_PIN, INPUT);
      // Activate internal pull-up
      digitalWrite(BUTTON_PIN, HIGH);
    
      // Setup the button
      pinMode(BUTTON_PIN_2, INPUT);
      // Activate internal pull-up
      digitalWrite(BUTTON_PIN_2, HIGH);
    
      // After setting up the button, setup debouncer
      debouncer.attach(BUTTON_PIN);
      debouncer.interval(5);
    
      debouncer2.attach(BUTTON_PIN_2);
      debouncer2.interval(5);
    
      // Set the initial values of oldValue/oldValue2 variables from status of physical switches
      //  if this is not done the loop() will detect status change and switch the relays on or off
      debouncer.update();
      debouncer2.update();
      oldValue = debouncer.read();
      oldValue2 = debouncer2.read();
    
    
      // Make sure relays are off when starting up
      setRelayState(RELAY_PIN, RELAY_OFF);
      // Then set relay pins in output mode
      pinMode(RELAY_PIN, OUTPUT);
    
      digitalWrite(RELAY_PIN_2, RELAY_OFF);
      // Then set relay pins in output mode
      pinMode(RELAY_PIN_2, OUTPUT);
    
      // Set relay to last known state (using eeprom storage)
      state = loadState(CHILD_ID);
      setRelayState(RELAY_PIN, state);
    
      state2 = loadState(CHILD_ID_2);
      setRelayState(RELAY_PIN_2, state2);
    }
    
    
    /*
       Example on how to asynchronously check for new messages from gw
    */
    void loop()
    {
    #ifdef USE_TEMP_SENSOR
      static float prevTemp = 0;
    #endif
    
      debouncer.update();
      debouncer2.update();
      // Get the update value
      int value = debouncer.read();
      int value2 = debouncer2.read();
    
      if (value != oldValue) {
        state =  !state;                                                  // Toggle the state
        send(msg.set(state), false);                          // send new state to controller, no ack requested
        setRelayState(RELAY_PIN, state);                // switch the relay to the new state
        saveState(CHILD_ID, state);        // Store state in eeprom
        // Write some debug info
        printStateChangedDebug(CHANGE_STATE_SOURCE_SWITCH, CHILD_ID, value);
        oldValue = value;
      }
      
    
      if (value2 != oldValue2) {
        state2 =  !state2;                                         // Toggle the state
        send(msg2.set(state2), false);                 // send new state to controller, no ack requested
        setRelayState(RELAY_PIN_2, state2);     // switch the relay to the new state
        saveState(CHILD_ID_2, state2);     // Store state in eeprom
        // Write some debug info
        printStateChangedDebug(CHANGE_STATE_SOURCE_SWITCH, CHILD_ID_2, value2);
        oldValue2 = value2;
      }
      
    
      // Fetch temperatures from Dallas sensors
    #ifdef USE_TEMP_SENSOR
      sensors.requestTemperatures();
      // Fetch and round temperature to one decimal
      float temperature = static_cast<float>(static_cast<int>(sensors.getTempCByIndex(0) * TEMPERATURE_ROUNDING)) / TEMPERATURE_ROUNDING;
    
      if (temperature != -127.00f && temperature != 85.00f && prevTemp != temperature) {
        // Send in the new temperature
        send(msgTemp.set(temperature, 1));
    #ifdef MY_DEBUG
        Serial.print("Sent temperature: ");
        Serial.println(temperature);
    #endif
        prevTemp = temperature;
      }
    #endif
    }
    
    void receive(const MyMessage &message) { 
    if (message.type == V_STATUS) {
     switch (message.sensor) {
      case CHILD_ID:    
        state = message.getBool();          // Change relay state
        setRelayState(RELAY_PIN, state);    
        saveState(CHILD_ID, state);        // Store state in eeprom
        // Write some debug info
        printStateChangedDebug(CHANGE_STATE_SOURCE_RADIO, CHILD_ID, state);
        break; 
      case CHILD_ID_2:
        state2 = message.getBool();
        setRelayState(RELAY_PIN_2, state2);
        saveState(CHILD_ID_2, state2);     // Store state in eeprom
        // Write some debug info
        printStateChangedDebug(CHANGE_STATE_SOURCE_RADIO, CHILD_ID_2, state2);
        break;
      }
     }
    }
    
    
    
    // Set status of a relay pin
    void setRelayState(byte relayPin, bool value) {
      digitalWrite(relayPin, value ? RELAY_ON : RELAY_OFF);
    }
    
    // Print debug info, centralized in one place to minimize memory usage and have only one #ifdef MY_DEBUG for all state change messages
    void printStateChangedDebug(int source, int sensorID, bool value) {
    #ifdef MY_DEBUG
      Serial.print(F("Sensor value changed, source="));
      Serial.print(source == CHANGE_STATE_SOURCE_RADIO ? F("Radio") : F("Physical switch"));
      Serial.print(F(", Sensor="));
      Serial.print(sensorID);
      Serial.print(F(", New status: "));
      Serial.println(value);
    #endif
    }
    


  • @Boots33 I have test your code without temp sensor. It works perfect. Thank you!!!


  • Hero Member

    @folkestorp great. Thanks for reporting back.



  • I got a problem. I connected the board directly to ä powersource but the adapter doesnt output 5V . The part before just output 230 v just fine. Any one has any sugestions on whatsapp im missing?


  • Hardware Contributor

    @XerOps do you have 230V on the input pins of the HLK ?



  • @Nca78 Well yeah, trough a completly soldered board tough, with both fuses and the varsisitator.



  • Hi,

    Many thanks for sharing this project!

    Is this also possible to post a picture of the other side of the PCB in order to get a better idea on how the Arduino is soldered?

    Kind regards,


  • Hardware Contributor



  • @laucarlier

    Hi Tonerre33,

    Thanks a lot for sharing the picture of your project!

    I really like the idea of the way you put the PSU and the arduino so that you win a lot of space!

    Kind regards,



  • Hi,

    it is very cool project. I assembled one but when I test it this is what I get:

    16:18:39.980 [DEBUG] [orsAbstractConnection$MySensorsReader] - Message from gateway received: 0;255;3;0;9;TSF:MSG:READ,101-101-255,s=255,c=3,t=7,pt=0,l=0,sg=0:
    16:18:39.981 [DEBUG] [orsAbstractConnection$MySensorsReader] - Message from gateway received: 0;255;3;0;9;TSF:MSG:BC
    16:18:39.982 [DEBUG] [orsAbstractConnection$MySensorsReader] - Message from gateway received: 0;255;3;0;9;TSF:MSG:FPAR REQ,ID=101
    16:18:39.985 [DEBUG] [orsAbstractConnection$MySensorsReader] - Message from gateway received: 0;255;3;0;9;TSF:PNG:SEND,TO=0
    16:18:39.988 [DEBUG] [orsAbstractConnection$MySensorsReader] - Message from gateway received: 0;255;3;0;9;TSF:CKU:OK
    16:18:39.993 [DEBUG] [orsAbstractConnection$MySensorsReader] - Message from gateway received: 0;255;3;0;9;TSF:MSG:GWL OK
    16:18:40.963 [DEBUG] [orsAbstractConnection$MySensorsReader] - Message from gateway received: 0;255;3;0;9;Will not sign message for destination 101 as it does not require it
    16:18:41.004 [DEBUG] [orsAbstractConnection$MySensorsReader] - Message from gateway received: 0;255;3;0;9;!TSF:MSG:SEND,0-0-101-101,s=255,c=3,t=8,pt=1,l=1,sg=0,ft=0,st=NACK:0
    16:18:41.010 [DEBUG] [orsAbstractConnection$MySensorsReader] - Message from gateway received: 0;255;3;0;9;TSF:MSG:READ,12-12-0,s=255,c=3,t=24,pt=1,l=1,sg=0:1
    16:18:41.013 [DEBUG] [orsAbstractConnection$MySensorsReader] - Message from gateway received: 0;255;3;0;9;TSF:MSG:PINGED,ID=12,HP=1
    16:18:41.018 [DEBUG] [orsAbstractConnection$MySensorsReader] - Message from gateway received: 0;255;3;0;9;Skipping security for command 3 type 25
    16:18:41.029 [DEBUG] [orsAbstractConnection$MySensorsReader] - Message from gateway received: 0;255;3;0;9;TSF:MSG:SEND,0-0-12-12,s=255,c=3,t=25,pt=1,l=1,sg=0,ft=0,st=OK:1
    16:18:44.038 [DEBUG] [orsAbstractConnection$MySensorsReader] - Message from gateway received: 0;255;3;0;9;TSF:MSG:READ,101-101-255,s=255,c=3,t=7,pt=0,l=0,sg=0:
    16:18:44.039 [DEBUG] [orsAbstractConnection$MySensorsReader] - Message from gateway received: 0;255;3;0;9;TSF:MSG:BC
    16:18:44.040 [DEBUG] [orsAbstractConnection$MySensorsReader] - Message from gateway received: 0;255;3;0;9;TSF:MSG:FPAR REQ,ID=101
    16:18:44.041 [DEBUG] [orsAbstractConnection$MySensorsReader] - Message from gateway received: 0;255;3;0;9;TSF:CKU:OK,FCTRL
    16:18:44.044 [DEBUG] [orsAbstractConnection$MySensorsReader] - Message from gateway received: 0;255;3;0;9;TSF:MSG:GWL OK
    16:18:44.974 [DEBUG] [orsAbstractConnection$MySensorsReader] - Message from gateway received: 0;255;3;0;9;Will not sign message for destination 101 as it does not require it
    16:18:45.016 [DEBUG] [orsAbstractConnection$MySensorsReader] - Message from gateway received: 0;255;3;0;9;!TSF:MSG:SEND,0-0-101-101,s=255,c=3,t=8,pt=1,l=1,sg=0,ft=0,st=NACK:0

    I guess it shows that radio has unreliable power. Please advise how should I debug?

    regards



  • The problem dissapeared when I changed 4.7uf capacitator to 47uf. works great!



  • Where to find a sketch with temperature read?


  • Mod

    @rzylius could you be a bit more specific? Do you want a way to read the temperature of the solid state relay?


  • Hardware Contributor



  • Hello,

    Thank you for sharing this project. I have built it and am testing it on my outdoor lights.
    .
    I have three issues I can't seem to figure out and am hoping others may have had similar problems and figured out a fix.

    First some background. I built a double relay board and have 120V 60 hz power. I am controlling it through MyNodes 2.0. I am using an unedited version of the source code. My networks includes about 7 other nodes that are only measuring temperature. Half of them are set up to be repeater nodes. I was suspicious that I may be getting interference from the other nodes causing the problem but have had the same problems with the other nodes disabled.

    Here are the issues I am trying to fix.

    1. I am finding that the relays will not stay in the position they are controlled to be in. Mostly they close when controlled to be open but also they are opening when controlled to be closed.
    2. When in a closed state relay 1 flickers every few minutes. I have replaced this relay and still have the same issue.
    3. The hardwired switch control isn't working for me work. The switch only causes a flicker in the lights.

    Any suggestions? For me Half of the fun in the projects is trouble shooting and making them work. I'll send updates on any fixes I come across.



  • Hi and Thank you for the Board!!!

    My question is, kann I user an usual old fashioned Light switch or must I buy a push button??



  • @nca78
    I used the code and it worked well with the remote control.-
    I can switch a LED (for testing purposes attached instead of a SSR) on and off.
    If I want to switch the LED with a push button I fail.

    This is what I have changed:

    #define RELAY_PIN 4 // Arduino Digital I/O pin number for relay
    #define RELAY_PIN_2 5
    #define BUTTON_PIN 3 // Arduino Digital I/O pin number for button
    #define BUTTON_PIN_2 7

    And this is the serial output I get, after I press the button:

    This is an ack from gateway
    1107867 TSF:MSG:SEND,10-10-0-0,s=111,c=1,t=2,pt=1,l=1,sg=0,ft=0,st=OK:1
    Sensor value changed, source=Physical switch, Sensor=111, New status: 0
    1107877 TSF:MSG:READ,0-0-10,s=111,c=1,t=2,pt=1,l=1,sg=0:1
    1107888 TSF:MSG:ACK
    This is an ack from gateway
    1108520 TSF:MSG:SEND,10-10-0-0,s=111,c=1,t=2,pt=1,l=1,sg=0,ft=0,st=OK:1
    Sensor value changed, source=Physical switch, Sensor=111, New status: 1
    1108531 TSF:MSG:READ,0-0-10,s=111,c=1,t=2,pt=1,l=1,sg=0:1
    1108541 TSF:MSG:ACK
    This is an ack from gateway



  • Hi,
    Any particular reason for the values of the thermal cut-offs? (73ºC, 10A)?
    This temperature (73ºC) makes it difficult to solder, I've burned a couple when trying to solder it... And why 10A? Shouldn't we get a lower current? I know the other fuse is limiting the current to 0.2A, but if we have a lower current on this one we may get cheaper components... Wouldn't this one, for instance, do the same function? https://www.ebay.com/itm/10-Pcs-Fuji-Microtemp-Thermal-Fuse-115-TF-Cutoff-1A-250V-New/322657006381

    If the PCB is inside a box, without any lossen wires, couldn't we limit the temperature to a sliglhly higher value (115ºC)?

    Thanks


  • Hardware Contributor

    Hello @joaoabs,

    I think it is based on measurements here :
    https://lygte-info.dk/review/Power Mains to 5V 0.6A Hi-Link HLK-PM01 UK.html

    As you can see when he tests at full load (0.6A) for a long time, max temperature is a bit over 60°C. So temperature should not be too much higher than that if you want to detect abnormal overheating. 115° is higher than what is measured at the hottest point on the top of the enclosure after 15mn overloading at twice the maximum load, so I don't think it's safe to use a temp fuse that high.

    For the max current there might be a short inrush current when switching on, so 1A could be a bit low (and that's why the other fuse is a slow blow fuse), but feel free to try and report 🙂



  • This looks like a great PCB and I'm interested in ordering a few from DirtyPCBs, however OpenHardware.io shows this project as "Work in Progress". Are there any plans to do additional updates to this PCB?



  • Hi,
    did you consider redesigning the PCB using mini nrf24l01+ like this:
    alt text
    It could compact the size of the whole device. Moreover it would be great to have GND and Vcc (3.3V or 5V), and 4 GPIO (ie. 2 analog, 2 digital) pins led out on the PCB (there are 6 holes on the edge not used as I understand?). It would be great to have an option to connect some additional sensors (I use 2 dht22 sensors for environment monitoring in some projects).



  • Unfortunately the Bottom copper layer is corrupted.
    Anybody has a good file for me?



  • how is the board and specially the hlk-pm01 transformer,that is the component that i need more trust ,after 3 years of work?

    i want to make some rolle shutter controllers to replace the expensive and buggy fibaro FGR-223 new modules.



  • What varistor should I use for 240VAC in Australia? The linked AliExpress item is no longer available.



  • Hi all,

    I've got two fully equipped, ready to go soldered v3.3.2 boards, two working USB gateways based on Arduino Nano, as well as 8 unsoldered PCBs (without the parts) to give away. I've used the system in my previous flat and it worked great. However, when I moved I wasn't able to fit them behind my light switches :(((
    I don't have time anymore to solder my own boards and switched to some China Zigbee boards. They use cheap standard relais and do not react as quick as the mysensor module unfortunately. Long story short, they are sitting around in my cupboard and I thought it might help someone to quickly expand their system or to kickstart before investing to much effort.
    I'm based in Germany so I would prefer to ship it to someone in Germany, however if nobody is interested then I would ship it abroad as well. Message me if you're interested 🙂


  • Banned

    Unfortunately the Bottom copper layer is corrupted.
    (Spam links removed by moderator)


  • Banned

    Does anyone know how to convert diptrace to kicad format? I want to try and edit to make a RFM69 version.



  • @kaylestoinis In principle, I tried to do it this way and succeeded:

    • Installed diptrace free
    • opened the schematic file
    • exported to eagle
    • imported eagle file in KiCad
    • same for the board file


  • thanks for the design.
    I did build a unit in 2018.
    Today I build one to control the light on my front door. It will be triggered by the IR Motion sensor.
    The Switch indoors will be just to power the light (and the arduino) off completly.
    Because of the IR Sensor VCC near the PIN 4 GND GND PIN7 Header.
    I routed my own with a wire.

    Never have I soldered a slow blow fuse in one go 🙂



  • What I didn't quite figure out was how it operates independently as a regular light switch.

    What I find most interesting is that this is 8 years old. There have been some incredible advances in the IoT world in that time. I was about to do a similar thing which morphed into an ESP-12F then added a touch screen. I call it the Universal Light Switch

    Imagine this: All the switches are identical. Any switch can easily be configured to control up to five devices ... and then changed, on-the-fly, to control a different set of devices.

    My design is part of a system that would require a controller (eg. Home Assistant), an MQTT broker, and receiving modules in the devices being switched. It's WiFI which assumes an access point.

    The DIY ULS is under $20 and the off-the-shelf receiving modules are under $10. (About the cost of a non-networked dimmer switch) If one doesn't have the controller and MQTT broker, they can run on an old (5 years?) computer (which is cheaper than an old RasberryPi).

    This project is a good one!

    OSD



Suggested Topics

0
Online

11.4k
Users

11.1k
Topics

112.7k
Posts