PLEASE! A How to would be amazing! Looking forward to it!
rhuehn
@rhuehn
Best posts made by rhuehn
-
RE: Multisensor PIR based on IKEA Molgan
-
RE: Help with PIR and Water Sensor or Nano - Water Sensor won't trigger
Got it working with this sleep function properly:
// Sleep until interrupt comes in on motion or water sensor. Send update every two minute. gw.sleep(DIGITAL_INPUT_SENSOR - 2, CHANGE, DIGITAL_INPUT_WATER_SENSOR - 2, CHANGE, SLEEP_TIME);
Latest posts made by rhuehn
-
RE: Prevent Relay from triggering on power loss or broker reboot
Hey guys! Thanks so very much for all the great comments. I haven't replied in a few days as I wanted to go back to the drawing board..... I didn't like that sketch, the sleep functions, etc etc.... It didn't also make sense clearly based on everyone's feedback ( Sorry I am just getting started with IDE... ) So, based on that, I've come up with the following, and if you could comment, modify where I messed up, it would be greatly appreciated. This sketch seems to work, and keep state on power LOSS. There's a relay for the garage door ( trigger, PIN 4 ), a reed switch to detect if the door is open or closed ( PIN 2 ), a DHT for Temp / Humidity ( PIN 7 ), and a PIR ( PIN 3 ) for motion activated events. Below is the sketch, and would really appreciate any great feedback.
Thanks again!
#define MY_DEBUG #define MY_RADIO_NRF24 #define MY_REPEATER_FEATURE #define MY_NODE_ID 50 #include <SPI.h> #include <MySensors.h> #include <Bounce2.h> #include <DHT.h> #define RELAY_1 4 // 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 TOGGLE_INTERVAL 350 #define CHILD_ID_SW 2 #define BUTTON_PIN 2 // Arduino Digital I/O pin for button/reed switch // Sleep time between sensor updates (in milliseconds) // Must be >1000ms for DHT22 and >2000ms for DHT11 static const uint64_t UPDATE_INTERVAL = 60000; // Force sending an update of the temperature after n sensor reads, so a controller showing the // timestamp of the last update doesn't show something like 3 hours in the unlikely case, that // the value didn't change since; // i.e. the sensor would force sending an update every UPDATE_INTERVAL*FORCE_UPDATE_N_READS [ms] static const uint8_t FORCE_UPDATE_N_READS = 10; float lastTemp; float lastHum; uint8_t nNoUpdatesTemp; uint8_t nNoUpdatesHum; bool metric = true; #define CHILD_ID_HUM 10 #define CHILD_ID_TEMP 11 #define HUMIDITY_SENSOR_DIGITAL_PIN 7 // Set this offset if the sensor has a permanent small offset to the real temperatures #define SENSOR_TEMP_OFFSET -1 #define CHILD_ID_PIR 3 #define PIR_PIN 3 byte StatePIR=0; byte oldStatePIR=0; Bounce debouncer = Bounce(); int oldValue=-1; MyMessage msgSw(CHILD_ID_SW,V_TRIPPED); MyMessage msgHum(CHILD_ID_HUM, V_HUM); // 1 MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP); // 0 MyMessage msgPir(CHILD_ID_PIR, V_TRIPPED); DHT dht; 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() { dht.setup(HUMIDITY_SENSOR_DIGITAL_PIN); // set data pin of DHT sensor if (UPDATE_INTERVAL <= dht.getMinimumSamplingPeriod()) { Serial.println("Warning: UPDATE_INTERVAL is smaller than supported by the sensor!"); } // Sleep for the time of the minimum sampling period to give the sensor time to power up // (otherwise, timeout errors might occure for the first reading) sleep(dht.getMinimumSamplingPeriod()); pinMode(PIR_PIN, INPUT_PULLUP); // 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); } void presentation() { // Send the sketch version information to the gateway and Controller sendSketchInfo("Garage Multi Sensor", "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); present(CHILD_ID_SW, S_DOOR); present(CHILD_ID_HUM, S_HUM); present(CHILD_ID_TEMP, S_TEMP); present(CHILD_ID_PIR, S_MOTION); metric = getConfig().isMetric; } } void loop() { StatePIR=digitalRead(PIR_PIN); if (StatePIR != oldStatePIR) { oldStatePIR=StatePIR; send(msgPir.set(StatePIR ? "ON" : "OFF")); // Force reading sensor, so it works also after sleep() dht.readSensor(true); // Get temperature from DHT library float temperature = dht.getTemperature(); if (isnan(temperature)) { Serial.println("Failed reading temperature from DHT!"); } else if (temperature != lastTemp || nNoUpdatesTemp == FORCE_UPDATE_N_READS) { // Only send temperature if it changed since the last measurement or if we didn't send an update for n times lastTemp = temperature; if (!metric) { temperature = dht.toFahrenheit(temperature); } // Reset no updates counter nNoUpdatesTemp = 0; temperature += SENSOR_TEMP_OFFSET; send(msgTemp.set(temperature, 1)); #ifdef MY_DEBUG Serial.print("T: "); Serial.println(temperature); #endif } else { // Increase no update counter if the temperature stayed the same nNoUpdatesTemp++; } // Get humidity from DHT library float humidity = dht.getHumidity(); if (isnan(humidity)) { Serial.println("Failed reading humidity from DHT"); } else if (humidity != lastHum || nNoUpdatesHum == FORCE_UPDATE_N_READS) { // Only send humidity if it changed since the last measurement or if we didn't send an update for n times lastHum = humidity; // Reset no updates counter nNoUpdatesHum = 0; send(msgHum.set(humidity, 1)); #ifdef MY_DEBUG Serial.print("H: "); Serial.println(humidity); #endif } else { // Increase no update counter if the humidity stayed the same nNoUpdatesHum++; } } debouncer.update(); // Get the update value int value = debouncer.read(); if (value != oldValue) { // Send in the new value send(msgSw.set(value==HIGH ? 1 : 0)); oldValue = value; } } 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); //Keep the relay on for the amount of time defined by TOGGLE_INTERVAL delay( TOGGLE_INTERVAL ); digitalWrite( RELAY_1, 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()); } }
-
RE: Prevent Relay from triggering on power loss or broker reboot
Hello @Boots33
The Reed switch should NOT have any effect on the relay. ( It shouldn't anyways, it only senses open / closed
From my understanding here:
https://home-assistant.io/components/mysensors/
It needs to be done in the loop function:
Present the sensor’s S_TYPE.
Send at least one initial value per V_TYPE. In version 2.0 of MySensors this has to be done in the loop function. See below for an example in 2.0 of how to make sure the initial value has been received by the controller.Below is an example from that page:
/* * Documentation: http://www.mysensors.org * Support Forum: http://forum.mysensors.org * * http://www.mysensors.org/build/relay */ #define MY_DEBUG #define MY_RADIO_NRF24 #define MY_REPEATER_FEATURE #define MY_NODE_ID 1 #include <SPI.h> #include <MySensors.h> #include <Bounce2.h> #define RELAY_PIN 5 #define BUTTON_PIN 3 #define CHILD_ID 1 #define RELAY_ON 1 #define RELAY_OFF 0 Bounce debouncer = Bounce(); bool state = false; bool initialValueSent = false; MyMessage msg(CHILD_ID, V_STATUS); void setup() { pinMode(BUTTON_PIN, INPUT_PULLUP); debouncer.attach(BUTTON_PIN); debouncer.interval(10); // Make sure relays are off when starting up digitalWrite(RELAY_PIN, RELAY_OFF); pinMode(RELAY_PIN, OUTPUT); } void presentation() { sendSketchInfo("Relay+button", "1.0"); present(CHILD_ID, S_BINARY); } void loop() { if (!initialValueSent) { Serial.println("Sending initial value"); send(msg.set(state?RELAY_ON:RELAY_OFF)); Serial.println("Requesting initial value from controller"); request(CHILD_ID, V_STATUS); wait(2000, C_SET, V_STATUS); } if (debouncer.update()) { if (debouncer.read()==LOW) { state = !state; // Send new state and request ack back send(msg.set(state?RELAY_ON:RELAY_OFF), true); } } } void receive(const MyMessage &message) { if (message.isAck()) { Serial.println("This is an ack from gateway"); } if (message.type == V_STATUS) { if (!initialValueSent) { Serial.println("Receiving initial value from controller"); initialValueSent = true; } // Change relay state state = (bool)message.getInt(); digitalWrite(RELAY_PIN, state?RELAY_ON:RELAY_OFF); send(msg.set(state?RELAY_ON:RELAY_OFF)); } }
I was just following some guidelines to use HASS+ My Sensors together.
-
RE: Prevent Relay from triggering on power loss or broker reboot
Hey @Boots33 Thanks very much for the reply. I apologize I should have elaborated further.
My home automation platform is Home Assistant. I am using a few mysensors around the house for temp, motion etc, and the purpose of this very sensor / sketch is to be used as a garage door opener. I am using an Uno, with the following PINS:
PIR - PIN 3
DHT - PIN 7
Relay - PIN 4
Reed switch - PIN 2The PIR and the DHT are just fun addon sensors that might trigger an action based on motion or temp.
The Reed switch can tell when the garage door is open or closed based on contact, and the relay's purpose is to provide a momentary "press" of the garage door wall control, ( I have it wired into the opener and relay ).
It currently works great, but on loss of power at the house ( The arduino is plugged in ), the relay trips on reload, causing the garage door to open / close, and well, if we are away from the house, this is obviously not good.
I just tried implementing your change you recommended, and unfortunately on reboot, the relay still triggers. Ideally, if I could have the relay not trigger on reboot, then I would consider it safe. I'm sure it's possible, I just can't figure out how to not have it reset / trigger on AC power fail. The interface appears as follows:
I did make the modification, but the results are the same, so I won't re paste the code block.
Thanks very much for the help @Boots33 if there are any other code mods I could make, I really would appreciate it.
Thanks!
-
RE: Prevent Relay from triggering on power loss or broker reboot
@Boots33 Thanks very much for the reply, and I know this is late in my response so I apologize about that....
So this sketch does the following. A Replay that momentarily interrupts the garage door button to simulate a press of the control button, has a PIR and a DHT for motion and temp / hum, and also has a reed switch that can determine if the door is open or closed. I've been playing none stop with the sketch, and have tweaked it to the best of my ability, but STILL on power loss, the relay always clicks... therefore opening or closing the door...... Based on these changes, is there any way I can clean this up ( I'm at a loss unfortunately ) so that on power loss the relay remains as it was "state"? I've tried a few combinations without any luck to this point. My revised sketch is below, and I really appreciate any help.
Thanks
#define MY_DEBUG #define MY_RADIO_NRF24 #define MY_REPEATER_FEATURE #define MY_NODE_ID 50 #include <SPI.h> #include <MySensors.h> #include <Bounce2.h> #include <DHT.h> #define CHILD_ID_TEMP 11 #define CHILD_ID_HUM 10 #define CHILD_ID_MOT 3 // Id of the sensor child #define CHILD_ID_REL 1 #define RELAY_PIN 4 #define RELAY_ON 1 #define RELAY_OFF 0 #define TOGGLE_INTERVAL 350 //Tells how many milliseconds the relay will be held closed #define CLOSED 0 #define OPEN 1 #define BUTTON_PIN_1 2 #define CHILD_ID_SW 2 #define HUMIDITY_SENSOR_DIGITAL_PIN 7 #define DIGITAL_INPUT_SENSOR 3 // The digital input you attached your motion sensor. (Only 2 and 3 generates interrupt!) #define INTERRUPT DIGITAL_INPUT_SENSOR-2 // Usually the interrupt = pin -2 (on uno/nano anyway) // Set this offset if the sensor has a permanent small offset to the real temperatures #define SENSOR_TEMP_OFFSET 1 Bounce debouncer = Bounce(); int oldValue=-1; bool state = false; bool initialValueSent = false; byte StatePIR=0; byte oldStatePIR=0; unsigned long SLEEP_TIME = 60000; // Sleep time between reads (in milliseconds) DHT dht; float lastTemp; float lastHum; boolean metric = true; bool StateREL=0, StateREL1=0; MyMessage msgHum(CHILD_ID_HUM, V_HUM); MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP); MyMessage msgMot(CHILD_ID_MOT, V_TRIPPED); MyMessage msg(CHILD_ID_REL, V_STATUS); MyMessage msgSW(CHILD_ID_SW,V_TRIPPED); void presentation() { // Send the Sketch Version Information to the Gateway sendSketchInfo("Garage Multi Sensor", "1.0"); // Register all sensors to gw (they will be created as child devices) delay(100); present(CHILD_ID_TEMP, S_TEMP); delay(100); present(CHILD_ID_HUM, S_HUM); delay(100); present(CHILD_ID_MOT, S_MOTION); delay(100); present(CHILD_ID_REL, S_BINARY); delay(100); present(CHILD_ID_SW, S_DOOR); metric = getConfig().isMetric; } void setup() { // Setup the button pinMode(BUTTON_PIN_1,INPUT); // Activate internal pull-up digitalWrite(BUTTON_PIN_1,HIGH); // After setting up the button, setup debouncer debouncer.attach(BUTTON_PIN_1); debouncer.interval(5); // Make sure relays are off when starting up pinMode(RELAY_PIN, OUTPUT); digitalWrite(RELAY_PIN, StateREL1); dht.setup(HUMIDITY_SENSOR_DIGITAL_PIN); if (SLEEP_TIME <= dht.getMinimumSamplingPeriod()) { Serial.println("Warning: UPDATE_INTERVAL is smaller than supported by the sensor!"); } // Sleep for the time of the minimum sampling period to give the sensor time to power up // (otherwise, timeout errors might occure for the first reading) sleep(dht.getMinimumSamplingPeriod()); // metric = getConfig().isMetric; pinMode(DIGITAL_INPUT_SENSOR, INPUT); // sets the motion sensor digital pin as input } void loop() { debouncer.update(); // Get the update value int value = debouncer.read(); if (value != oldValue) { // Send in the new value send(msgSW.set(value==HIGH ? 1 : 0)); oldValue = value; } StatePIR=digitalRead(DIGITAL_INPUT_SENSOR); if (StatePIR != oldStatePIR) { oldStatePIR=StatePIR; send(msgMot.set(StatePIR ? 1 : 0)); } if (!initialValueSent) { Serial.println("Sending initial value"); send(msg.set(state?RELAY_ON:RELAY_OFF)); Serial.println("Requesting initial value from controller"); request(CHILD_ID_REL, V_STATUS); wait(2000, C_SET, V_STATUS); } if (debouncer.update()) { if (debouncer.read()==LOW) { state = !state; // Send new state and request ack back send(msg.set(state?RELAY_ON:RELAY_OFF), true); } } // Read digital motion value boolean tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH; Serial.println(tripped); send(msgMot.set(tripped?"1":"0")); // Send tripped value to gw delay(dht.getMinimumSamplingPeriod()); // Fetch temperatures from DHT sensor float temperature = dht.getTemperature(); if (isnan(temperature)) { Serial.println("Failed reading temperature from DHT"); } else if (temperature != lastTemp) { lastTemp = temperature; if (!metric) { temperature = dht.toFahrenheit(temperature); } temperature += SENSOR_TEMP_OFFSET; send(msgTemp.set(temperature, 1)); #ifdef MY_DEBUG Serial.print("T: "); Serial.println(temperature); #endif } // Fetch humidity from DHT sensor float humidity = dht.getHumidity(); if (isnan(humidity)) { Serial.println("Failed reading humidity from DHT"); } else if (humidity != lastHum) { lastHum = humidity; send(msgHum.set(humidity, 1)); #ifdef MY_DEBUG Serial.print("H: "); Serial.println(humidity); #endif } sleep(INTERRUPT,CHANGE, SLEEP_TIME); //sleep a bit } void receive(const MyMessage &message) { if (message.isAck()) { Serial.println("This is an ack from gateway"); } if (message.type == V_STATUS) { if (!initialValueSent) { Serial.println("Receiving initial value from controller"); initialValueSent = true; } // Change relay state state = (bool)message.getInt(); digitalWrite(RELAY_PIN, state?RELAY_ON:RELAY_OFF); //Keep the relay on for the amount of time defined by TOGGLE_INTERVAL delay( TOGGLE_INTERVAL ); digitalWrite( RELAY_PIN, RELAY_OFF ); // Store state in eeprom saveState(message.sensor, message.getBool()); send(msg.set(state?RELAY_ON:RELAY_OFF)); } }
-
RE: Prevent Relay from triggering on power loss or broker reboot
@hek Thanks for the reply, but I'm not 100% sure as I am still somewhat new to mysensors and arduino. Is there any chance you could possibly show an example using the above sketch I pasted previously?
Thanks!
-
Prevent Relay from triggering on power loss or broker reboot
Hey guys:
I'm currently using a relay to control a garage door opener, but when the MQTT broker reboots, or the Arduino reboots, the relay's click on and off, of course opening / closing the garage door. Is there a way to have the relay's remember state and NOT click on and off in case of power or broker restart? I am not much of a coder, and combled this together, so if anyone can help it would be greatly appreciated!
#define MY_DEBUG #define MY_RADIO_NRF24 #define MY_REPEATER_FEATURE #define MY_NODE_ID 50 #include <SPI.h> #include <MySensors.h> #include <Bounce2.h> #include <DHT.h> #define CHILD_ID_TEMP 11 #define CHILD_ID_HUM 10 #define CHILD_ID_MOT 3 // Id of the sensor child #define HUMIDITY_SENSOR_DIGITAL_PIN 7 #define DIGITAL_INPUT_SENSOR 3 // The digital input you attached your motion sensor. (Only 2 and 3 generates interrupt!) #define INTERRUPT DIGITAL_INPUT_SENSOR-2 // Usually the interrupt = pin -2 (on uno/nano anyway) #define RELAY_PIN 4 #define CHILD_ID_REL 1 #define RELAY_ON 1 #define RELAY_OFF 0 #define TOGGLE_INTERVAL 350 //Tells how many milliseconds the relay will be held closed #define CHILD_ID_SW 2 #define BUTTON_PIN_2 2 // Arduino Digital I/O pin for button/reed switch Bounce debouncer = Bounce(); bool state = false; bool initialValueSent = false; Bounce debouncer2 = Bounce(); int oldValue2=-1; unsigned long SLEEP_TIME = 60000; // Sleep time between reads (in milliseconds) DHT dht; float lastTemp; float lastHum; boolean metric = true; MyMessage msgHum(CHILD_ID_HUM, V_HUM); MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP); MyMessage msgMot(CHILD_ID_MOT, V_TRIPPED); MyMessage msg(CHILD_ID_REL, V_STATUS); MyMessage msgSW(CHILD_ID_SW,V_TRIPPED); void presentation() { // Send the Sketch Version Information to the Gateway sendSketchInfo("Temp/Hum/Mot", "1.3"); // Register all sensors to gw (they will be created as child devices) delay(100); present(CHILD_ID_TEMP, S_TEMP); delay(100); present(CHILD_ID_HUM, S_HUM); delay(100); present(CHILD_ID_MOT, S_MOTION); delay(100); present(CHILD_ID_REL, S_BINARY); delay(100); present(CHILD_ID_SW, S_DOOR); metric = getConfig().isMetric; } void setup() { // Setup the button pinMode(BUTTON_PIN_2,INPUT); // Activate internal pull-up digitalWrite(BUTTON_PIN_2,HIGH); // After setting up the button, setup debouncer debouncer2.attach(BUTTON_PIN_2); debouncer2.interval(5); // Make sure relays are off when starting up digitalWrite(RELAY_PIN, RELAY_OFF); pinMode(RELAY_PIN, OUTPUT); dht.setup(HUMIDITY_SENSOR_DIGITAL_PIN); if (SLEEP_TIME <= dht.getMinimumSamplingPeriod()) { Serial.println("Warning: UPDATE_INTERVAL is smaller than supported by the sensor!"); } // Sleep for the time of the minimum sampling period to give the sensor time to power up // (otherwise, timeout errors might occure for the first reading) sleep(dht.getMinimumSamplingPeriod()); // metric = getConfig().isMetric; pinMode(DIGITAL_INPUT_SENSOR, INPUT); // sets the motion sensor digital pin as input delay(100); send(msgTemp.set("0")); delay(100); send(msgHum.set("0")); delay(100); send(msgMot.set("0")); } void loop() { debouncer2.update(); // Get the update value int value2 = debouncer2.read(); if (value2 != oldValue2) { // Send in the new value send(msgSW.set(value2==HIGH ? 1 : 0)); oldValue2 = value2; } { if (!initialValueSent) { Serial.println("Sending initial value"); send(msg.set(state?RELAY_ON:RELAY_OFF)); Serial.println("Requesting initial value from controller"); request(CHILD_ID_REL, V_STATUS); wait(2000, C_SET, V_STATUS); } if (debouncer.update()) { if (debouncer.read()==LOW) { state = !state; // Send new state and request ack back send(msg.set(state?RELAY_ON:RELAY_OFF), true); } } // Read digital motion value boolean tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH; Serial.println(tripped); send(msgMot.set(tripped?"1":"0")); // Send tripped value to gw delay(dht.getMinimumSamplingPeriod()); // Fetch temperatures from DHT sensor float temperature = dht.getTemperature(); if (isnan(temperature)) { Serial.println("Failed reading temperature from DHT"); } else if (temperature != lastTemp) { lastTemp = temperature; if (!metric) { temperature = dht.toFahrenheit(temperature); } send(msgTemp.set(temperature, 1)); #ifdef MY_DEBUG Serial.print("T: "); Serial.println(temperature); #endif } // Fetch humidity from DHT sensor float humidity = dht.getHumidity(); if (isnan(humidity)) { Serial.println("Failed reading humidity from DHT"); } else if (humidity != lastHum) { lastHum = humidity; send(msgHum.set(humidity, 1)); #ifdef MY_DEBUG Serial.print("H: "); Serial.println(humidity); #endif } sleep(INTERRUPT,CHANGE, SLEEP_TIME); //sleep a bit } } void receive(const MyMessage &message) { if (message.isAck()) { Serial.println("This is an ack from gateway"); } if (message.type == V_STATUS) { if (!initialValueSent) { Serial.println("Receiving initial value from controller"); initialValueSent = true; } // Change relay state state = (bool)message.getInt(); digitalWrite(RELAY_PIN, state?RELAY_ON:RELAY_OFF); digitalWrite( RELAY_PIN, RELAY_ON ); //Keep the relay on for the amount of time defined by TOGGLE_INTERVAL delay( TOGGLE_INTERVAL ); digitalWrite( RELAY_PIN, RELAY_OFF ); //Added this to tell the controller that we shut off the relay // Store state in eeprom saveState(message.sensor, message.getBool()); send(msg.set(state?RELAY_ON:RELAY_OFF)); } }
-
RE: Mysensors 2.0 + Relay, DHT, and PIR - No Relay
Hello @Nuubi Yes I believe that is exactly why the Relay goes unresponsive. If I remove that sleep block, the PIR floods the gateway, and I am not sure how to get around it? Is there any possible recommendations you could make to the code so that the DHT, PIR AND Relay all work without the PIR flooding the gateway?
Thanks very much!
-
Mysensors 2.0 + Relay, DHT, and PIR - No Relay
Hello folks:
I'm trying to put together a powered multi sensor using mysensors 2, that will have a DHT, PIR, and a relay to act as a quick trigger for the garage. ( momentary push ), but I can't seem to get the relay to trigger with the following sketch:
/** DHT-Motion, MySensors 2.0.0, motion sensor pin 3, DHT pin 7 */ // Enable debug prints #define MY_DEBUG #define MY_NODE_ID 50 // My Node ID variable // Enable and select radio type attached #define MY_RADIO_NRF24 //#define MY_RADIO_RFM69 //#define MY_RS485 #include <SPI.h> #include <MySensors.h> #include <DHT.h> // Set this to the pin you connected the DHT's data pin to #define DHT_DATA_PIN 7 #define DIGITAL_INPUT_SENSOR 3 // The digital input you attached your motion sensor. (Only 2 and 3 generates interrupt!) // Set this offset if the sensor has a permanent small offset to the real temperatures #define SENSOR_TEMP_OFFSET -1 // Sleep time between sensor updates (in milliseconds) // Must be >1000ms for DHT22 and >2000ms for DHT11 static const uint64_t UPDATE_INTERVAL = 60000; // Force sending an update of the temperature after n sensor reads, so a controller showing the // timestamp of the last update doesn't show something like 3 hours in the unlikely case, that // the value didn't change since; // i.e. the sensor would force sending an update every UPDATE_INTERVAL*FORCE_UPDATE_N_READS [ms] static const uint8_t FORCE_UPDATE_N_READS = 10; #define CHILD_ID_MO 3 #define CHILD_ID_HUM 10 #define CHILD_ID_TEMP 11 #define RELAY_1 4 // 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 CHILD_ID_OPENER 0 #define CHILD_ID_STATUS 1 #define TOGGLE_INTERVAL 350 //Tells how many milliseconds the relay will be held closed #define CLOSED 0 #define OPEN 1 DHT dht; float lastTemp; float lastHum; uint8_t nNoUpdatesTemp; uint8_t nNoUpdatesHum; bool metric = true; MyMessage msgMot(CHILD_ID_MO, V_TRIPPED); MyMessage msgHum(CHILD_ID_HUM, V_HUM); MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP); MyMessage msgOpener(CHILD_ID_OPENER, V_STATUS); MyMessage msgStatus(CHILD_ID_STATUS, V_TEXT); void presentation() { // Send the sketch version information to the gateway sendSketchInfo("DHT-Motion_Relay", "1.1"); // Register all sensors to gw (they will be created as child devices) present(CHILD_ID_MO, S_MOTION); wait(30); present(CHILD_ID_HUM, S_HUM); wait(30); present(CHILD_ID_TEMP, S_TEMP); wait(30); sendHeartbeat(); wait(30); present(CHILD_ID_OPENER, S_BINARY); wait(30); present(CHILD_ID_STATUS, S_INFO); wait(30); } void setup() { pinMode(DIGITAL_INPUT_SENSOR, INPUT); // sets the motion sensor digital pin as input dht.setup(DHT_DATA_PIN); // set data pin of DHT sensor if (UPDATE_INTERVAL <= dht.getMinimumSamplingPeriod()) { Serial.println("Warning: UPDATE_INTERVAL is smaller than supported by the sensor!"); } // Sleep for the time of the minimum sampling period to give the sensor time to power up // (otherwise, timeout errors might occure for the first reading) sleep(dht.getMinimumSamplingPeriod()); pinMode(RELAY_1, OUTPUT); digitalWrite(RELAY_1, loadState(RELAY_1)?RELAY_OFF:RELAY_ON); } void loop() { // Force reading sensor, so it works also after sleep() dht.readSensor(true); // Get temperature from DHT library float temperature = dht.getTemperature(); if (isnan(temperature)) { Serial.println("Failed reading temperature from DHT!"); } else if (temperature != lastTemp || nNoUpdatesTemp == FORCE_UPDATE_N_READS) { // Only send temperature if it changed since the last measurement or if we didn't send an update for n times lastTemp = temperature; if (!metric) { temperature = dht.toFahrenheit(temperature); } // Reset no updates counter nNoUpdatesTemp = 0; temperature += SENSOR_TEMP_OFFSET; send(msgTemp.set(temperature, 1)); wait(50); #ifdef MY_DEBUG Serial.print("T: "); Serial.println(temperature); #endif } else { // Increase no update counter if the temperature stayed the same nNoUpdatesTemp++; } // Get humidity from DHT library float humidity = dht.getHumidity(); if (isnan(humidity)) { Serial.println("Failed reading humidity from DHT"); } else if (humidity != lastHum || nNoUpdatesHum == FORCE_UPDATE_N_READS) { // Only send humidity if it changed since the last measurement or if we didn't send an update for n times lastHum = humidity; // Reset no updates counter nNoUpdatesHum = 0; send(msgHum.set(humidity, 1)); wait(50); #ifdef MY_DEBUG Serial.print("H: "); Serial.println(humidity); #endif } else { // Increase no update counter if the humidity stayed the same nNoUpdatesHum++; } // Read digital motion value bool tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH; Serial.println(tripped); send(msgMot.set(tripped?"1":"0")); // Send tripped value to gw wait(300); // Sleep for a while to save energy sleep(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR), CHANGE, UPDATE_INTERVAL); } void receive(const MyMessage &message) { // We only expect one type of message from controller. But we better check anyway. if (message.type==V_LIGHT) { // Change relay state digitalWrite(message.sensor-1+RELAY_1, message.getBool()?RELAY_ON:RELAY_OFF); digitalWrite( RELAY_1, RELAY_ON ); //Keep the relay on for the amount of time defined by TOGGLE_INTERVAL delay( TOGGLE_INTERVAL ); digitalWrite( RELAY_1, RELAY_OFF ); //Added this to tell the controller that we shut off the relay // 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()); } }
Can anyone help with where I have gone wrong? Board, NRF, etc all work with the default relay sketch, but when I am combining, I am not having any luck with the relay, everything else appears fine based on serial output:
Starting sensor (RNNNA-, 2.0.0) TSM:INIT TSM:RADIO:OK TSP:ASSIGNID:OK (ID=50) TSM:FPAR TSP:MSG:SEND 50-50-255-255 s=255,c=3,t=7,pt=0,l=0,sg=0,ft=0,st=bc: TSP:MSG:READ 0-0-50 s=255,c=3,t=8,pt=1,l=1,sg=0:0 TSP:MSG:FPAR RES (ID=0, dist=0) TSP:MSG:PAR OK (ID=0, dist=1) TSM:FPAR:OK TSM:ID TSM:CHKID:OK (ID=50) TSM:UPL TSP:PING:SEND (dest=0) TSP:MSG:SEND 50-50-0-0 s=255,c=3,t=24,pt=1,l=1,sg=0,ft=0,st=ok:1 TSP:MSG:READ 0-0-50 s=255,c=3,t=25,pt=1,l=1,sg=0:1 TSP:MSG:PONG RECV (hops=1) TSP:CHKUPL:OK TSM:UPL:OK TSM:READY TSP:MSG:SEND 50-50-0-0 s=255,c=3,t=15,pt=6,l=2,sg=0,ft=0,st=ok:0100 !TSP:MSG:SEND 50-50-0-0 s=255,c=0,t=17,pt=0,l=5,sg=0,ft=0,st=fail:2.0.0 TSP:MSG:SEND 50-50-0-0 s=255,c=3,t=6,pt=1,l=1,sg=0,ft=1,st=ok:0 TSP:MSG:SEND 50-50-0-0 s=255,c=3,t=11,pt=0,l=16,sg=0,ft=0,st=ok:DHT-Motion_Relay TSP:MSG:SEND 50-50-0-0 s=255,c=3,t=12,pt=0,l=3,sg=0,ft=0,st=ok:1.1 TSP:MSG:SEND 50-50-0-0 s=3,c=0,t=1,pt=0,l=0,sg=0,ft=0,st=ok: TSP:MSG:SEND 50-50-0-0 s=10,c=0,t=7,pt=0,l=0,sg=0,ft=0,st=ok: TSP:MSG:SEND 50-50-0-0 s=11,c=0,t=6,pt=0,l=0,sg=0,ft=0,st=ok: TSP:MSG:SEND 50-50-0-0 s=255,c=3,t=22,pt=5,l=4,sg=0,ft=0,st=ok:2197 TSP:MSG:SEND 50-50-0-0 s=0,c=0,t=3,pt=0,l=0,sg=0,ft=0,st=ok: TSP:MSG:READ 0-0-50 s=255,c=3,t=6,pt=0,l=1,sg=0:M TSP:MSG:SEND 50-50-0-0 s=1,c=0,t=36,pt=0,l=0,sg=0,ft=0,st=ok: Request registration... TSP:MSG:SEND 50-50-0-0 s=255,c=3,t=26,pt=1,l=1,sg=0,ft=0,st=ok:2 TSP:MSG:READ 0-0-50 s=255,c=3,t=27,pt=1,l=1,sg=0:1 Node registration=1 Init complete, id=50, parent=0, distance=1, registration=1 TSP:MSG:SEND 50-50-0-0 s=11,c=1,t=0,pt=7,l=5,sg=0,ft=0,st=ok:20.0 T: 20.00 TSP:MSG:SEND 50-50-0-0 s=10,c=1,t=1,pt=7,l=5,sg=0,ft=0,st=ok:23.0 H: 23.00 0 TSP:MSG:SEND 50-50-0-0 s=3,c=1,t=16,pt=0,l=1,sg=0,ft=0,st=ok:0
-
RE: 3 in 1 incl battery monitor
Hey @carlierd Just curious if you are still using a DHT22 with your sketch? Have you modified the code much from the above? I am looking at implementing something similiar ( identical actually ) and was wondering if much has changed for you over the last few months?
Thanks!
-
RE: Help with PIR and Water Sensor or Nano - Water Sensor won't trigger
Got it working with this sleep function properly:
// Sleep until interrupt comes in on motion or water sensor. Send update every two minute. gw.sleep(DIGITAL_INPUT_SENSOR - 2, CHANGE, DIGITAL_INPUT_WATER_SENSOR - 2, CHANGE, SLEEP_TIME);