Feather m0 (SAMD) sleep and interrupt
-
Hi,
I've been trying everything I know of to get a feather m0 wake up by interrupt after deep sleep but I can't get it working with the mysensors lib.
if I remove all mysensors related code sleep and wakeup works just fine
Any help or tip appreciated!Here's the code:
#define MY_DEBUG #define MY_RADIO_RFM69 #define TIME_TO_SLEEP 299 #define Battery_HIGH 4.2 #define Battery_LOW 3.2 #define MY_IS_RFM69HW #define MY_RFM69_FREQUENCY RFM69_433MHZ #define MY_RFM69_NEW_DRIVER #define MY_DEFAULT_ERR_LED_PIN 13 #define MY_RFM69_RST_PIN 4 #define MY_RFM69_IRQ_PIN 3 #define MY_RFM69_CS_PIN 8 #define MY_NODE_ID 11 #define MY_SIGNAL_REPORT_ENABLED #define MY_TRANSPORT_WAIT_READY_MS 15000 #include <MySensors.h> #define REEDSWITCHPIN 6 volatile bool SLEEP_FLAG = true; // Use sleeproutines or not bool debug = true; int bootCycles = 0; String wakeupReason = "none"; void setup() { pinMode(REEDSWITCHPIN, INPUT_PULLUP); attachInterrupt(digitalPinToInterrupt(REEDSWITCHPIN), EIC_ISR, FALLING); delay(100); sleepSetup(); } void presentation() { } void loop() { delay(5000); Serial.println("Going to sleep in 60 seconds..."); delay(60000); if (debug) Serial.print("REEDSWITCHPIN State: "); if (debug) Serial.println(REEDSWITCHPIN); sleepRoutine(); } void sleepRoutine() { PORT->Group[g_APinDescription[LED_BUILTIN].ulPort].OUTCLR.reg = (uint32_t)(1<<g_APinDescription[LED_BUILTIN].ulPin); // set pin mode to low transportDisable(); // Disable rfm69 __DSB(); if (debug) Serial.println("ZzZ (WFI)"); USBDevice.detach(); delay(5000); __WFI(); // Sleep delay(1000); PORT->Group[g_APinDescription[LED_BUILTIN].ulPort].OUTTGL.reg = (uint32_t)(1<<g_APinDescription[LED_BUILTIN].ulPin); // toggle output of built-in LED pin USBDevice.attach(); delay(10000); if (debug) Serial.println("Out of ZzZ (WFI)"); //transportReInitialise(); // Enable rfm69 delay(100); } void EIC_ISR(void) { //SLEEP_FLAG ^= true; // toggle SLEEP_FLAG by XORing it against true wakeupReason = "INTERRUPT"; } void sleepSetup() { SYSCTRL->XOSC32K.reg |= (SYSCTRL_XOSC32K_RUNSTDBY | SYSCTRL_XOSC32K_ONDEMAND); // set external 32k oscillator to run when idle or sleep mode is chosen REG_GCLK_CLKCTRL |= GCLK_CLKCTRL_ID(GCM_EIC) | // generic clock multiplexer id for the external interrupt controller GCLK_CLKCTRL_GEN_GCLK1 | // generic clock 1 which is xosc32k GCLK_CLKCTRL_CLKEN; // enable it while (GCLK->STATUS.bit.SYNCBUSY); // write protected, wait for sync EIC->WAKEUP.reg |= EIC_WAKEUP_WAKEUPEN4; // Set External Interrupt Controller to use channel 4 (pin 6) PM->SLEEP.reg |= PM_SLEEP_IDLE_CPU; // Enable Idle0 mode - sleep CPU clock only SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; // Enable Standby or "deep sleep" mode if (debug) Serial.println("EO sleepsetup"); }
-
@Alpoy void presentation() is empty - That could have an effect as the node is probably going round and round in circles trying to find the gateway. We will only know if you would post your debg output to see what is really going on here.
-
Indeed you're right I have removed more and more coded to eliminate any causes and reduced it all to the bare minimum, nothing changed. Anyways, I added this to the above code:
#define CHILD_ID_MBXTRIP 52 MyMessage MbxTrip(CHILD_ID_MBXTRIP, V_TRIPPED); void presentation() { sendSketchInfo("Mbx", "2.0"); present(CHILD_ID_MBXTRIP, S_DOOR); }
And here's the debug output:
11:54:19.036 -> 3084 TSM:FPAR:OK 11:54:19.036 -> 3084 TSM:ID 11:54:19.036 -> 3084 TSM:ID:OK 11:54:19.036 -> 3084 TSM:UPL 11:54:19.106 -> 3153 TSF:MSG:SEND,11-11-0-0,s=255,c=3,t=24,pt=1,l=1,sg=0,ft=0,st=OK:1 11:54:19.748 -> 3399 TSF:MSG:READ,0-0-11,s=255,c=3,t=25,pt=1,l=1,sg=0:1 11:54:19.748 -> 3399 TSF:MSG:PONG RECV,HP=1 11:54:19.748 -> 3399 TSM:UPL:OK 11:54:19.748 -> 3399 TSM:READY:ID=11,PAR=0,DIS=1 11:54:19.748 -> 3475 TSF:MSG:SEND,11-11-0-0,s=255,c=3,t=15,pt=6,l=2,sg=0,ft=0,st=OK:0100 11:54:19.748 -> 3714 TSF:MSG:READ,0-0-11,s=255,c=3,t=15,pt=6,l=2,sg=0:0100 11:54:19.763 -> 3801 TSF:MSG:SEND,11-11-0-0,s=255,c=0,t=17,pt=0,l=5,sg=0,ft=0,st=OK:2.3.2 11:54:20.561 -> 4370 TSF:MSG:SEND,11-11-0-0,s=255,c=3,t=6,pt=1,l=1,sg=0,ft=0,st=OK:0 11:54:22.599 -> 6437 TSF:MSG:SEND,11-11-0-0,s=255,c=3,t=11,pt=0,l=3,sg=0,ft=0,st=OK:Mbx 11:54:22.972 -> 7006 TSF:MSG:SEND,11-11-0-0,s=255,c=3,t=12,pt=0,l=3,sg=0,ft=0,st=OK:2.0 11:54:23.576 -> 7573 TSF:MSG:SEND,11-11-0-0,s=52,c=0,t=0,pt=0,l=0,sg=0,ft=0,st=OK: 11:54:23.576 -> 7574 MCO:REG:REQ 11:54:24.110 -> 8142 TSF:MSG:SEND,11-11-0-0,s=255,c=3,t=26,pt=1,l=1,sg=0,ft=0,st=OK:2 11:54:24.538 -> 8383 TSF:MSG:READ,0-0-11,s=255,c=3,t=27,pt=1,l=1,sg=0:1 11:54:24.538 -> 8383 MCO:PIM:NODE REG=1 11:54:24.538 -> 8383 MCO:BGN:STP 11:54:24.538 -> EO sleepsetup 11:54:24.538 -> 8484 MCO:BGN:INIT OK,TSP=1 11:54:29.540 -> Going to sleep in 60 seconds... 11:55:29.782 -> REEDSWITCHPIN State: 6 11:55:29.782 -> 73484 TSF:TDI:TSL 11:55:29.782 -> ZzZ (WFI)
Now, when I make D6 (REEDSWITCHPIN) go LOW by conneting to GND nothing happens (doesn't wake up). But removing all mysensors code makes it work
-
I've forgotten to add a digitalRead in the code above on the REEDSWITCHPIN State but it's "1".
-
I may have solved/found a workaround for this, changing the interrupt to trigger on "LOW" instead of "FALLING" works for some reason
-
@Alpoy Well done! - That is interesting! - I never used a SAMD, but at least you have a way to make it work! Maybe I should try one someday....