Sleep() with interrupt only works with level "LOW"
-
@Yveaux Not really.. since 2.1.1 I'm losing it... :blush: Still in the process of finding differences with the previous version...
-
-
@AWI Took me a day of debugging, datasheet reading and searching the internet, but It looks like I fixed the sleep with external interrupts issues in the MySensors library!
Main issue was this one: https://github.com/mysensors/MySensors/issues/811
If an interrupt was pending (if it had been registered before actually sleeping the AVR) it would immediately wake the AVR again, just 2ms after sleeping it. It didn't matter if this interrupt was registered just before calling sleep or 1 hour ago...
Furthermore https://github.com/mysensors/MySensors/issues/812 and https://github.com/mysensors/MySensors/issues/809 were also fixed, but have minor impact.I tested it on a ProMini with ATMega328P @ 8MHz, powered directly by 2xAA battery -- a 'standard' sleeping sensor processor setup.
I verified sleeping modes LOW, CHANGE, RISING & FALLING to work Ok. This confirms your findings and Nick Gammon's.Sidenote: Mode HIGH is mapped onto CHANGE in Arduino ATMega328P port (duh!). The library can therefore not distinguish between the two and will use CHANGE in both situations.
The bugs are solved in development branch, so please give it a try!
-
@AWI Took me a day of debugging, datasheet reading and searching the internet, but It looks like I fixed the sleep with external interrupts issues in the MySensors library!
Main issue was this one: https://github.com/mysensors/MySensors/issues/811
If an interrupt was pending (if it had been registered before actually sleeping the AVR) it would immediately wake the AVR again, just 2ms after sleeping it. It didn't matter if this interrupt was registered just before calling sleep or 1 hour ago...
Furthermore https://github.com/mysensors/MySensors/issues/812 and https://github.com/mysensors/MySensors/issues/809 were also fixed, but have minor impact.I tested it on a ProMini with ATMega328P @ 8MHz, powered directly by 2xAA battery -- a 'standard' sleeping sensor processor setup.
I verified sleeping modes LOW, CHANGE, RISING & FALLING to work Ok. This confirms your findings and Nick Gammon's.Sidenote: Mode HIGH is mapped onto CHANGE in Arduino ATMega328P port (duh!). The library can therefore not distinguish between the two and will use CHANGE in both situations.
The bugs are solved in development branch, so please give it a try!
The new version didn't seem to help with my scenario - a vibration sensor where I only want to send one message per "event". (A vibration detected within a few seconds, or more). Using the default handling:
switch ( sleep(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR), CHANGE, SLEEP_TIME) ) { case MY_WAKE_UP_BY_TIMER: sendHeartbeat(); break; case MY_SLEEP_NOT_POSSIBLE: Serial.println("Unable to sleep ;-("); break; default: Serial.println("Sending a message with value = 1 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); send(msg.set(1)); }There are always 2 messages sent. This happens even if I add a sleep either before or after the send().
My workaround has been to add this after the send():
while (sleep(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR), CHANGE, 2000) != MY_WAKE_UP_BY_TIMER ) { Serial.println("Clearing interrupts"); }I'm not sure the workaround is a good idea - because it may cause other problems. Any other ideas? Or is this correct?
Thanks!
-
@AWI Took me a day of debugging, datasheet reading and searching the internet, but It looks like I fixed the sleep with external interrupts issues in the MySensors library!
Main issue was this one: https://github.com/mysensors/MySensors/issues/811
If an interrupt was pending (if it had been registered before actually sleeping the AVR) it would immediately wake the AVR again, just 2ms after sleeping it. It didn't matter if this interrupt was registered just before calling sleep or 1 hour ago...
Furthermore https://github.com/mysensors/MySensors/issues/812 and https://github.com/mysensors/MySensors/issues/809 were also fixed, but have minor impact.I tested it on a ProMini with ATMega328P @ 8MHz, powered directly by 2xAA battery -- a 'standard' sleeping sensor processor setup.
I verified sleeping modes LOW, CHANGE, RISING & FALLING to work Ok. This confirms your findings and Nick Gammon's.Sidenote: Mode HIGH is mapped onto CHANGE in Arduino ATMega328P port (duh!). The library can therefore not distinguish between the two and will use CHANGE in both situations.
The bugs are solved in development branch, so please give it a try!
-
The new version didn't seem to help with my scenario - a vibration sensor where I only want to send one message per "event". (A vibration detected within a few seconds, or more). Using the default handling:
switch ( sleep(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR), CHANGE, SLEEP_TIME) ) { case MY_WAKE_UP_BY_TIMER: sendHeartbeat(); break; case MY_SLEEP_NOT_POSSIBLE: Serial.println("Unable to sleep ;-("); break; default: Serial.println("Sending a message with value = 1 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); send(msg.set(1)); }There are always 2 messages sent. This happens even if I add a sleep either before or after the send().
My workaround has been to add this after the send():
while (sleep(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR), CHANGE, 2000) != MY_WAKE_UP_BY_TIMER ) { Serial.println("Clearing interrupts"); }I'm not sure the workaround is a good idea - because it may cause other problems. Any other ideas? Or is this correct?
Thanks!
@ileneken3 Could it be that your sensor is better handled with a RISING or FALLING interrupt? CHANGE fires on both edges. Else post your whole sketch and debug log.
-
The new version didn't seem to help with my scenario - a vibration sensor where I only want to send one message per "event". (A vibration detected within a few seconds, or more). Using the default handling:
switch ( sleep(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR), CHANGE, SLEEP_TIME) ) { case MY_WAKE_UP_BY_TIMER: sendHeartbeat(); break; case MY_SLEEP_NOT_POSSIBLE: Serial.println("Unable to sleep ;-("); break; default: Serial.println("Sending a message with value = 1 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); send(msg.set(1)); }There are always 2 messages sent. This happens even if I add a sleep either before or after the send().
My workaround has been to add this after the send():
while (sleep(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR), CHANGE, 2000) != MY_WAKE_UP_BY_TIMER ) { Serial.println("Clearing interrupts"); }I'm not sure the workaround is a good idea - because it may cause other problems. Any other ideas? Or is this correct?
Thanks!
@ileneken3 for how long did you sleep when trying to use sleep to debounce the interrupt after sending? If you used a number less than 15, could you try with 15 or above? The sleep function does not work very well with small sleep times. or replace that sleep with wait.
-
Tried all suggestions. Here is the whole code:
/** The MySensors dev version **/ #define MY_NODE_ID 89 #define MY_PARENT_NODE_ID 88 // Main floor repeater #define CHILD_ID 88 // Id of the sensor child #define MY_RF24_PA_LEVEL RF24_PA_HIGH // Attempt to get radio to work #define MY_BAUD_RATE 9600 #define MY_RADIO_NRF24 #define MY_DEBUG // Enables debug messages #include <MySensors.h> unsigned long SLEEP_TIME = 360000; // 6 minutes between heartbeats #define DIGITAL_INPUT_SENSOR 3 // The digital input attached to vibration sensor. // Initialize message MyMessage msg(CHILD_ID, V_TRIPPED); void setup() { Serial.begin(9600); // 9600 needed for 1MHZ pinMode(DIGITAL_INPUT_SENSOR, INPUT); // sets the motion sensor digital pin as input pinMode(DIGITAL_INPUT_SENSOR, INPUT_PULLUP); wait(100); Serial.println("Sending a message with value = 1 to get things started"); send(msg.set(1)); } void presentation() { // Send the sketch version information to the gateway and Controller sendSketchInfo("Mailbox Sensor 1Mhz", "1.5"); // Register all sensors to gw (they will be created as child devices) present(CHILD_ID, S_MOTION); } void loop() { // Sleep until woken by sensor, or timeout // Tried with FALLING and RISING also. switch ( sleep(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR), CHANGE, SLEEP_TIME) ) { case MY_WAKE_UP_BY_TIMER: Serial.println("Woke up after SLEEP_TIME seconds so sending heartbeat"); sendHeartbeat(); break; case MY_SLEEP_NOT_POSSIBLE: Serial.println("Unable to sleep ;-("); break; default: Serial.println("Sending a message with value = 1 !!!!!!"); // Tried with sleep(15), sleep(1000), sleep(10000). delay(1000) and wait(4000) wait(4000); #ifdef SHOULD_NOT_BE_NEEDED while (sleep(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR), CHANGE, 2000) != MY_WAKE_UP_BY_TIMER ) { Serial.println("Clearing interrupts"); } #endif break; } }Here is the debug log:
0 MCO:BGN:INIT NODE,CP=RNNNA---,VER=2.2.0-beta
49 TSM:INIT
65 TSF:WUR:MS=0
81 TSM:INIT:TSP OK
114 TSM:INIT:STATID=89
131 TSF:SID:OK,ID=89
163 TSM:FPAR
212 TSF:MSG:SEND,89-89-255-255,s=255,c=3,t=7,pt=0,l=0,sg=0,ft=0,st=OK:
737 TSF:MSG:READ,0-0-89,s=255,c=3,t=8,pt=1,l=1,sg=0:0
786 TSF:MSG:FPAR OK,ID=0,D=1
1179 TSF:MSG:READ,88-88-89,s=255,c=3,t=8,pt=1,l=1,sg=0:1
1245 TSF:MSG:FPAR PREF
1261 TSF:MSG:FPAR OK,ID=88,D=2
1294 TSM:FPAR:OK
1327 TSM:ID
1343 TSM:ID:OK
1359 TSM:UPL
1376 TSF:MSG:SEND,89-89-88-0,s=255,c=3,t=24,pt=1,l=1,sg=0,ft=0,st=OK:1
3473 TSM:UPL
3489 TSF:MSG:SEND,89-89-88-0,s=255,c=3,t=24,pt=1,l=1,sg=0,ft=0,st=OK:1
3571 TSF:MSG:READ,0-88-89,s=255,c=3,t=25,pt=1,l=1,sg=0:2
3637 TSF:MSG:PONG RECV,HP=2
3670 TSM:UPL:OK
3686 TSM:READY:ID=89,PAR=88,DIS=2
3735 TSF:MSG:SEND,89-89-88-0,s=255,c=3,t=15,pt=6,l=2,sg=0,ft=0,st=OK:0100
3817 TSF:MSG:READ,0-88-89,s=255,c=3,t=15,pt=6,l=2,sg=0:0100
3899 TSF:MSG:SEND,89-89-88-0,s=255,c=0,t=17,pt=0,l=10,sg=0,ft=0,st=OK:2.2.0-beta
3997 TSF:MSG:SEND,89-89-88-0,s=255,c=3,t=6,pt=1,l=1,sg=0,ft=0,st=OK:88
6111 TSF:MSG:SEND,89-89-88-0,s=255,c=3,t=11,pt=0,l=19,sg=0,ft=0,st=OK:Mailbox Sensor 1Mhz
6225 TSF:MSG:SEND,89-89-88-0,s=255,c=3,t=12,pt=0,l=3,sg=0,ft=0,st=OK:1.5
6324 TSF:MSG:SEND,89-89-88-0,s=88,c=0,t=1,pt=0,l=0,sg=0,ft=0,st=OK:
6406 MCO:REG:REQ
6422 TSF:MSG:SEND,89-89-88-0,s=255,c=3,t=26,pt=1,l=1,sg=0,ft=0,st=OK:2
6504 TSF:MSG:READ,0-88-89,s=255,c=3,t=27,pt=1,l=1,sg=0:1
6586 MCO:PIM:NODE REG=1
6602 MCO:BGN:STP
Sending a message with value = 1 to get things started
6766 TSF:MSG:SEND,89-89-88-0,s=88,c=1,t=16,pt=2,l=2,sg=0,ft=0,st=OK:1
6881 MCO:BGN:INIT OK,TSP=1
6897 MCO:SLP:MS=360000,SMS=0,I1=1,M1=1,I2=255,M2=255
6963 TSF:TDI:TSL
6995 MCO:SLP:WUP=1
7012 TSF:TRI:TSB
Sending a message with value = 1 !!!!!!
11059 MCO:SLP:MS=360000,SMS=0,I1=1,M1=1,I2=255,M2=255
11108 TSF:TDI:TSL
11141 MCO:SLP:WUP=1
11157 TSF:TRI:TSB
Sending a message with value = 1 !!!!!!
15204 MCO:SLP:MS=360000,SMS=0,I1=1,M1=1,I2=255,M2=255
15253 TSF:TDI:TSLI always get at least two messages, sometimes more.
Here is the sensor:
-
@ileneken3 for how long did you sleep when trying to use sleep to debounce the interrupt after sending? If you used a number less than 15, could you try with 15 or above? The sleep function does not work very well with small sleep times. or replace that sleep with wait.
I did try many combinations of sleep,wait,delay. I always get at least 2 messages sent.
Below, I posted the code and the debug log.Thanks again.
