-
Notifications
You must be signed in to change notification settings - Fork 26
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
base: master
Are you sure you want to change the base?
Changes from 41 commits
756ea4e
32dbe97
0b21e93
4ba708b
6b736c6
6bed71f
c9869a7
939b983
8dfc171
c9c05ea
54ef098
5738e06
193cfbd
67f5969
0f7bcab
e599abb
c0941a1
a3a83ca
1a56e3b
d650ce8
59ecaec
e58ab86
348990c
bda7d59
b9200a3
a005ef8
72108db
ef70b27
1328207
868672a
f46fffe
6352f3e
cf311e2
b62b6f0
f08d648
05f454d
940f4a2
d5f613a
1f40038
6b5c7bb
60bfe4b
71b9c68
03cc19e
14c691d
b7f84ae
080d0a2
8766972
d5c4d39
58c2004
070e3c0
2f79a32
43fd013
b53521d
f326e60
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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")); | ||
debugSerial.println(wakeReason,HEX); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Spacing; |
||
|
||
if (wakeReason&TTN_WAKE_WATCHDOG) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Spacing; |
||
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 ")); | ||
} | ||
} | ||
``` | ||
|
||
|
@@ -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(); | ||
|
@@ -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. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
- `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`. | ||
|
@@ -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(); | ||
``` | ||
|
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.
Spacing;
Reason: 0x