Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ultra Low Power deepsleep #15

Open
wants to merge 54 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 41 commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
756ea4e
bugfix and features
hallard Feb 12, 2018
32dbe97
Added Low Power Example
hallard Feb 12, 2018
0b21e93
Creation
hallard Feb 12, 2018
4ba708b
Added Lora Module Sleep Mode
hallard Feb 12, 2018
6b736c6
Fixed link
hallard Feb 12, 2018
6bed71f
bump to version 2.0.3
hallard Feb 12, 2018
c9869a7
force cast of CONFIG_INTERVAL #define
hallard Feb 12, 2018
939b983
Only TTN Core team allowed to increase version
hallard Feb 12, 2018
8dfc171
Cosmetic
hallard Feb 12, 2018
c9c05ea
cosmetic formating
hallard Feb 13, 2018
54ef098
Added missing include
hallard Feb 13, 2018
5738e06
Requires TheThingsNode library 2.5.6
hallard Feb 13, 2018
193cfbd
Added option to wake by lora module
hallard Feb 20, 2018
67f5969
added option to wake by lora module
hallard Feb 20, 2018
0f7bcab
Fix Lora Module Sleep
hallard Feb 20, 2018
e599abb
Fix IRQ problem on Serial Wake not detected
hallard Feb 20, 2018
c0941a1
Added new sleep mode with LoRa module
hallard Feb 20, 2018
a3a83ca
cosmetic
hallard Feb 20, 2018
1a56e3b
Updated to new Ultra Low Power Sleep Mode (with LoRa module wake)
hallard Feb 20, 2018
d650ce8
Detailled Low Power Mode
hallard Feb 20, 2018
59ecaec
Merge remote-tracking branch 'upstream/master'
hallard Feb 20, 2018
e58ab86
Added getVCC() using with ADC Low Noise Feature
hallard Feb 21, 2018
348990c
Get VCC of ATMega with getVCC()
hallard Feb 21, 2018
bda7d59
Fixed button release bug
hallard Feb 22, 2018
b9200a3
send all VDD/VCC/VRN values
hallard Feb 22, 2018
a005ef8
Added The Thing Network Library 2.5.7
hallard Feb 22, 2018
72108db
use of sprintf_p and some cosmetics
hallard Feb 22, 2018
ef70b27
Disable USB Regulator on deep sleeep
hallard Feb 24, 2018
1328207
Added Ultra Low Power mode
hallard Feb 26, 2018
868672a
send wakeSatus to intervall callback
hallard Feb 28, 2018
f46fffe
Low Power optimization and bug fixes
hallard Feb 28, 2018
6352f3e
Optimized Low Power
hallard Feb 28, 2018
cf311e2
Updated for Ultra Low Power
hallard Mar 1, 2018
b62b6f0
fix Link
hallard Mar 1, 2018
f08d648
fix code dispkay
hallard Mar 1, 2018
05f454d
Updated for Ultra Low Power
hallard Mar 1, 2018
940f4a2
secrure printf and set channel 10 for button duration
hallard Mar 1, 2018
d5f613a
updated onInterval method()
hallard Mar 1, 2018
1f40038
fixed wake with wakeReason parameter
hallard Mar 1, 2018
6b5c7bb
fixed call of wake and interval
hallard Mar 1, 2018
60bfe4b
fix var name error
hallard Mar 1, 2018
71b9c68
renamed getVcc to getVCC
hallard Mar 4, 2018
03cc19e
renamed getVcc to getVCC and cosmetic
hallard Mar 4, 2018
14c691d
renamed getVcc to getVCC
hallard Mar 4, 2018
b7f84ae
renamed getVcc to getVCC
hallard Mar 4, 2018
080d0a2
costemic requested by johan
hallard Mar 4, 2018
8766972
removed all printf reference
hallard Mar 4, 2018
d5c4d39
removed printf reference requested by johan
hallard Mar 4, 2018
58c2004
Clarification about sensor working mode
hallard Mar 4, 2018
070e3c0
Updated temp sensor to Low Power
hallard Mar 4, 2018
2f79a32
Added delay on wake if temp sensor was in power down mode
hallard Mar 5, 2018
43fd013
fix push button debouncing in IRQ
hallard Mar 6, 2018
b53521d
Disable Sleep mode in USB
hallard Mar 6, 2018
f326e60
Disabled sleep mode in USB
hallard Mar 6, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ before_install:
- sudo ln -s /usr/local/share/arduino/arduino /usr/local/bin/arduino
install:
- ln -s $PWD /usr/local/share/arduino/libraries/TheThingsNode
- arduino --install-library "DHT sensor library:1.3.0,Adafruit Unified Sensor:1.0.2,TheThingsNetwork:2.5.6"
- arduino --install-library "DHT sensor library:1.3.0,Adafruit Unified Sensor:1.0.2,TheThingsNetwork:2.5.7"
- git clone https://github.com/sparkfun/arduino_boards /tmp/sparkfun
- mv /tmp/sparkfun/sparkfun /usr/local/share/arduino/hardware/sparkfun
before_script:
Expand Down
103 changes: 90 additions & 13 deletions docs/TheThingsNode.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,23 +38,76 @@ This will:
> Don't add any other code in your `loop()` function, but use [`onWake()`](#method-onwake), [`onInterval()`](#method-oninterval) and [`onSleep()`](#method-onsleep) instead, to prevent unpredictable behavior.

## Method: onWake
Set a callback that will run first thing every time the Node wakes up, which is when an interrupt changes because of interaction with the button, motion sensor or temperature sensor. The device also wakes up every 8 seconds, which is the longest we can make it sleep.
Set a callback that will run first thing every time the Node wakes up, which is when an interrupt changes because of interaction with the button, motion sensor, temperature sensor or LoRa device wake.

Depending on [`configInterval()`](#method-configinterval) setup, this method can be called:

- When you instructed the LoRa RN2xxx device to wake up after the specific interval.
- Every 8 seconds (Watchdog), which is the longest we can make it sleep.

the parameter wakeReason is indicating what waked the node and can be a bit field of the following description

| Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| :--- | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: |
| Wake by | Interval | Watchdog | LoRa | Btn Release | Btn Press | Motion Stop | Motion Start | Temperature |

Is declared into the library as follow:
```c
void onWake(void(*callback)(void));
#define TTN_WAKE_TEMPERATURE 0x01
#define TTN_WAKE_MOTION_START 0x02
#define TTN_WAKE_MOTION_STOP 0x04
#define TTN_WAKE_BTN_PRESS 0x08
#define TTN_WAKE_BTN_RELEASE 0x10
#define TTN_WAKE_LORA 0x20
#define TTN_WAKE_WATCHDOG 0x40
#define TTN_WAKE_INTERVAL 0x80
```

Note that of course, wake by TTN_WAKE_LORA also setup the TTN_WAKE_INTERVAL because we program the LoRa module to wake at the specified interval.


```c
void onWake(void(*callback)(uint8_t wakeReason));
```

Usage:


```c
void setup() {
node = TheThingsNode::setup();

node->onWake(wake);
}

void wake() {
node->setColor(TTN_GREEN);
void wake(uint8_t wakeReason) {
debugSerial.print(F("Wake Reason:0x"));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Spacing; Reason: 0x

debugSerial.println(wakeReason,HEX);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Spacing; wakeReason, HEX


if (wakeReason&TTN_WAKE_WATCHDOG) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Spacing; wakeReason & TTN_WAKE_WATCHDOG

debugSerial.print(F("Watchdog "));
}
if (wakeReason&TTN_WAKE_INTERVAL) {
debugSerial.print(F("Interval "));
}
if (wakeReason&TTN_WAKE_LORA) {
debugSerial.print(F("LoRa_RN2xxx "));
}
if (wakeReason&TTN_WAKE_BTN_PRESS) {
debugSerial.print(F("Button_Press "));
}
if (wakeReason&TTN_WAKE_BTN_RELEASE) {
debugSerial.print(F("Button_release "));
}
if (wakeReason&TTN_WAKE_MOTION_START) {
debugSerial.print(F("Motion_Start "));
}
if (wakeReason&TTN_WAKE_MOTION_STOP) {
debugSerial.print(F("Motion_Stop "));
}
if (wakeReason&TTN_WAKE_TEMPERATURE) {
debugSerial.print(F("Temperature "));
}
}
```

Expand All @@ -81,12 +134,10 @@ void sleep() {
}
```

Pay attention, this internal sleep method of the library does not put the LoRa module (RN2483 or RN2903) into sleep mode and thus your node may consume 3mA even in sleep mode. You need to manually set the LoRa module to sleep and wake.
Check the example [BatteryMonitorLPP](../examples/BatteryMonitorLPP/)

## Interval
Instead of using your `loop()` function, use `configInterval()` and `onInterval()` to set a function to be called on a certain interval:


```c
void setup() {
node = TheThingsNode::setup();
Expand All @@ -97,31 +148,37 @@ void setup() {
node->onInterval(interval);
}

void interval() {
void interval(uint8_t wakeReason) {
node->showStatus();
}
```
See [`onWake()`](#method-onwake) for definition of wakeReason:


### Method: onInterval
Set a callback that will run on a certain interval. This will automatically enable the interval.

```c
void onInterval(void(*callback)(void));
void onInterval(void(*callback)(uint8_t wakeReason));
```

- `void(*callback)(void)`: Function to be called, with no arguments nor return value.
- `void(*callback)(uint8_t wakeReason)`: Function to be called.

See [`onWake()`](#method-onwake) for definition of wakeReason:

### Method: configInterval

```c
void configInterval(bool enabled, uint32_t ms);
void configInterval(bool enabled);
void configInterval(TheThingsNetwork *pttn, uint32_t ms);
```

- `bool enabled`: Enable or disable the interval callback. Enabled automatically by `onInterval()`, but you can use this method to temporarily disable it. Defaults to `false`.
- `TheThingsNetwork * pttn`: This enable the interval callback but in this mode, the interval is passed to RN2483 or RN2903 module (this is why we need to pass pointer to object) with the command `sys sleep ms` and then it's the LoRa module that wake up the node. This is the most advanced Low Power Mode. In this mode, the watchdog is disabled and consuption again reduced.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

consuMption

- `uint32_t ms`: Minimal time between calling the interval callback. Defaults to `60000` or 60 seconds.

> If the Node has no USB data connection or is configured to also sleep in that case, it will only wake up every 8 seconds to check if the interval callback should run. This means setting `ms` to less than `8000` makes no sense. It also means that the maximum time between calls can be up to 8 seconds longer than `ms` if it wakes up to handle button or sensor interaction in between.
> If the Node has no USB data connection or is configured to also sleep in that case, it will only wake up every 8 seconds to check if the interval callback should run. This means setting `ms` to less than `8000` makes no sense. It also means that the maximum time between calls can be up to 8 seconds longer than `ms` if it wakes up to handle button or sensor interaction in between. This does not apply when wake up by LoRa module.

## Method: showStatus
Writes information about the device and sensors to `Serial`.
Expand Down Expand Up @@ -457,9 +514,29 @@ When disabled, the [`loop()`](#method-loop) method will delay 100ms until an int

> When the Node goes into sleep, the Serial Monitor will loose its connection. The Node will try to reopen the connection when it wakes up, but Serial Monitor might not always be able to pick it up.

## Method: getBattery
Returns the battery level in millivolt (mV) as a unsigned integer of 2 bytes.
## Battery
Different methods to get battery level

### Method: getBattery
Returns the battery level in millivolt (mV) as a unsigned integer of 2 bytes. This method measure battery with a resistor voltage divider (located before 3.3V ob board regulator.) and connected to an analog input pin. The ADC pin as voltage reference of 2.52V

```c
uint16_t getBattery();
```

### Method: getVcc
Returns the AT32U4 chip measured VCC voltage millivolt (mV) using the 1.1V internal Analog Reference voltage. This method is prefered when voltage before regulator comes to and below 3.3V. Moreover, if voltage is below 2.52V, using the method `getBattery` could return wrong values due to the main voltage < ADC reference voltage.

```c
uint16_t getVcc();
```

### Alternative Method: getVDD
You can also use the getVDD from [TTN Device Library](https://github.com/TheThingsNetwork/arduino-device-lib).

Returns the voltage in millivolt (mV) measured by the RN2xxx LoRa module. It's for information only since we don't know how it's measured.

```c
uint16_t bat = ttn.getVDD();
```

4 changes: 2 additions & 2 deletions examples/Basic/Basic.ino
Original file line number Diff line number Diff line change
Expand Up @@ -80,15 +80,15 @@ void loop()
node->loop();
}

void interval()
void interval(uint8_t wakeReason)
{
node->setColor(TTN_BLUE);

debugSerial.println("-- SEND: INTERVAL");
sendData(PORT_INTERVAL);
}

void wake()
void wake(uint8_t wakeReason)
{
node->setColor(TTN_GREEN);
}
Expand Down
Loading