Skip to content

Commit 45e601a

Browse files
committed
Add power saving technique with wake on RTC
1 parent bbd4e85 commit 45e601a

File tree

8 files changed

+265
-51
lines changed

8 files changed

+265
-51
lines changed

LICENSE.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2019 Olivier Staquet
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 21 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ The pins A4 and A5 have an internal pull up and are designed to be used as an I2
1414

1515
## Unofficial Arduino Nano 33 IoT pinout diagram
1616

17-
![Unofficial Arduino Nano 33 IoT pinout diagram](/images/Arduino%20Nano%2033%20IoT%20pinout%20diagram.png)
17+
![Unofficial Arduino Nano 33 IoT pinout diagram](images/Arduino%20Nano%2033%20IoT%20pinout%20diagram.png)
1818

1919
Useful ressources:
2020
* [Unofficial Arduino Nano 33 IoT pinout diagram (PDF)](https://github.com/ostaquet/Arduino-Nano-33-IoT-Ultimate-Guide/raw/master/resources/Arduino%20Nano%2033%20IoT%20pinout%20diagram.pdf)
@@ -24,15 +24,15 @@ Useful ressources:
2424
## Which pins can be used for external interrupt?
2525
The pins below can be used with `attachInterrupt()` on Nano 33 IoT.
2626

27-
| Board PIN | Internal PIN |
27+
| Board PIN | Internal PIN |
2828
|----|----|
29-
| A1 | 15 |
30-
| A5 | 19 |
31-
| A7 | 21 |
32-
| D2 | 2 |
33-
| D3 | 3 |
34-
| D9 | 9 |
35-
| D10 | 10 |
29+
| A1 | 15 |
30+
| A5 | 19 |
31+
| A7 | 21 |
32+
| D2 | 2 |
33+
| D3 | 3 |
34+
| D9 | 9 |
35+
| D10 | 10 |
3636
| D11 | 11 |
3737

3838
That information was extracted from [github.com/arduino/ArduinoCore-samd/blob/master/variants/nano_33_iot/variant.cpp](https://github.com/arduino/ArduinoCore-samd/blob/master/variants/nano_33_iot/variant.cpp).
@@ -44,7 +44,7 @@ According to the box, the Arduino Nano 33 IoT can be powered by the USB connecto
4444

4545
See the results of the experiments below regarding the power supply and the peak current consumption per voltage.
4646

47-
![Power consumption table](/images/PowerTable.png)
47+
![Power consumption table](images/PowerTable.png)
4848

4949
The programs below have been used to test the power consumption of the embedded modules:
5050
* **Sleep**: Using the watchdog to set the board to idle (see section *How to save power?* below)
@@ -59,53 +59,22 @@ The Arduino Nano 33 IoT has a 5V pin which is not wired by default. If you need
5959

6060
To to that, you just have to solder the VUSB jumper on the board.
6161

62-
![How to solder VUSB jumper on Arduino Nano 33 IoT](/images/Arduino_Nano_33_IoT_VUSB_jumper.jpg)
62+
![How to solder VUSB jumper on Arduino Nano 33 IoT](images/Arduino_Nano_33_IoT_VUSB_jumper.jpg)
6363

6464
Notice that you cannot supply power to the board through this pin, it is only to have a handy 5V for your external components powered by the USB. If you don't power the board through the USB jack, you will stay with 0V on this pin.
6565

6666
## How to save power with the Arduino Nano 33 IoT?
67-
The common way to save power with microcontroller is to go to sleep and use the watchdog to wakeup. Indeed, most of the power are drain while the microcontroller is doing nothing (i.e. waiting between two sample).
67+
There are the recommended approaches to save power with the Arduino Nano 33 IoT:
6868

69-
The very popular [Low-Power library](https://github.com/rocketscream/Low-Power) is supporting the SAMD21G but only after making some patching. A good alternative is to use the [Adafruit SleepyDog Library](https://github.com/adafruit/Adafruit_SleepyDog).
70-
71-
To install the library in the Arduino IDE, go in the menu *Tools -> Manage Libraries...* In the library manager, search for `Sleepy` and install the `Adafruit SleepyDog Library` by `Adafruit`.
72-
73-
![How to install SleepyDog with the library manager](/images/library_mgr_SleepyDog.png)
74-
75-
The usage is quite simple:
76-
77-
```
78-
#include <Adafruit_SleepyDog.h>
79-
80-
void setup() {
81-
pinMode(LED_BUILTIN, OUTPUT);
82-
digitalWrite(LED_BUILTIN, HIGH);
83-
}
84-
85-
void loop() {
86-
digitalWrite(LED_BUILTIN, LOW); // Show we're sleeping
87-
88-
// Sleep
89-
Watchdog.sleep();
90-
91-
digitalWrite(LED_BUILTIN, HIGH); // Show we're awake again
92-
delay(5000);
93-
}
94-
```
95-
96-
When you're calling the function `Watchdog.sleep()`, the board will be idle for **16 seconds** and the consumption is going as low as **6mA when powered at 3.3V** (which is quite better than 18mA with the BareMinimum program).
97-
98-
The only trick is when you want to upload a new program on your board... When the board is idle, you cannot upload a new program on it because it is not listening to the USB serial. So, never upload a program without some activities (real activities or fake activities like the `delay(5000)` above) to have the time slot to upload successfully.
99-
100-
Useful resources:
101-
* [Adafruit SleepyDog Library](https://github.com/adafruit/Adafruit_SleepyDog)
69+
- Shutdown all useless components (Wifi, IMU...) and put the microcontroller (SAMD21G) in sleep mode. This will allow you to go down to 6mA while sleeping (if powered in 3.3V). [See how to put the Arduino Nano 33 IoT on sleep](SavePowerSleeping.md).
70+
- Shutdown the power and wake-up based on a RTC clock. This will allow you to go down to 0mA while the power is off and wake up at a specific interval of time (every minutes, every hours...). [See how to shutdown the power of the Arduino Nano 33 IoT and wake up on specific time with the RTC](SavePowerRTC.md).
10271

10372
## How to use the Wifi with the Arduino Nano 33 IoT?
10473
The Wifi module embedded on the Arduino Nano 33 IoT is the popular [NINA W102](https://www.u-blox.com/sites/default/files/NINA-W10_DataSheet_%28UBX-17065507%29.pdf) ESP32 based module. It provides support of Wifi 802.11 b/g/n in the 2.4 GHz band and Bluetooth v4.2 (Bluetooth BR/EDR and Bluetooth Low Energy BLE). The module is fully compatible with the [official WiFiNINA library](https://www.arduino.cc/en/Reference/WiFiNINA).
10574

10675
To install the official library in the Arduino IDE, go in the menu *Tools -> Manage Libraries...* In the library manager, search for `WifiNINA` and install the `WiFiNINA` by `Arduino`.
10776

108-
![How to install WifiNINA with the library manager](/images/library_mgr_WifiNINA.png)
77+
![How to install WifiNINA with the library manager](images/library_mgr_WifiNINA.png)
10978

11079
Useful ressources:
11180
* [Official documentation of the WiFiNINA library](https://www.arduino.cc/en/Reference/WiFiNINA)
@@ -124,7 +93,7 @@ Useful ressources:
12493
### The official Arduino LSM6DS3 library (basic usage)
12594
To install the official library in the Arduino IDE, go in the menu *Tools -> Manage Libraries...* In the library manager, search for `LSM6DS3` and install the `Arduino_LSM6DS3` by `Arduino`.
12695

127-
![How to install LSM6DS3 with the library manager](/images/library_mgr_LSM6DS3.png)
96+
![How to install LSM6DS3 with the library manager](images/library_mgr_LSM6DS3.png)
12897

12998
The usage is described on the [official Arduino website](https://www.arduino.cc/en/Reference/ArduinoLSM6DS3).
13099

@@ -135,7 +104,7 @@ Simple programs are available with the library:
135104
### The Sparkfun LSM6DS3 library (advanced usage)
136105
To install the official library in the Arduino IDE, go in the menu *Tools -> Manage Libraries...* In the library manager, search for `LSM6DS3` and install the `SparkFun LSM6DS3 Breakout` by `SparkFun Electronics`.
137106

138-
![How to install LSM6DS3 with the library manager](/images/library_mgr_LSM6DS3_SparkFun.png)
107+
![How to install LSM6DS3 with the library manager](images/library_mgr_LSM6DS3_SparkFun.png)
139108

140109
The usage is described on the [GitHub page of the library](https://github.com/sparkfun/SparkFun_LSM6DS3_Arduino_Library). You will notice that this library is offering advanced features like:
141110
* Usage through multiples instances on I2C channels and SPI.
@@ -180,12 +149,12 @@ A SERCOM can be *classic* or *alternate*. In the data sheet, the *classic* is in
180149

181150
For reference, see below the table I used to select the SERCOM to assign:
182151

183-
![Reference of SERCOM to assign](/images/SERCOM.png)
152+
![Reference of SERCOM to assign](images/SERCOM.png)
184153

185154
Enough of theory, go for the solution...
186155

187156
Add a **hardware serial on pins 5 (RX) and 6 (TX)** of the Arduino Nano 33 IoT:
188-
```
157+
```c++
189158
#include <Arduino.h>
190159
#include "wiring_private.h"
191160

@@ -213,7 +182,7 @@ void loop() {
213182
214183
Another example, add a **hardware serial on pins 13 (RX) and 8 (TX)** of the Arduino Nano 33 IoT:
215184
216-
```
185+
```c++
217186
#include <Arduino.h>
218187
#include "wiring_private.h"
219188
@@ -238,3 +207,4 @@ void loop() {
238207
// Do something with mySerial...
239208
}
240209
```
210+

SavePowerRTC.md

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
# How to save power with the Arduino Nano 33 IoT by shutting down the power and wake up on RTC alarm?
2+
3+
## How to shutdown the power of the Arduino Nano 33 IoT and wake up on specific time with the RTC clock?
4+
5+
In most data capture projects, the microcontroller is spending a tremendous amount of time doing nothing (waiting or sleeping). During this sleeping time, the power is consumed and the batteries are going down. In order to keep your project alive on months/years on battery, the best is to minimize the power consumption while the sleeping cycle.
6+
7+
The approach described here allows to:
8+
9+
- Shutdown the all power of the circuit during the sleep cycle.
10+
- Wake up at pre-defined interval (every minute, every hour, every day or at a specific moment).
11+
- Consume only the power required for the RTC clock.
12+
13+
What do you need?
14+
15+
- RTC DS3231 module (I use the ChronoDot 2.1 by Macetech but any DS3231 module with the INT pin wired in OK)
16+
- The [library DS3231 by NothernWidget](https://github.com/NorthernWidget/DS3231)
17+
- 2x capacitors 0.1mF
18+
- 2x resistors 100KOhms
19+
- 1x NPN transistor (I use the BC547B)
20+
- 1x MOSFET N-channel (I use the STP16NF06)
21+
22+
The schematics is quite simple:
23+
24+
![Wake on RTC alarm schematics](images/WakeOnTime_schem.png)
25+
26+
If you want to reproduce this circuit on a breadboard:
27+
28+
![Wake on RTC alarm schematics](images/WakeOnTime_bb.png)
29+
30+
The bevaviour is easy to understand:
31+
32+
- The Arduino Nano 33 IoT is piloting the RTC clock via I2C bus to set the alarm and clear the alarm.
33+
- The alarm of RTC clock is piloting the NPN transistor to open the power on the MOSFET.
34+
- The Arduino Nano 33 IoT is powered through the MOSFET.
35+
- The program is running only once and go everytime through the `setup()` and `loop()` functions.
36+
37+
The program below is doing:
38+
39+
- Blink the buildin LED 3 times fast at the startup.
40+
- Set the alarm on the RTC to wake up every minute.
41+
- Blink the building LED 5 seconds.
42+
- Clear the alarm to shutdown the power.
43+
44+
```c++
45+
// Libraries required
46+
#include <Wire.h>
47+
#include <DS3231.h>
48+
49+
// Global variables
50+
DS3231 Clock;
51+
52+
void setup() {
53+
// Wait 1 second (sometime, the wake-up is hard...)
54+
delay(1000);
55+
56+
// Initialize LED
57+
pinMode(PIN_LED, OUTPUT);
58+
59+
// On startup, blink 3 times fast...
60+
for(uint8_t i = 0; i < 3; i++) {
61+
digitalWrite(PIN_LED, HIGH);
62+
delay(100);
63+
digitalWrite(PIN_LED, LOW);
64+
delay(100);
65+
}
66+
67+
// Start the I2C interface
68+
Wire.begin();
69+
70+
// Alarm is not enabled! Should set alarm
71+
if(!Clock.checkAlarmEnabled(1))
72+
{
73+
Clock.setClockMode(false);
74+
// 0b1111 // each second
75+
// 0b1110 // Once per minute (when second matches)
76+
// 0b1100 // Once per hour (when minute and second matches)
77+
// 0b1000 // Once per day (when hour, minute and second matches)
78+
// 0b0000 // Once per month when date, hour, minute and second matches. Once per week if day of the week and A1Dy=true
79+
// Set alarm to happen every minute (change to your wanted interval)
80+
Clock.setA1Time(1, 1, 1, 0, 0b1110, false, false, false);
81+
Clock.turnOnAlarm(1);
82+
}
83+
84+
// Empty the I2C buffer
85+
while(Wire.available()) {
86+
Wire.read();
87+
}
88+
}
89+
90+
/****************************************************************************************
91+
* Main program
92+
***************************************************************************************/
93+
void loop() {
94+
// When waking-up, blink for 5 seconds
95+
for(uint8_t i = 0; i < 5; i++) {
96+
digitalWrite(PIN_LED, HIGH);
97+
delay(1000);
98+
digitalWrite(PIN_LED, LOW);
99+
delay(1000);
100+
}
101+
102+
// Reset alarm to turn off the device
103+
Clock.checkIfAlarm(1);
104+
105+
// Wait 10 seconds (if power down not wired)
106+
delay(10000);
107+
}
108+
```
109+
110+
([See the source code](https://github.com/ostaquet/arduino-nano-33-iot-ultimate-guide/blob/master/src/PowerOnTimer/PowerOnTimer.ino))

SavePowerSleeping.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# How to save power with the Arduino Nano 33 IoT by sleeping?
2+
3+
## How to put the Arduino Nano 33 IoT on sleep?
4+
5+
The common way to save power with microcontroller is to go to sleep and use the watchdog to wakeup. Indeed, most of the power are drain while the microcontroller is doing nothing (i.e. waiting between two sample). This will allow you to go down to 6mA at the microcontroller level while sleeping (if powered in 3.3V).
6+
7+
The very popular [Low-Power library](https://github.com/rocketscream/Low-Power) is supporting the SAMD21G but only after making some patching. A good alternative is to use the [Adafruit SleepyDog Library](https://github.com/adafruit/Adafruit_SleepyDog).
8+
9+
To install the library in the Arduino IDE, go in the menu *Tools -> Manage Libraries...* In the library manager, search for `Sleepy` and install the `Adafruit SleepyDog Library` by `Adafruit`.
10+
11+
![How to install SleepyDog with the library manager](images/library_mgr_SleepyDog.png)
12+
13+
The usage is quite simple:
14+
15+
```c++
16+
#include <Adafruit_SleepyDog.h>
17+
18+
void setup() {
19+
pinMode(LED_BUILTIN, OUTPUT);
20+
digitalWrite(LED_BUILTIN, HIGH);
21+
}
22+
23+
void loop() {
24+
digitalWrite(LED_BUILTIN, LOW); // Show we're sleeping
25+
26+
// Sleep
27+
Watchdog.sleep();
28+
29+
digitalWrite(LED_BUILTIN, HIGH); // Show we're awake again
30+
delay(5000);
31+
}
32+
```
33+
34+
When you're calling the function `Watchdog.sleep()`, the board will be idle for **16 seconds** and the consumption is going as low as **6mA when powered at 3.3V** (which is quite better than 18mA with the BareMinimum program).
35+
36+
The only trick is when you want to upload a new program on your board... When the board is idle, you cannot upload a new program on it because it is not listening to the USB serial. So, never upload a program without some activities (real activities or fake activities like the `delay(5000)` above) to have the time slot to upload successfully.
37+
38+
Useful resources:
39+
40+
* [Adafruit SleepyDog Library](https://github.com/adafruit/Adafruit_SleepyDog)

images/WakeOnTime_bb.png

338 KB
Loading

images/WakeOnTime_schem.png

90.9 KB
Loading

resources/WakeOnTime.fzz

15.6 KB
Binary file not shown.

src/PowerOnTimer/PowerOnTimer.ino

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/****************************************************************************************
2+
* PowerOnTimer
3+
* ------------
4+
* Based on Arduino Nano IoT 33 and ChronoDot 2.1
5+
* By Olivier Staquet
6+
***************************************************************************************/
7+
8+
// Libraries required
9+
#include <Wire.h>
10+
#include <DS3231.h>
11+
12+
// Global variables
13+
DS3231 Clock;
14+
15+
/****************************************************************************************
16+
* Initialization
17+
***************************************************************************************/
18+
void setup() {
19+
// Wait 1 second (sometime, the wake-up is hard...)
20+
delay(1000);
21+
22+
// Initialize LED
23+
pinMode(PIN_LED, OUTPUT);
24+
25+
// On startup, blink 3 times fast...
26+
for(uint8_t i = 0; i < 3; i++) {
27+
digitalWrite(PIN_LED, HIGH);
28+
delay(100);
29+
digitalWrite(PIN_LED, LOW);
30+
delay(100);
31+
}
32+
33+
// Start the I2C interface
34+
Wire.begin();
35+
36+
// Alarm is not enabled! Should set alarm
37+
if(!Clock.checkAlarmEnabled(1))
38+
{
39+
Clock.setClockMode(false);
40+
// 0b1111 // each second
41+
// 0b1110 // Once per minute (when second matches)
42+
// 0b1100 // Once per hour (when minute and second matches)
43+
// 0b1000 // Once per day (when hour, minute and second matches)
44+
// 0b0000 // Once per month when date, hour, minute and second matches. Once per week if day of the week and A1Dy=true
45+
// Set alarm to happen every minute (change to your wanted interval)
46+
Clock.setA1Time(1, 1, 1, 0, 0b1110, false, false, false);
47+
Clock.turnOnAlarm(1);
48+
}
49+
50+
// Empty the I2C buffer
51+
while(Wire.available()) {
52+
Wire.read();
53+
}
54+
}
55+
56+
/****************************************************************************************
57+
* Main program
58+
***************************************************************************************/
59+
void loop() {
60+
// When waking-up, blink for 5 seconds
61+
for(uint8_t i = 0; i < 5; i++) {
62+
digitalWrite(PIN_LED, HIGH);
63+
delay(1000);
64+
digitalWrite(PIN_LED, LOW);
65+
delay(1000);
66+
}
67+
68+
// Reset alarm to turn off the device
69+
Clock.checkIfAlarm(1);
70+
71+
// Wait 10 seconds (if power down not wired)
72+
delay(10000);
73+
}

0 commit comments

Comments
 (0)