Humidity+Relay with button node
-
Thee sketch i used is:
#include <SPI.h> #include <MySensor.h> #include <DHT.h> #include <Bounce2.h> #include <MySigningNone.h> #include <MyTransportNRF24.h> #include <MyTransportRFM69.h> #include <MyHwATMega328.h> #define NODE_ID 1 #define CHILD_ID_HUM 0 #define CHILD_ID_TEMP 1 #define CHILD_ID_RELAY 2 #define RELAY_PIN 3 #define BUTTON_PIN 4 #define HUMIDITY_SENSOR_DIGITAL_PIN 2 //unsigned long SLEEP_TIME = 30000; // Sleep time between reads (in milliseconds) #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 MyTransportNRF24 radio(RF24_CE_PIN, RF24_CS_PIN, RF24_PA_LEVEL_GW); MyHwATMega328 hw; MySensor gw(radio, hw); Bounce debouncer = Bounce(); int oldValue=0; bool state; MyMessage msg(CHILD_ID_RELAY,V_LIGHT); DHT dht; float lastTemp; float lastHum; boolean metric = true; MyMessage msgHum(CHILD_ID_HUM, V_HUM); MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP); void setup() { gw.begin(incomingMessage, AUTO, true); dht.setup(HUMIDITY_SENSOR_DIGITAL_PIN); gw.sendSketchInfo("Combo", "1.0"); gw.present(CHILD_ID_HUM, S_HUM); gw.present(CHILD_ID_TEMP, S_TEMP); pinMode(BUTTON_PIN,INPUT); digitalWrite(BUTTON_PIN,HIGH); debouncer.attach(BUTTON_PIN); debouncer.interval(5); gw.present(CHILD_ID_RELAY, S_LIGHT); metric = gw.getConfig().isMetric; digitalWrite(RELAY_PIN, RELAY_OFF); pinMode(RELAY_PIN, OUTPUT); state = gw.loadState(CHILD_ID_RELAY); digitalWrite(RELAY_PIN, state?RELAY_ON:RELAY_OFF); } void loop() { gw.process(); debouncer.update(); int value = debouncer.read(); if (value != oldValue && value==0) { gw.send(msg.set(state?false:true), true); // Send new state and request ack back } oldValue = value; delay(dht.getMinimumSamplingPeriod()); 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); } gw.send(msgTemp.set(temperature, 1)); Serial.print("T: "); Serial.println(temperature); } float humidity = dht.getHumidity(); if (isnan(humidity)) { Serial.println("Failed reading humidity from DHT"); } else if (humidity != lastHum) { lastHum = humidity; gw.send(msgHum.set(humidity, 1)); Serial.print("H: "); Serial.println(humidity); } } void incomingMessage(const MyMessage &message) { if (message.type == V_LIGHT) { digitalWrite(RELAY_PIN, message.getBool() ? RELAY_ON : RELAY_OFF); gw.saveState(1, message.getBool()); Serial.print("Incoming change for sensor:"); Serial.print(message.sensor); Serial.print(", New status: "); Serial.println(message.getBool()); } }With this sketch i can control the relay with domoticz, but i can only activate the relay, not deactivate.
I connected the button to GND pin and PIN4 on the Arduino. -
Hi,
i started playing with Mysensors and Arduino and managed to make a Gateway and the relay/humidity node with the following code:#include <SPI.h> #include <MySensor.h> #include <DHT.h> #include <MySigningNone.h> #include <MyTransportNRF24.h> #include <MyTransportRFM69.h> #include <MyHwATMega328.h> #define NODE_ID 1 #define CHILD_ID_HUM 0 #define CHILD_ID_TEMP 1 #define CHILD_ID_RELAY 2 #define RELAY_PIN 3 #define HUMIDITY_SENSOR_DIGITAL_PIN 2 //unsigned long SLEEP_TIME = 30000; // Sleep time between reads (in milliseconds) #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 MyTransportNRF24 radio(RF24_CE_PIN, RF24_CS_PIN, RF24_PA_LEVEL_GW); MyHwATMega328 hw; MySensor gw(radio, hw); DHT dht; float lastTemp; float lastHum; boolean metric = true; MyMessage msgHum(CHILD_ID_HUM, V_HUM); MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP); void setup() { gw.begin(incomingMessage, AUTO, true); dht.setup(HUMIDITY_SENSOR_DIGITAL_PIN); gw.sendSketchInfo("Combo", "1.0"); gw.present(CHILD_ID_HUM, S_HUM); gw.present(CHILD_ID_TEMP, S_TEMP); gw.present(CHILD_ID_RELAY, S_LIGHT); metric = gw.getConfig().isMetric; pinMode(RELAY_PIN, OUTPUT); digitalWrite(RELAY_PIN, gw.loadState(1) ? RELAY_ON : RELAY_OFF); } void loop() { gw.process(); delay(dht.getMinimumSamplingPeriod()); 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); } gw.send(msgTemp.set(temperature, 1)); Serial.print("T: "); Serial.println(temperature); } float humidity = dht.getHumidity(); if (isnan(humidity)) { Serial.println("Failed reading humidity from DHT"); } else if (humidity != lastHum) { lastHum = humidity; gw.send(msgHum.set(humidity, 1)); Serial.print("H: "); Serial.println(humidity); } } void incomingMessage(const MyMessage &message) { if (message.type == V_LIGHT) { digitalWrite(RELAY_PIN, message.getBool() ? RELAY_ON : RELAY_OFF); gw.saveState(1, message.getBool()); Serial.print("Incoming change for sensor:"); Serial.print(message.sensor); Serial.print(", New status: "); Serial.println(message.getBool()); } }Since this is copy/pasted from the forum, i am wondering if it is possible to incorporate a hardware button to control the relay. I tried adding code from the Relay with actuator example, but i failed to make it work, i can only turn the relay on with the button. I am using Domoticz as a controller. Any help would be welcome.
@thecko Great to hear that you've got it working. The answer to your question is: Yet that's possible.
What you need for it?
- Include Bounce2.h
- declare a bounce object in your setup
- do the following in your loop()
a. read the debounced value of your switch
b. if value changes, than invert current relay value
With the Bounce library comes an Update-example which shows how you can do the above pseudo code.
Hope it helps you.
-
@thecko said:
The problem is in the "state" variable, you use the state variable to toggle but never save changed value
so change this code snippet
debouncer.update(); int value = debouncer.read(); if (value != oldValue && value==0) { gw.send(msg.set(state?false:true), true); // Send new state and request ack back } oldValue = value;to
debouncer.update(); int value = debouncer.read(); if (value != oldValue && value==0) { gw.send(msg.set(gw.loadState(1)?false:true), true); // Send new state and request ack back } oldValue = value;and remove the state variable at all.
Even better also remove the "oldValue" and "value" variables (the bounce2 library keeps the old value for you and debouncer.update(); returns true when the value was toggled )
if (debouncer.update() && debouncer.read() == 0) { gw.send(msg.set(gw.loadState(1)?false:true), true); // Send new state and request ack back } -
Hi, thank you for the suggestions, its working now!
The final code looks like this:#include <SPI.h> #include <MySensor.h> #include <DHT.h> #include <Bounce2.h> #include <MySigningNone.h> #include <MyTransportNRF24.h> #include <MyTransportRFM69.h> #include <MyHwATMega328.h> #define NODE_ID 1 #define CHILD_ID_HUM 0 #define CHILD_ID_TEMP 1 #define CHILD_ID_RELAY 2 #define RELAY_PIN 3 #define BUTTON_PIN 4 #define HUMIDITY_SENSOR_DIGITAL_PIN 2 //unsigned long SLEEP_TIME = 30000; // Sleep time between reads (in milliseconds) #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 MyTransportNRF24 radio(RF24_CE_PIN, RF24_CS_PIN, RF24_PA_LEVEL_GW); MyHwATMega328 hw; MySensor gw(radio, hw); Bounce debouncer = Bounce(); int oldValue=0; bool state; MyMessage msg(CHILD_ID_RELAY,V_LIGHT); DHT dht; float lastTemp; float lastHum; boolean metric = true; MyMessage msgHum(CHILD_ID_HUM, V_HUM); MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP); void setup() { gw.begin(incomingMessage, AUTO, true); dht.setup(HUMIDITY_SENSOR_DIGITAL_PIN); gw.sendSketchInfo("Combo", "1.0"); gw.present(CHILD_ID_HUM, S_HUM); gw.present(CHILD_ID_TEMP, S_TEMP); pinMode(BUTTON_PIN,INPUT); digitalWrite(BUTTON_PIN,HIGH); debouncer.attach(BUTTON_PIN); debouncer.interval(5); gw.present(CHILD_ID_RELAY, S_LIGHT); metric = gw.getConfig().isMetric; digitalWrite(RELAY_PIN, RELAY_OFF); pinMode(RELAY_PIN, OUTPUT); state = gw.loadState(CHILD_ID_RELAY); digitalWrite(RELAY_PIN, state?RELAY_ON:RELAY_OFF); } void loop() { gw.process(); debouncer.update(); int value = debouncer.read(); if (value != oldValue && value==0) { gw.send(msg.set(gw.loadState(1)?false:true), true); // Send new state and request ack back } oldValue = value; delay(dht.getMinimumSamplingPeriod()); 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); } gw.send(msgTemp.set(temperature, 1)); Serial.print("T: "); Serial.println(temperature); } float humidity = dht.getHumidity(); if (isnan(humidity)) { Serial.println("Failed reading humidity from DHT"); } else if (humidity != lastHum) { lastHum = humidity; gw.send(msgHum.set(humidity, 1)); Serial.print("H: "); Serial.println(humidity); } } void incomingMessage(const MyMessage &message) { if (message.type == V_LIGHT) { digitalWrite(RELAY_PIN, message.getBool() ? RELAY_ON : RELAY_OFF); gw.saveState(1, message.getBool()); Serial.print("Incoming change for sensor:"); Serial.print(message.sensor); Serial.print(", New status: "); Serial.println(message.getBool()); } }The only thing that remains is that the button needs to be pressed for about 2 secs to actuate. When measured with a multimeter, it takes about 2 secs to get from 1 to 0. Tried inserting a 4.7k resistor between PIN4 and the button, but still 2 sec for the button to actuate.
-
Hi, thank you for the suggestions, its working now!
The final code looks like this:#include <SPI.h> #include <MySensor.h> #include <DHT.h> #include <Bounce2.h> #include <MySigningNone.h> #include <MyTransportNRF24.h> #include <MyTransportRFM69.h> #include <MyHwATMega328.h> #define NODE_ID 1 #define CHILD_ID_HUM 0 #define CHILD_ID_TEMP 1 #define CHILD_ID_RELAY 2 #define RELAY_PIN 3 #define BUTTON_PIN 4 #define HUMIDITY_SENSOR_DIGITAL_PIN 2 //unsigned long SLEEP_TIME = 30000; // Sleep time between reads (in milliseconds) #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 MyTransportNRF24 radio(RF24_CE_PIN, RF24_CS_PIN, RF24_PA_LEVEL_GW); MyHwATMega328 hw; MySensor gw(radio, hw); Bounce debouncer = Bounce(); int oldValue=0; bool state; MyMessage msg(CHILD_ID_RELAY,V_LIGHT); DHT dht; float lastTemp; float lastHum; boolean metric = true; MyMessage msgHum(CHILD_ID_HUM, V_HUM); MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP); void setup() { gw.begin(incomingMessage, AUTO, true); dht.setup(HUMIDITY_SENSOR_DIGITAL_PIN); gw.sendSketchInfo("Combo", "1.0"); gw.present(CHILD_ID_HUM, S_HUM); gw.present(CHILD_ID_TEMP, S_TEMP); pinMode(BUTTON_PIN,INPUT); digitalWrite(BUTTON_PIN,HIGH); debouncer.attach(BUTTON_PIN); debouncer.interval(5); gw.present(CHILD_ID_RELAY, S_LIGHT); metric = gw.getConfig().isMetric; digitalWrite(RELAY_PIN, RELAY_OFF); pinMode(RELAY_PIN, OUTPUT); state = gw.loadState(CHILD_ID_RELAY); digitalWrite(RELAY_PIN, state?RELAY_ON:RELAY_OFF); } void loop() { gw.process(); debouncer.update(); int value = debouncer.read(); if (value != oldValue && value==0) { gw.send(msg.set(gw.loadState(1)?false:true), true); // Send new state and request ack back } oldValue = value; delay(dht.getMinimumSamplingPeriod()); 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); } gw.send(msgTemp.set(temperature, 1)); Serial.print("T: "); Serial.println(temperature); } float humidity = dht.getHumidity(); if (isnan(humidity)) { Serial.println("Failed reading humidity from DHT"); } else if (humidity != lastHum) { lastHum = humidity; gw.send(msgHum.set(humidity, 1)); Serial.print("H: "); Serial.println(humidity); } } void incomingMessage(const MyMessage &message) { if (message.type == V_LIGHT) { digitalWrite(RELAY_PIN, message.getBool() ? RELAY_ON : RELAY_OFF); gw.saveState(1, message.getBool()); Serial.print("Incoming change for sensor:"); Serial.print(message.sensor); Serial.print(", New status: "); Serial.println(message.getBool()); } }The only thing that remains is that the button needs to be pressed for about 2 secs to actuate. When measured with a multimeter, it takes about 2 secs to get from 1 to 0. Tried inserting a 4.7k resistor between PIN4 and the button, but still 2 sec for the button to actuate.
-
@thecko the button should connect pin D4 to ground when pressed and there should be no resistor needed since your sketch activates the internal pull up resistor with this line:
digitalWrite(BUTTON_PIN,HIGH); -
@BartE Is there any way to decrease the amount of time the button needs to be pushed ? Maybe my choice of the button is not good, will try another button when i come home?
@thecko the amount of time you have to wait is the result of this line
delay(dht.getMinimumSamplingPeriod());Your sketch has to pass 5 times time delay (set by this line debouncer.interval(5);)
before a button press is detected.
Better use a while loop without a delay some something like thisunsigned long lastCheckTimestamp = 0; // setup stuff void loop () { gw.process(); if (debouncer.update() && debouncer.read() == 0) { gw.send(msg.set(gw.loadState(1)?false:true), true); // Send new state and request ack back } // Check if the minimal sample period has been passed if ((lastCheckTimestamp < (millis() - dht.getMinimumSamplingPeriod()) ) || lastCheckTimestamp > millis()) { lastCheckTimestamp = millis(); // do the normal stuff after the delay 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); } gw.send(msgTemp.set(temperature, 1)); Serial.print("T: "); Serial.println(temperature); } float humidity = dht.getHumidity(); if (isnan(humidity)) { Serial.println("Failed reading humidity from DHT"); } else if (humidity != lastHum) { lastHum = humidity; gw.send(msgHum.set(humidity, 1)); Serial.print("H: "); Serial.println(humidity); } } } -
When i try your sketch in this format:
#include <SPI.h> #include <MySensor.h> #include <DHT.h> #include <Bounce2.h> #include <MySigningNone.h> #include <MyTransportNRF24.h> #include <MyTransportRFM69.h> #include <MyHwATMega328.h> #define NODE_ID 1 #define CHILD_ID_HUM 0 #define CHILD_ID_TEMP 1 #define CHILD_ID_RELAY 2 #define RELAY_PIN 3 #define BUTTON_PIN 4 #define HUMIDITY_SENSOR_DIGITAL_PIN 2 //unsigned long SLEEP_TIME = 30000; // Sleep time between reads (in milliseconds) #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 MyTransportNRF24 radio(RF24_CE_PIN, RF24_CS_PIN, RF24_PA_LEVEL_GW); MyHwATMega328 hw; MySensor gw(radio, hw); Bounce debouncer = Bounce(); int oldValue=0; bool state; MyMessage msg(CHILD_ID_RELAY,V_LIGHT); DHT dht; float lastTemp; float lastHum; boolean metric = true; MyMessage msgHum(CHILD_ID_HUM, V_HUM); MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP); void setup() { gw.begin(incomingMessage, AUTO, true); dht.setup(HUMIDITY_SENSOR_DIGITAL_PIN); gw.sendSketchInfo("Combo", "1.0"); gw.present(CHILD_ID_HUM, S_HUM); gw.present(CHILD_ID_TEMP, S_TEMP); pinMode(BUTTON_PIN,INPUT); digitalWrite(BUTTON_PIN,HIGH); debouncer.attach(BUTTON_PIN); debouncer.interval(5); gw.present(CHILD_ID_RELAY, S_LIGHT); metric = gw.getConfig().isMetric; digitalWrite(RELAY_PIN, RELAY_OFF); pinMode(RELAY_PIN, OUTPUT); state = gw.loadState(CHILD_ID_RELAY); digitalWrite(RELAY_PIN, state?RELAY_ON:RELAY_OFF); } unsigned long lastCheckTimestamp = 0; // setup stuff void loop() { gw.process(); if (debouncer.update() && debouncer.read() == 0) { gw.send(msg.set(gw.loadState(1)?false:true), true); // Send new state and request ack back } // Check if the minimal sample period has been passed if ((lastCheckTimestamp < (millis() - dht.getMinimumSamplingPeriod()) ) || lastCheckTimestamp > millis()) { lastCheckTimestamp = millis(); // do the normal stuff after the delay 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); } gw.send(msgTemp.set(temperature, 1)); Serial.print("T: "); Serial.println(temperature); } float humidity = dht.getHumidity(); if (isnan(humidity)) { Serial.println("Failed reading humidity from DHT"); } else if (humidity != lastHum) { lastHum = humidity; gw.send(msgHum.set(humidity, 1)); Serial.print("H: "); Serial.println(humidity); } } }Forumhlp.ino: In function 'void setup()':
Forumhlp:44: error: 'incomingMessage' was not declared in this scope
'incomingMessage' was not declared in this scopeSeems something is not right, tried deleting incomingMessage line, but no dice.
-
When i try your sketch in this format:
#include <SPI.h> #include <MySensor.h> #include <DHT.h> #include <Bounce2.h> #include <MySigningNone.h> #include <MyTransportNRF24.h> #include <MyTransportRFM69.h> #include <MyHwATMega328.h> #define NODE_ID 1 #define CHILD_ID_HUM 0 #define CHILD_ID_TEMP 1 #define CHILD_ID_RELAY 2 #define RELAY_PIN 3 #define BUTTON_PIN 4 #define HUMIDITY_SENSOR_DIGITAL_PIN 2 //unsigned long SLEEP_TIME = 30000; // Sleep time between reads (in milliseconds) #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 MyTransportNRF24 radio(RF24_CE_PIN, RF24_CS_PIN, RF24_PA_LEVEL_GW); MyHwATMega328 hw; MySensor gw(radio, hw); Bounce debouncer = Bounce(); int oldValue=0; bool state; MyMessage msg(CHILD_ID_RELAY,V_LIGHT); DHT dht; float lastTemp; float lastHum; boolean metric = true; MyMessage msgHum(CHILD_ID_HUM, V_HUM); MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP); void setup() { gw.begin(incomingMessage, AUTO, true); dht.setup(HUMIDITY_SENSOR_DIGITAL_PIN); gw.sendSketchInfo("Combo", "1.0"); gw.present(CHILD_ID_HUM, S_HUM); gw.present(CHILD_ID_TEMP, S_TEMP); pinMode(BUTTON_PIN,INPUT); digitalWrite(BUTTON_PIN,HIGH); debouncer.attach(BUTTON_PIN); debouncer.interval(5); gw.present(CHILD_ID_RELAY, S_LIGHT); metric = gw.getConfig().isMetric; digitalWrite(RELAY_PIN, RELAY_OFF); pinMode(RELAY_PIN, OUTPUT); state = gw.loadState(CHILD_ID_RELAY); digitalWrite(RELAY_PIN, state?RELAY_ON:RELAY_OFF); } unsigned long lastCheckTimestamp = 0; // setup stuff void loop() { gw.process(); if (debouncer.update() && debouncer.read() == 0) { gw.send(msg.set(gw.loadState(1)?false:true), true); // Send new state and request ack back } // Check if the minimal sample period has been passed if ((lastCheckTimestamp < (millis() - dht.getMinimumSamplingPeriod()) ) || lastCheckTimestamp > millis()) { lastCheckTimestamp = millis(); // do the normal stuff after the delay 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); } gw.send(msgTemp.set(temperature, 1)); Serial.print("T: "); Serial.println(temperature); } float humidity = dht.getHumidity(); if (isnan(humidity)) { Serial.println("Failed reading humidity from DHT"); } else if (humidity != lastHum) { lastHum = humidity; gw.send(msgHum.set(humidity, 1)); Serial.print("H: "); Serial.println(humidity); } } }Forumhlp.ino: In function 'void setup()':
Forumhlp:44: error: 'incomingMessage' was not declared in this scope
'incomingMessage' was not declared in this scopeSeems something is not right, tried deleting incomingMessage line, but no dice.
@thecko said:
You have to add you original setup and incomingMessage function, i just was explaning how to alter the loop function.void incomingMessage(const MyMessage &message) { if (message.type == V_LIGHT) { digitalWrite(RELAY_PIN, message.getBool() ? RELAY_ON : RELAY_OFF); gw.saveState(1, message.getBool()); Serial.print("Incoming change for sensor:"); Serial.print(message.sensor); Serial.print(", New status: "); Serial.println(message.getBool()); } } -
@thecko said:
You have to add you original setup and incomingMessage function, i just was explaning how to alter the loop function.void incomingMessage(const MyMessage &message) { if (message.type == V_LIGHT) { digitalWrite(RELAY_PIN, message.getBool() ? RELAY_ON : RELAY_OFF); gw.saveState(1, message.getBool()); Serial.print("Incoming change for sensor:"); Serial.print(message.sensor); Serial.print(", New status: "); Serial.println(message.getBool()); } }@BartE Adding the extra code done the job, now its working great. Thank you for your help!
The final working code if someone wonders is:
#include <SPI.h> #include <MySensor.h> #include <DHT.h> #include <Bounce2.h> #include <MySigningNone.h> #include <MyTransportNRF24.h> #include <MyTransportRFM69.h> #include <MyHwATMega328.h> #define NODE_ID 1 #define CHILD_ID_HUM 0 #define CHILD_ID_TEMP 1 #define CHILD_ID_RELAY 2 #define RELAY_PIN 3 #define BUTTON_PIN 4 #define HUMIDITY_SENSOR_DIGITAL_PIN 2 //unsigned long SLEEP_TIME = 30000; // Sleep time between reads (in milliseconds) #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 MyTransportNRF24 radio(RF24_CE_PIN, RF24_CS_PIN, RF24_PA_LEVEL_GW); MyHwATMega328 hw; MySensor gw(radio, hw); Bounce debouncer = Bounce(); int oldValue=0; bool state; MyMessage msg(CHILD_ID_RELAY,V_LIGHT); DHT dht; float lastTemp; float lastHum; boolean metric = true; MyMessage msgHum(CHILD_ID_HUM, V_HUM); MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP); void setup() { gw.begin(incomingMessage, AUTO, true); dht.setup(HUMIDITY_SENSOR_DIGITAL_PIN); gw.sendSketchInfo("Combo", "1.0"); gw.present(CHILD_ID_HUM, S_HUM); gw.present(CHILD_ID_TEMP, S_TEMP); pinMode(BUTTON_PIN,INPUT); digitalWrite(BUTTON_PIN,HIGH); debouncer.attach(BUTTON_PIN); debouncer.interval(5); gw.present(CHILD_ID_RELAY, S_LIGHT); metric = gw.getConfig().isMetric; digitalWrite(RELAY_PIN, RELAY_OFF); pinMode(RELAY_PIN, OUTPUT); state = gw.loadState(CHILD_ID_RELAY); digitalWrite(RELAY_PIN, state?RELAY_ON:RELAY_OFF); } unsigned long lastCheckTimestamp = 0; // setup stuff void incomingMessage(const MyMessage &message) { if (message.type == V_LIGHT) { digitalWrite(RELAY_PIN, message.getBool() ? RELAY_ON : RELAY_OFF); gw.saveState(1, message.getBool()); Serial.print("Incoming change for sensor:"); Serial.print(message.sensor); Serial.print(", New status: "); Serial.println(message.getBool()); } } void loop() { gw.process(); if (debouncer.update() && debouncer.read() == 0) { gw.send(msg.set(gw.loadState(1)?false:true), true); // Send new state and request ack back } // Check if the minimal sample period has been passed if ((lastCheckTimestamp < (millis() - dht.getMinimumSamplingPeriod()) ) || lastCheckTimestamp > millis()) { lastCheckTimestamp = millis(); // do the normal stuff after the delay 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); } gw.send(msgTemp.set(temperature, 1)); Serial.print("T: "); Serial.println(temperature); } float humidity = dht.getHumidity(); if (isnan(humidity)) { Serial.println("Failed reading humidity from DHT"); } else if (humidity != lastHum) { lastHum = humidity; gw.send(msgHum.set(humidity, 1)); Serial.print("H: "); Serial.println(humidity); } } }