-
Notifications
You must be signed in to change notification settings - Fork 58
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for ADC wakeup interrupt on SAMD21
This can be used to configure the ADC window interrupt on the SAMD21. It uses OSCULP32K via GCLK6 to clock the ADC while in sleep mode (the same as used for the EIC). Note that attachAdcInterrupt()/detachAdcInterrupt() should be called immediately before/after LowPower.sleep() otherwise analogRead() will not work as expected. There is also an example (AdcWakeup.ino) which is much like the ExternalWakeup example but uses the ADC interrupt instead.
- Loading branch information
Showing
3 changed files
with
204 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
/* | ||
AdcWakeup | ||
This sketch demonstrates the usage of the ADC to wakeup a chip in sleep mode. | ||
Sleep modes allow a significant drop in the power usage of a board while it does nothing waiting for an event to happen. Battery powered application can take advantage of these modes to enhance battery life significantly. | ||
In this sketch, changing the voltage on pin A0 will wake up the board. You can test this by connecting a potentiometer between VCC, A0, and GND. | ||
Please note that, if the processor is sleeping, a new sketch can't be uploaded. To overcome this, manually reset the board (usually with a single or double tap to the RESET button) | ||
This example code is in the public domain. | ||
*/ | ||
|
||
#include "ArduinoLowPower.h" | ||
|
||
// Blink sequence number | ||
// Declare it volatile since it's incremented inside an interrupt | ||
volatile int repetitions = 1; | ||
|
||
// Pin used to trigger a wakeup | ||
const int pin = A0; | ||
// How sensitive to be to changes in voltage | ||
const int margin = 10; | ||
|
||
void setup() { | ||
pinMode(LED_BUILTIN, OUTPUT); | ||
pinMode(pin, INPUT); | ||
} | ||
|
||
void loop() { | ||
for (int i = 0; i < repetitions; i++) { | ||
digitalWrite(LED_BUILTIN, HIGH); | ||
delay(500); | ||
digitalWrite(LED_BUILTIN, LOW); | ||
delay(500); | ||
} | ||
|
||
// Read the voltage at the ADC pin | ||
int value = analogRead(pin); | ||
|
||
// Define a window around that value | ||
uint16_t lo = max(value - margin, 0); | ||
uint16_t hi = min(value + margin, UINT16_MAX); | ||
|
||
// Attach an ADC interrupt on pin A0, calling repetitionsIncrease when the voltage is outside the given range. | ||
// This should be called immediately before LowPower.sleep() because it reconfigures the ADC internally. | ||
LowPower.attachAdcInterrupt(pin, repetitionsIncrease, ADC_INT_OUTSIDE, lo, hi); | ||
|
||
// Triggers an infinite sleep (the device will be woken up only by the registered wakeup sources) | ||
// The power consumption of the chip will drop consistently | ||
LowPower.sleep(); | ||
|
||
// Detach the ADC interrupt. This should be called immediately after LowPower.sleep() because it restores the ADC configuration after waking up. | ||
LowPower.detachAdcInterrupt(); | ||
} | ||
|
||
void repetitionsIncrease() { | ||
// This function will be called once on device wakeup | ||
// You can do some little operations here (like changing variables which will be used in the loop) | ||
// Remember to avoid calling delay() and long running functions since this functions executes in interrupt context | ||
repetitions ++; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
fa71703
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@sijk this addition is great! Thanks for coding it.
I am having an error with it though. If I use it in conjunction with a timed interrupt, for example: LowPower.sleep(uint32_t(30000)); Then the device wakes up but never runs the loop. What am I missing? Can both interrupts exist at the same time?