gw.sleep on battery powered magnet door switch
-
@AWI Thanks. By the way would you care to explain the interrupt index number? or may be a link for explanation?
@Chakkie In a few words.. The ATMEGA has two external interrupts 0 and 1 which are connected to pins 2 and 3. ("-2" translates the pin number to the interrupt number, which is rather confusing as @mfalkvidd meant)
-
We should really get rid of the confusing "- 2" stuff in the examples and start using DigtalPinToInterrupt instead.
I'm annoyed enough to see if I can create a pull request later this week.@mfalkvidd Thanks for the info. Does DigitalPinTolnterrupt works better?
-
@Chakkie In a few words.. The ATMEGA has two external interrupts 0 and 1 which are connected to pins 2 and 3. ("-2" translates the pin number to the interrupt number, which is rather confusing as @mfalkvidd meant)
-
@AWI Thanks this clear thinks up but at the same time also confusing too.
So "-2" activates both 0 and 1 on pin 2 or pin 3 as you mentioned earlier. I always though it represents a pin number.
-
@Chakkie The function
digitalPinToInterrupt(pin)translates the pin number to the attached interrupt like "-2" does but in a reliable and more understandable way. -
I would like to build the same but I am still very confused now. Could you upload some pictures so I can make myself an image of how you wirde things together?
Also I don´t really understand what happens here: gw.sleep(BUTTON_PIN_Deur - 2, CHANGE, BUTTON_PIN_Post - 2, CHANGE, 86400000);
-
I would like to build the same but I am still very confused now. Could you upload some pictures so I can make myself an image of how you wirde things together?
Also I don´t really understand what happens here: gw.sleep(BUTTON_PIN_Deur - 2, CHANGE, BUTTON_PIN_Post - 2, CHANGE, 86400000);
@siod If you are using a "standard" Atmega328 (pro-mini, etc.) don't make it hard for yourself. This processor has two external interrupts (0 & 1) connected to pins 2 & 3. Taking your line of code
gw.sleep(BUTTON_PIN_Deur - 2, CHANGE, BUTTON_PIN_Post - 2, CHANGE, 86400000);the arguments are respectively:- Use interrupt "0" (connected to pin 2 is BUTTON_PIN_Deur)
- Have is fired on change (i.e Rising and Falling)
- Use interrupt "1" (connected to pin 3 is BUTTON_PIN_Post)
- Have is fired on change (i.e Rising and Falling)
- Wake after every 86400000 ms (24 hrs) if no interrupt fired. To be safe you should use 86400000UL (the UL indicating that it is an Unsigned long type)
-
@siod If you are using a "standard" Atmega328 (pro-mini, etc.) don't make it hard for yourself. This processor has two external interrupts (0 & 1) connected to pins 2 & 3. Taking your line of code
gw.sleep(BUTTON_PIN_Deur - 2, CHANGE, BUTTON_PIN_Post - 2, CHANGE, 86400000);the arguments are respectively:- Use interrupt "0" (connected to pin 2 is BUTTON_PIN_Deur)
- Have is fired on change (i.e Rising and Falling)
- Use interrupt "1" (connected to pin 3 is BUTTON_PIN_Post)
- Have is fired on change (i.e Rising and Falling)
- Wake after every 86400000 ms (24 hrs) if no interrupt fired. To be safe you should use 86400000UL (the UL indicating that it is an Unsigned long type)
-
@AWI
Ok thx for explanation, but that means he is using 2 reed switches, right (interrupt at pin2 and int pin3)?@siod I guess so. But don't ask me why. One should be sufficient to detect if the door is open :smile:
In addition (and for what it is worth). If you use a real low power circuit you can save around a factor 3 on battery lifetime when you get rid of the timed wakeup. The arduino sleeps a lot better when it doesn't have to look at the alarm clock every few ms :zzz:
-
@siod I guess so. But don't ask me why. One should be sufficient to detect if the door is open :smile:
In addition (and for what it is worth). If you use a real low power circuit you can save around a factor 3 on battery lifetime when you get rid of the timed wakeup. The arduino sleeps a lot better when it doesn't have to look at the alarm clock every few ms :zzz:
-
@AWI
yes, makes sense, but how should you do this wihout the wakeup ? I guess this is just the disadvantage one must accept...@siod The wakeup function can be disabled by setting the timer values to 0 (or omitting it). There is no purpose in the sketch above for what I can see. If you want to have a kind of "hey I am still alive"/heartbeat feature you need to do a little more (e.g. sending battery level)
-
@siod The wakeup function can be disabled by setting the timer values to 0 (or omitting it). There is no purpose in the sketch above for what I can see. If you want to have a kind of "hey I am still alive"/heartbeat feature you need to do a little more (e.g. sending battery level)
@AWI I was going to ask about that.. I dont see any reason to wake up every 24 hours just to go back to sleep again.. I assume the radio doesn't have any reason to send a keepalive or anything? So, you can omit that number, and it will sleep until interrupted? That's cool..
-Steve
-
@AWI I was going to ask about that.. I dont see any reason to wake up every 24 hours just to go back to sleep again.. I assume the radio doesn't have any reason to send a keepalive or anything? So, you can omit that number, and it will sleep until interrupted? That's cool..
-Steve
-
@siod I guess so. But don't ask me why. One should be sufficient to detect if the door is open :smile:
In addition (and for what it is worth). If you use a real low power circuit you can save around a factor 3 on battery lifetime when you get rid of the timed wakeup. The arduino sleeps a lot better when it doesn't have to look at the alarm clock every few ms :zzz:
-
well, as you can see, if you don´t know the libraries exactly you accept things as they are or as they seem to be. I wasn´t aware that you can just set the wakeup function to 0. So this said I would like to thank you @AWI for your patience and your willingness of explaining also the most obvious things! :thumbsup:
-
The sketch works with both reeds switches (2 windows) but how to integreate it with DS18B20 temp sensor? I also power it with battery, so I would like to check the temp eg every 5min and if it is changed then send the new value to the controler. How to wake up arduino only if any window is opened or temp is changed (after 5 min)
Thanks
treb0r -
The sketch works with both reeds switches (2 windows) but how to integreate it with DS18B20 temp sensor? I also power it with battery, so I would like to check the temp eg every 5min and if it is changed then send the new value to the controler. How to wake up arduino only if any window is opened or temp is changed (after 5 min)
Thanks
treb0r@treb0r You can either wake up on the interrupt or on a time period:
bool sleep(int interrupt, int mode, unsigned long ms=0);
interrupt - Interrupt that should trigger the wakeup.
mode - RISING, FALLING, CHANGE
ms - Number of milliseconds to sleep (or 0 to sleep forever).The sleep method returns true if wake up was triggered by pin change and false means timer woke it up.
-
The sketch works with both reeds switches (2 windows) but how to integreate it with DS18B20 temp sensor? I also power it with battery, so I would like to check the temp eg every 5min and if it is changed then send the new value to the controler. How to wake up arduino only if any window is opened or temp is changed (after 5 min)
Thanks
treb0r@treb0r the problem is, you need to wake up the arduino to tell the temp sensor to take a new reading, so the best you can do is to trigger on the interrupts for the Windows and then use the timer to wake up and take the temperature reading, and then you'll have to compare to your saved value to decide whether it has been 5 degrees or not, so you can't completely sleep until that happens..
-
Hi guys,
unfortunately I have to answer again to this topic because I don´t get my nodes work longer then up to two weeks. I guess it is still a sleep function problem and the problem persits though I am usin ver 2.0 now. Please have a look at my code, any hint is very appreciated!!
I have attached 2 reed switches which should trigger a wakeup and one Hum/Temp Sensor is attached, too. I would like the device to send temp/hum measurements every 15 minutes, what works, but only for a few days or so. Then I also send battery level, that´s all.
I have 3 devices up and running right now, they all fail once in while...
// Sensor Node Schlafzimmer mit HTU21D Temp/Hum Sensor, Fensterkontakte an Interrupt PINS Digital 5&6. Sleep Time 15 Minutwn, wake up wenn Fenster geöffnet/geschlossen wird. #define MY_RADIO_NRF24 //MySensor Library auf NRF24 Funkmodul einstellen, muss vor MySensor.h Initialisierung geschehen // Define Node ID #define MY_NODE_ID 200 //Batterysensor int BATTERY_SENSE_PIN = A0; // select the input pin for the battery sense point int oldBatteryPcnt = 0; #define CHILD_ID_BATT 7 //Kontaktschalter //#include <Bounce2.h> #define CHILD1_ID 1 // Kontaktschalter 1 #define CHILD2_ID 2 // Kontaktschalter 2 #define BUTTON1_PIN 2 // Kontaktschalter 1 #define BUTTON2_PIN 3 // Kontaktschalter 2 int oldValueReed1=-1; int oldValueReed2=-1; //Tempsensor #include <SparkFunHTU21D.h> #include <Wire.h> #define CHILD_ID_HUM 3 #define CHILD_ID_TEMP 4 unsigned long SLEEP_TIME = 900000; // Sleep time between reads (in milliseconds) #include <MySensors.h> #include <SPI.h> //tempsensor HTU21D myHumidity; float lastTemp; float lastHum; //boolean metric = true; //Messages //Battery MyMessage msgbatt(CHILD_ID_BATT,V_VOLTAGE); // Kontaktschalter MyMessage msgReed1(CHILD1_ID,V_TRIPPED); // Kontaktschalter 1 MyMessage msgReed2(CHILD2_ID,V_TRIPPED); // Kontaktschalter 2 //TempMessage MyMessage msgHum(CHILD_ID_HUM, V_HUM); MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP); //Presentation; present sensors to gateway! void presentation(){ // Send the sketch version information to the gateway and Controller sendSketchInfo("Schlafzimmer Messstation", "2.0"); // Register binary input sensor to gw (they will be created as child devices) // You can use S_DOOR, S_MOTION or S_LIGHT here depending on your usage. // If S_LIGHT is used, remember to update variable type you send in. See "msg" above. present(CHILD1_ID, S_DOOR); present(CHILD2_ID, S_DOOR); //Tempsensor present(CHILD_ID_HUM, S_HUM); present(CHILD_ID_TEMP, S_TEMP); //metric = getConfig().isMetric; //Battery present(CHILD_ID_BATT,V_VOLTAGE); } //Setup void setup() { //Serial.begin(9600); Serial.println("Hello!"); //Batterysensor // use the 1.1 V internal reference #if defined(__AVR_ATmega2560__) analogReference(INTERNAL1V1); #else analogReference(INTERNAL); #endif //Tempsensor Serial.println("Setting up TempSensor..."); myHumidity.begin(); Serial.println("...done!"); // Setup Kontaktschalter 1 pinMode(BUTTON1_PIN,INPUT); // Activate internal pull-up digitalWrite(BUTTON1_PIN,HIGH); // Setup Kontaktschalter 2 pinMode(BUTTON2_PIN,INPUT); // Activate internal pull-up digitalWrite(BUTTON2_PIN,HIGH); } //Starte den Loop void loop() { //Batterysensor // get the battery Voltage delay(1000); int sensorValue = analogRead(BATTERY_SENSE_PIN); #ifdef DEBUG #endif // 1M, 470K divider across battery and using internal ADC ref of 1.1V // Sense point is bypassed with 0.1 uF cap to reduce noise at that point // ((1e6+470e3)/470e3)*1.1 = Vmax = 3.44 Volts // 3.44/1023 = Volts per bit = 0.003363075 float batteryV = sensorValue * 0.003363075; int batteryPcnt = sensorValue / 10; #ifdef DEBUG Serial.print("Battery Voltage: "); Serial.print(batteryV); Serial.println(" V"); Serial.print("Battery percent: "); Serial.print(batteryPcnt); Serial.println(" %"); #endif if (oldBatteryPcnt != batteryPcnt) { // Power up radio after sleep sendBatteryLevel(batteryPcnt); send(msgbatt.set(batteryPcnt)); oldBatteryPcnt = batteryPcnt; } //Kontakstschalter 1 // Short delay to allow buttons to properly settle sleep(10); // Get the update value int valueReed1 = digitalRead(BUTTON1_PIN); if (valueReed1 != oldValueReed1) { // Send in the new value send(msgReed1.set(valueReed1==HIGH ? 1 : 0)); Serial.println("Button 1 geschaltet"); oldValueReed1 = valueReed1; } //Kontakstschalter 2 // Get the update value int valueReed2 = digitalRead(BUTTON2_PIN); if (valueReed2 != oldValueReed2) { // Send in the new value send(msgReed2.set(valueReed2==HIGH ? 1 : 0)); Serial.println("Button 2 geschaltet"); oldValueReed2 = valueReed2; } //Tempsensor Serial.println("Starte Messung..."); float temp = myHumidity.readTemperature(); if (isnan(temp)) { Serial.println("Failed reading temperature from DHT"); } else if (temp != lastTemp) { lastTemp = temp; send(msgTemp.set(temp, 1)); Serial.print("T: "); Serial.println(temp); } float humd = myHumidity.readHumidity(); if (isnan(humd)) { Serial.println("Failed reading humidity from DHT"); } else if (humd != lastHum) { lastHum = humd; send(msgHum.set(humd, 1)); Serial.print("H: "); Serial.println(humd); } Serial.println("Sleep..."); sleep(BUTTON1_PIN - 2, CHANGE, BUTTON2_PIN - 2, CHANGE, SLEEP_TIME); //sleep a bit }