Interrupt, Perform a specific function, not the loop
-
It's untested, but here you go. It's a modified version of the sketch by @Anticimex for a binary switch with two interrupts.
-
I tested it when I submitted it so I can vouch for the functionality. At least for the time of submission. But the library might have changed since then of course.
-
@martinhjelmare Thank you so much buddy for the help. I have not tested it yet. Can I use it with mysensors 1.4 version? Because I am using easyiot as controller and it uses 1.4 version.
-
@martinhjelmare Thank you so much buddy for the help. I have not tested it yet. Can I use it with mysensors 1.4 version? Because I am using easyiot as controller and it uses 1.4 version.
Yes, I don't see why it shouldn't work with version 1.4, but as I said, I haven't even tested this myself yet. Try it, and post back if you encounter problems. It'll be interesting to see what your final version will be.
Btw, @hek, I noticed that the API says that the sleep function with two interrupts returns a bool, but looking at github it should be int8_t, which also makes sense.
int8_t sleep(uint8_t interrupt1, uint8_t mode1, uint8_t interrupt2, uint8_t mode2, unsigned long ms=0); -
I have tried it with single interrupt and It is working good so far on my mysensors 1.4 version. In case of interrupt
wake = gw.sleep(INTERRUPT,FALLING, SLEEP_TIME);I use wake value (wake == 1) for function related to interrupt and use else condition for function related to timer wake up.
-
Here is my sketch if someone finds it useful. It uses LDR to set night mode in low light conditions and vice versa, door reed switch and PIR sensor to turn ac or dc lights with the help of two channel relay and EasyIOT as server. Interrupts perform the functions of turning lights on and off while timer wake up decides the night mode implementation. Moreover, sensor node sleeps most of its time to conserve the battery.
#include <SPI.h> #include <MySensor.h> #define CHILD_ID_LIGHT 0 #define CHILD_ID_DOOR 1 #define CHILD_ID_PIR 2 #define CHILD_ID_LED 3 #define CHILD_ID_SAVER 4 #define LDR_PIN A0 #define DOOR_PIN 2 #define PIR_PIN 3 #define LED_PIN 4 // Relay 1 is attached #define SAVER_PIN 5 // Relay 2 is attached #define INTERRUPT DOOR_PIN-2 unsigned long SLEEP_TIME = 1200000; // Sleep time 1200000 i.e. 20 minutes (in milliseconds) MySensor gw; boolean activity = false; boolean LEDSwitch = false; boolean SaverSwitch = false; boolean nightSwitch = false; MyMessage msgLDR(CHILD_ID_LIGHT, V_LIGHT_LEVEL); MyMessage msgDoor(CHILD_ID_DOOR, V_TRIPPED); MyMessage msgPir(CHILD_ID_PIR, V_TRIPPED); void setup() { gw.begin(NULL, AUTO, false, 1); gw.sendSketchInfo("BedRoom", "1.2"); pinMode(DOOR_PIN,INPUT); pinMode(PIR_PIN,INPUT); pinMode(LED_PIN, OUTPUT); pinMode(SAVER_PIN, OUTPUT); digitalWrite(DOOR_PIN, HIGH); digitalWrite(PIR_PIN, HIGH); digitalWrite(LED_PIN, HIGH); digitalWrite(SAVER_PIN, HIGH); gw.present(CHILD_ID_LIGHT, S_LIGHT_LEVEL); gw.present(CHILD_ID_DOOR, S_DOOR); gw.present(CHILD_ID_PIR, S_MOTION); int LightLevel; for(int i = millis(); i < (millis() + 5000); i++){ LightLevel = (100 - ((1023-analogRead(LDR_PIN))/10.23)); } if(LightLevel < 20){ gw.send(msgLDR.set(LightLevel)); nightSwitch = true; } else { gw.send(msgLDR.set(LightLevel)); nightSwitch = false; } } void loop() { if(nightSwitch){ //When night switch is on int wake; wake = gw.sleep(INTERRUPT,FALLING, SLEEP_TIME); if(wake == 1){ if(!activity){ gw.send(msgDoor.set("1")); gw.send(msgDoor.set("0")); activity = true; if((!LEDSwitch) && (!SaverSwitch)){ pirswitch(); } else{ //activity finished activityoff(); } } } else{ //Timer wake up int LightLevel; if((!LEDSwitch) && (!SaverSwitch)){ for(int i = millis(); i < (millis() + 5000); i++){ LightLevel = (100 - ((1023-analogRead(LDR_PIN))/10.23)); } } else{ for(int i = millis(); i < (millis() + 1000); i++){ LightLevel = (100 - ((1023-analogRead(LDR_PIN))/10.23)); } } if((LightLevel < 10) && ((!LEDSwitch) && (SaverSwitch))){ Serial.println("Light level is less than 50%, Turning LED on"); digitalWrite(LED_PIN, LOW); LEDSwitch = true; SLEEP_TIME = 7200000; // Sleep time changed to 2 hours } else if((LightLevel > 20) && ((!LEDSwitch) && (!SaverSwitch))){ gw.send(msgLDR.set(LightLevel)); nightSwitch = false; SLEEP_TIME = 7200000; // Sleep time changed to 2 hours gw.sleep(SLEEP_TIME); } else if((LightLevel > 5) && (nightSwitch) && ((!LEDSwitch) && (!SaverSwitch))){ gw.send(msgLDR.set(LightLevel)); SLEEP_TIME = 600000; // Sleep time changed to 10 minutes } } } else { //When night switch is off int LightLevel; for(int i = millis(); i < (millis() + 5000); i++){ LightLevel = (100 - ((1023-analogRead(LDR_PIN))/10.23)); } if(LightLevel < 20){ gw.send(msgLDR.set(LightLevel)); nightSwitch = true; SLEEP_TIME = 7200000; // Sleep time changed to 2 hours gw.sleep(INTERRUPT,FALLING, SLEEP_TIME); } else if((LightLevel < 30) && (!nightSwitch)){ SLEEP_TIME = 600000; // Sleep time changed to 10 minutes gw.sleep(SLEEP_TIME); } else if((LightLevel < 50) && (!nightSwitch)){ SLEEP_TIME = 1800000; // Sleep time changed to 30 minutes gw.sleep(SLEEP_TIME); } } } void pirswitch() { for(int i = millis(); i < (millis() + 5000); i++){ //Check PIR for activity 10 times with delay of half second boolean tripped = digitalRead(PIR_PIN) == HIGH; Serial.println(i); if(tripped){ gw.send(msgPir.set(tripped?"1":"0")); Serial.println("Motion detected"); //activity on function activityon(); Serial.println("Loop terminated"); break; } } delay(3000); activity = false; } void activityon() { //turn saver on digitalWrite(SAVER_PIN, LOW); SaverSwitch = true; Serial.println("Energy saver turned on"); int LightLevel; for(int i = millis(); i < (millis() + 1000); i++){ //Check if energy saver is on LightLevel = (100 - ((1023-analogRead(LDR_PIN))/10.23)); } if(LightLevel < 10){ Serial.println("Light level is less than 50%, Turning LED on"); digitalWrite(LED_PIN, LOW); LEDSwitch = true; } else{ SLEEP_TIME = 1000; Serial.println("Sleep time changed to second"); } } void activityoff() { delay(3000); //turn off saver or LED digitalWrite(SAVER_PIN, HIGH); digitalWrite(LED_PIN, HIGH); Serial.println("Activity finished"); SaverSwitch = false; LEDSwitch = false; activity = false; SLEEP_TIME = 7200000; Serial.println("Sleep time changed to 2 hours"); } -
Here is my sketch if someone finds it useful. It uses LDR to set night mode in low light conditions and vice versa, door reed switch and PIR sensor to turn ac or dc lights with the help of two channel relay and EasyIOT as server. Interrupts perform the functions of turning lights on and off while timer wake up decides the night mode implementation. Moreover, sensor node sleeps most of its time to conserve the battery.
#include <SPI.h> #include <MySensor.h> #define CHILD_ID_LIGHT 0 #define CHILD_ID_DOOR 1 #define CHILD_ID_PIR 2 #define CHILD_ID_LED 3 #define CHILD_ID_SAVER 4 #define LDR_PIN A0 #define DOOR_PIN 2 #define PIR_PIN 3 #define LED_PIN 4 // Relay 1 is attached #define SAVER_PIN 5 // Relay 2 is attached #define INTERRUPT DOOR_PIN-2 unsigned long SLEEP_TIME = 1200000; // Sleep time 1200000 i.e. 20 minutes (in milliseconds) MySensor gw; boolean activity = false; boolean LEDSwitch = false; boolean SaverSwitch = false; boolean nightSwitch = false; MyMessage msgLDR(CHILD_ID_LIGHT, V_LIGHT_LEVEL); MyMessage msgDoor(CHILD_ID_DOOR, V_TRIPPED); MyMessage msgPir(CHILD_ID_PIR, V_TRIPPED); void setup() { gw.begin(NULL, AUTO, false, 1); gw.sendSketchInfo("BedRoom", "1.2"); pinMode(DOOR_PIN,INPUT); pinMode(PIR_PIN,INPUT); pinMode(LED_PIN, OUTPUT); pinMode(SAVER_PIN, OUTPUT); digitalWrite(DOOR_PIN, HIGH); digitalWrite(PIR_PIN, HIGH); digitalWrite(LED_PIN, HIGH); digitalWrite(SAVER_PIN, HIGH); gw.present(CHILD_ID_LIGHT, S_LIGHT_LEVEL); gw.present(CHILD_ID_DOOR, S_DOOR); gw.present(CHILD_ID_PIR, S_MOTION); int LightLevel; for(int i = millis(); i < (millis() + 5000); i++){ LightLevel = (100 - ((1023-analogRead(LDR_PIN))/10.23)); } if(LightLevel < 20){ gw.send(msgLDR.set(LightLevel)); nightSwitch = true; } else { gw.send(msgLDR.set(LightLevel)); nightSwitch = false; } } void loop() { if(nightSwitch){ //When night switch is on int wake; wake = gw.sleep(INTERRUPT,FALLING, SLEEP_TIME); if(wake == 1){ if(!activity){ gw.send(msgDoor.set("1")); gw.send(msgDoor.set("0")); activity = true; if((!LEDSwitch) && (!SaverSwitch)){ pirswitch(); } else{ //activity finished activityoff(); } } } else{ //Timer wake up int LightLevel; if((!LEDSwitch) && (!SaverSwitch)){ for(int i = millis(); i < (millis() + 5000); i++){ LightLevel = (100 - ((1023-analogRead(LDR_PIN))/10.23)); } } else{ for(int i = millis(); i < (millis() + 1000); i++){ LightLevel = (100 - ((1023-analogRead(LDR_PIN))/10.23)); } } if((LightLevel < 10) && ((!LEDSwitch) && (SaverSwitch))){ Serial.println("Light level is less than 50%, Turning LED on"); digitalWrite(LED_PIN, LOW); LEDSwitch = true; SLEEP_TIME = 7200000; // Sleep time changed to 2 hours } else if((LightLevel > 20) && ((!LEDSwitch) && (!SaverSwitch))){ gw.send(msgLDR.set(LightLevel)); nightSwitch = false; SLEEP_TIME = 7200000; // Sleep time changed to 2 hours gw.sleep(SLEEP_TIME); } else if((LightLevel > 5) && (nightSwitch) && ((!LEDSwitch) && (!SaverSwitch))){ gw.send(msgLDR.set(LightLevel)); SLEEP_TIME = 600000; // Sleep time changed to 10 minutes } } } else { //When night switch is off int LightLevel; for(int i = millis(); i < (millis() + 5000); i++){ LightLevel = (100 - ((1023-analogRead(LDR_PIN))/10.23)); } if(LightLevel < 20){ gw.send(msgLDR.set(LightLevel)); nightSwitch = true; SLEEP_TIME = 7200000; // Sleep time changed to 2 hours gw.sleep(INTERRUPT,FALLING, SLEEP_TIME); } else if((LightLevel < 30) && (!nightSwitch)){ SLEEP_TIME = 600000; // Sleep time changed to 10 minutes gw.sleep(SLEEP_TIME); } else if((LightLevel < 50) && (!nightSwitch)){ SLEEP_TIME = 1800000; // Sleep time changed to 30 minutes gw.sleep(SLEEP_TIME); } } } void pirswitch() { for(int i = millis(); i < (millis() + 5000); i++){ //Check PIR for activity 10 times with delay of half second boolean tripped = digitalRead(PIR_PIN) == HIGH; Serial.println(i); if(tripped){ gw.send(msgPir.set(tripped?"1":"0")); Serial.println("Motion detected"); //activity on function activityon(); Serial.println("Loop terminated"); break; } } delay(3000); activity = false; } void activityon() { //turn saver on digitalWrite(SAVER_PIN, LOW); SaverSwitch = true; Serial.println("Energy saver turned on"); int LightLevel; for(int i = millis(); i < (millis() + 1000); i++){ //Check if energy saver is on LightLevel = (100 - ((1023-analogRead(LDR_PIN))/10.23)); } if(LightLevel < 10){ Serial.println("Light level is less than 50%, Turning LED on"); digitalWrite(LED_PIN, LOW); LEDSwitch = true; } else{ SLEEP_TIME = 1000; Serial.println("Sleep time changed to second"); } } void activityoff() { delay(3000); //turn off saver or LED digitalWrite(SAVER_PIN, HIGH); digitalWrite(LED_PIN, HIGH); Serial.println("Activity finished"); SaverSwitch = false; LEDSwitch = false; activity = false; SLEEP_TIME = 7200000; Serial.println("Sleep time changed to 2 hours"); } -
@martinhjelmare In your code example, the sleep function needs a non-zero last parameter, in order to wake on timer.
So line 104 should read:
wake_cause = sensor_node.sleep(PRIMARY_BUTTON_PIN-2, CHANGE, SECONDARY_BUTTON_PIN-2, CHANGE, SLEEP_TIME);where SLEEP_TIME is in milliseconds, e.g.,
unsigned long SLEEP_TIME = 60000; // 60 sec sleep time between reads (seconds * 1000 milliseconds)Just tested this on the binary switch sketch.
-
@martinhjelmare In your code example, the sleep function needs a non-zero last parameter, in order to wake on timer.
So line 104 should read:
wake_cause = sensor_node.sleep(PRIMARY_BUTTON_PIN-2, CHANGE, SECONDARY_BUTTON_PIN-2, CHANGE, SLEEP_TIME);where SLEEP_TIME is in milliseconds, e.g.,
unsigned long SLEEP_TIME = 60000; // 60 sec sleep time between reads (seconds * 1000 milliseconds)Just tested this on the binary switch sketch.
Thanks! Good to hear that the sketch works after that correction.
-
@vickey Just curious, what is the purpose of this piece of code?
for(int i = millis(); i < (millis() + 5000); i++){ LightLevel = (100 - ((1023-analogRead(LDR_PIN))/10.23)); }