Go Down

Topic: Arduino Zero / M0 pro in sleep mode. (Read 17881 times) previous topic - next topic

ClumsyPilot

I just tested your code, and replaced

attachInterrupt(0, onInt, RISING);


with:

attachInterrupt(0, onInt, LOW);

In that case it appears that Arduino restarts code from the beginging, it does not call the interrupt function. Anyone has a working example of DeelSleep?

josephchrzempiec

#16
Dec 30, 2018, 07:55 am Last Edit: Dec 30, 2018, 07:56 am by josephchrzempiec
Hello i know is this is a old project of mine And i didn't finish it. I actually just came back to it and wanted to see If I can finish it and see where it goes.


To answer  ClumsyPilot question for some unknown reason that didn't work. I couldn't even get the Led to turn on when power is applied. But if i change 13 to LED_BUILTIN That did turn on the led blinking it before it went to sleep.

however when i change from attachInterrupt(0, onInt, RISING); to attachInterrupt(0, onInt, LOW); Nothing changed. Still wouldn't wake up.




New updated sketch based off the old one.  




Code: [Select]



/*

 Arduino ZERO PRO low-power sleep mode with wakeup upon external interrupt
 (example sketch)

 Add a button on digital pin 0, with an additional pull-up resistor.
 Add an LED on digital pin 3 (don't forget resistor)
 
 NOTE: LED might not appear to toggle, or it might flash, that is because of switch bounce.
 (Electrically noisy contacts)
 I think there is a filtering option to digitally filter external interrupts.
  Might check that out in the future.

*/

bool ledState = true;

void setup()
{
  Serial.begin(9600);
  pinMode(3, OUTPUT);  // Output for an LED that is toggled on/off upon interrupt
  pinMode(LED_BUILTIN, OUTPUT);  // Flashing LED pin
  
  // I could actually use the ARM macro thingies and set registers
  // and what not to do the same exact thing,
  // But I'm lazy so I just cheated and used this arduino function
  
  attachInterrupt(0, onInt, LOW);
  
  SCB->SCR |= 1<<2; // Enable deep-sleep mode
  
  // Set the EIC (External Interrupt Controller) to wake up the MCU
  // on an external interrupt from digital pin 0. (It's EIC channel 11)
  EIC->WAKEUP.reg = EIC_WAKEUP_WAKEUPEN11;
}

void loop()
{
  Serial.println("Sleeping in 3");
  toggleAndDelay();
  Serial.println("Sleeping in 2");
  toggleAndDelay();
  Serial.println("Sleeping in 1");
  toggleAndDelay();
  __WFI(); // This is the WFI (Wait For Interrupt) function call.
}

// Called upon interrupt of digital pin 0.
void onInt()
{
  ledState = !ledState;
  digitalWrite(3, ledState);
}

// This just toggles the LED on pin 13, and delays.
// Used in between the sleep countdown Serial.println()
void toggleAndDelay()
{
  digitalWrite(LED_BUILTIN, HIGH);
  delay(500);
  digitalWrite(LED_BUILTIN, LOW);
  delay(500);
}

MartinL

#17
Dec 30, 2018, 12:45 pm Last Edit: Dec 30, 2018, 05:48 pm by MartinL
Hi josephchrzempiec,

The following code puts the CPU core into deep sleep and awakens it with a logic HIGH interrupt on digtial pin D12. The interrupt sets the LED on D13 high, returns to the main loop(), waits for one second, switches off the LED and enters deep sleep oncemore:

Code: [Select]
// Put the CPU core into deep sleep and awake with a logic HIGH interrupt on D12
void setup()
{
  pinMode(13, OUTPUT);                          // Set digital pin 13 to an output
  pinMode(12, INPUT_PULLDOWN);                  // Set digital pin D12 to an input with an internal pull-down resistor
  attachInterrupt(12, interrupt, HIGH);         // Set up an interrupt on digital pin D12 on a logic HIGH level
  SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;            // Set up the CPU to enter low power STANDBY mode on running the WFI() function (Wait For Interrupt)
}

void loop()
{
  delay(1000);                                  // Wait for 1 second
  digitalWrite(13, LOW);                        // Set D13 output to logic LOW
  __WFI();                                      // Put the CPU core into deep sleep
}

void interrupt()                                // Interrupt Service Routine (ISR)
{
  digitalWrite(13, HIGH);                       // Set D13 output to logic HIGH
}

Note that putting the processor core into deep sleep requires a double tap on the reset button (bootloader mode), in order to load the next sketch, as internally it stops the clock that drives the native USB port.

josephchrzempiec

Hello MartinL Thank you i will try it as soon as i get home.

evilkos

The code above works, thanks! And there's also a library for Arduino Zero called ArduinoLowPower: https://www.arduinolibraries.info/libraries/arduino-low-power

It has the sleep() function defined and working perfectly for my device. Not a whole lot simpler than the code above, but has other handy functions, and also depends on an otherwise useful RTCZero lib.

Go Up