Relay Actuator with momentary (pulse) action



  • What do I need to edit in the relay actuator sketch in order to turn the relay on for about .5 seconds then turn it immediately back off?

    /**
     * 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
     */
    
    // Enable debug prints to serial monitor
    #define MY_DEBUG
    
    // Enable and select radio type attached
    #define MY_RADIO_NRF24
    //#define MY_RADIO_RFM69
    
    // Enable repeater functionality for this node
    #define MY_REPEATER_FEATURE
    
    #include <MySensors.h>
    
    #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
    #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
    
    
    void before()
    {
        for (int sensor=1, pin=RELAY_1; sensor<=NUMBER_OF_RELAYS; sensor++, pin++) {
            // Then set relay pins in output mode
            pinMode(pin, OUTPUT);
            // Set relay to last known state (using eeprom storage)
            digitalWrite(pin, loadState(sensor)?RELAY_ON:RELAY_OFF);
        }
    }
    
    void setup()
    {
    
    }
    
    void presentation()
    {
        // Send the sketch version information to the gateway and Controller
        sendSketchInfo("Relay", "1.0");
    
        for (int sensor=1, pin=RELAY_1; sensor<=NUMBER_OF_RELAYS; sensor++, pin++) {
            // Register all sensors to gw (they will be created as child devices)
            present(sensor, S_BINARY);
        }
    }
    
    
    void loop()
    {
    
    }
    
    void receive(const MyMessage &message)
    {
        // We only expect one type of message from controller. But we better check anyway.
        if (message.type==V_STATUS) {
            // Change relay state
            digitalWrite(message.sensor-1+RELAY_1, message.getBool()?RELAY_ON:RELAY_OFF);
            // Store state in eeprom
            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());
        }
    }
    

  • Mod

    @drradkin change

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

    to

    if (message.getBool() == RELAY_ON) {
    digitalWrite(message.sensor-1+RELAY_1, RELAY_ON);
    wait(500);
    digitalWrite(message.sensor-1+RELAY_1, RELAY_OFF);
    }
    

    and

    digitalWrite(pin, loadState(sensor)?RELAY_ON:RELAY_OFF);
    

    to

    if (loadState(sensor) == RELAY_ON) {
    digitalWrite(pin, RELAY_ON);
    wait(500);
    digitalWrite(pin, RELAY_OFF);
    }
    


  • @mfalkvidd Hello, today I used your suggestion, but in the meanwhile the code of RelayActuator.ino has changed a little bit.
    So this is what has changed and how I adjusted. This could be useful to another beginner like me.

    Change:

    digitalWrite(message.getSensor()-1+RELAY_PIN, message.getBool()?RELAY_ON:RELAY_OFF);
    

    to:

    if (message.getBool() == RELAY_ON) {
        digitalWrite(message.getSensor()-1+RELAY_PIN, RELAY_ON);
        wait(500);
        digitalWrite(message.getSensor()-1+RELAY_PIN, RELAY_OFF);
        }
    

  • Plugin Developer

    Here is my code, which I used to hack my dishwasher so I can turn it on via my smart home system. The code is designed to work well with the Mozilla WebThings gateway and the Candle project, which is based on MySensors. But it but should work just fine with any smart home controller that supports MySensors.

    /**
     * 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
     * 
     * 
     * 
     * Only sends a quick pulse via a relay. Useful to hack other devices with push 
     * buttons. In my case, a cheap IKEA dishwasher that didn't have a timer functionality.
     */
    
    // Enable debug prints to serial monitor
    #define DEBUG
    #define MY_DEBUG
    
    #define LOOP_DURATION 1000                          // The main loop runs every x milliseconds. This main loop starts the modem, and from then on periodically requests the password.
    #define SECONDS_BETWEEN_HEARTBEAT_TRANSMISSION 120  // The smart lock might not send any data for a very long time if it isn't used. Sending a heartbeat tells the controller: I'm still there.
    
    //#define RF_NANO                                     // RF-Nano. Check this box if you are using the RF-Nano Arduino, which has a built in radio. The Candle project uses the RF-Nano.
    
    
    
    
    #ifdef RF_NANO
    // If you are using an RF-Nano, you have to switch CE and CS pins.
    #define MY_RF24_CS_PIN 9                            // Used by the MySensors library.
    #define MY_RF24_CE_PIN 10                           // Used by the MySensors library.
    #endif
    
    // Enable and select radio type attached
    #define MY_RADIO_RF24
    #define MY_RF24_PA_LEVEL RF24_PA_MAX  
    //#define MY_RADIO_RFM69
    
    // Mysensors advanced settings
    #define MY_TRANSPORT_WAIT_READY_MS 10000            // Try connecting for 10 seconds. Otherwise just continue.
    //#define MY_RF24_CHANNEL 100                       // In EU the default channel 76 overlaps with wifi, so you could try using channel 100. But you will have to set this up on every device, and also on the controller.
    //#define MY_RF24_DATARATE RF24_1MBPS                 // Slower datarate makes the network more stable
    //#define MY_RF24_DATARATE RF24_250KBPS             // Slower datarate increases wireless range
    //#define MY_NODE_ID 10                             // Giving a node a manual ID can in rare cases fix connection issues.
    //#define MY_PARENT_NODE_ID 0                       // Fixating the ID of the gatewaynode can in rare cases fix connection issues.
    //#define MY_PARENT_NODE_IS_STATIC                  // Used together with setting the parent node ID. Daking the controller ID static can in rare cases fix connection issues.
    #define MY_SPLASH_SCREEN_DISABLED                   // Saves a little memory.
    //#define MY_DISABLE_RAM_ROUTING_TABLE_FEATURE      // Saves a little memory.
    
    // Mysensors security
    //#define DEBUG_SIGNING
    //#define MY_ENCRYPTION_SIMPLE_PASSWD "changeme"      // Be aware, the length of the password has an effect on memory use.
    //#define MY_SECURITY_SIMPLE_PASSWD "changeme"      // Be aware, the length of the password has an effect on memory use.
    //#define MY_SIGNING_SOFT_RANDOMSEED_PIN A7         // Setting a pin to pickup random electromagnetic noise helps make encryption more secure.
    
    
    // Enable repeater functionality for this node
    //#define MY_REPEATER_FEATURE
    
    #include <MySensors.h>
    
    #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
    #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 PULSELENGTH 500 // How long the pulse should last (how long the button should be pressed).
    #define RADIO_DELAY 100                             // Milliseconds delay betweeen radio signals. This gives the radio some breathing room.
    
    MyMessage relay_message(RELAY_1, V_STATUS); // A generic boolean state message.
    
    
    boolean desiredState = false;
    boolean send_all_values = 1;
    
    
    void before()
    {
      pinMode(RELAY_1, OUTPUT);
    	digitalWrite(RELAY_1, LOW);
    }
    
    void presentation()
    {
    	// Send the sketch version information to the gateway and Controller
    	sendSketchInfo(F("Dish washer"), F("1.0")); wait(RADIO_DELAY);
      present(RELAY_1, S_BINARY, F("Power") ); wait(RADIO_DELAY);
      
      send_all_values = true;                           // Whenever a new presentation is requested, we should also send the current values of the children.
    }
    
    void setup()
    {
      Serial.begin(115200);
      Serial.println(F("Hello world, I am a relay."));
    }
    
    void send_values()
    {
    #ifdef DEBUG
      Serial.println(F("Sending button states"));
    #endif
      send(relay_message.set(desiredState)); wait(RADIO_DELAY); // Send initial state
    }
    
    
    void loop()
    {
      if( send_all_values ){
    #ifdef DEBUG
        Serial.println(F("RESENDING VALUES"));
    #endif
        send_all_values = 0;
        send_values();
      }
    
    
    
      // Pulse the relay
      if(desiredState == 1){
        digitalWrite(RELAY_1, RELAY_ON);
        Serial.println(F("Turning on"));
        wait(PULSELENGTH);
        digitalWrite(RELAY_1, RELAY_OFF);
        Serial.println(F("Turned off"));
        
        desiredState = 0;
        send(relay_message.setSensor(RELAY_1).set(desiredState)); // Send off state
      }
    
    
    
      static unsigned long last_loop_time = 0;          // Holds the last time the main loop ran.
      static byte loop_counter = 0;                     // Count how many loops have passed (reset to 0 after at most 254 loops).
    
      if( millis() - last_loop_time > LOOP_DURATION ){ // Runs every second
        last_loop_time = millis();
    
        wdt_reset();                                  // Reset the watchdog timer. If this doesn't happen, the device must have crashed, and it will be automatically rebooted by the watchdog.
    
        if( loop_counter >= SECONDS_BETWEEN_HEARTBEAT_TRANSMISSION ){ // If a couple of minutes have passed, tell the controller we're still here
          loop_counter = 0;
          Serial.println(F("Sending heartbeat"));
          sendHeartbeat();
        }
      }
    
    }
    
    void receive(const MyMessage &message)
    {
      if( message.isAck() ){
    #ifdef DEBUG
        Serial.println(F("- Echo"));
    #endif
      }
      else if (message.type==V_STATUS) { // We only expect one type of message from controller. But we better check anyway.
    
        Serial.print("Incoming change for child:");
        Serial.print(message.sensor);
        Serial.print(", New status: ");
        Serial.println(message.getBool());
    
        // Change relay state
        desiredState = message.getBool(); //?RELAY_ON:RELAY_OFF;
        send(relay_message.setSensor(message.sensor).set(desiredState)); // Send on state
      }
    }
    

Log in to reply
 

Suggested Topics

  • 4
  • 7
  • 2
  • 14
  • 9
  • 30
  • 9
  • 17

164
Online

9.4k
Users

10.0k
Topics

104.5k
Posts