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()); } }
-
@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); }
-
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 } }