Skip to content

Commit 7e6cc0c

Browse files
ysoldakdeadprogram
authored andcommitted
concept: low power
1 parent e85557b commit 7e6cc0c

File tree

1 file changed

+74
-0
lines changed

1 file changed

+74
-0
lines changed

content/docs/concepts/low-power.md

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
---
2+
title: "Low Power"
3+
linkTitle: "Low Power"
4+
type: "docs"
5+
weight: 35
6+
description: >
7+
How to consume less power on microcontrollers
8+
---
9+
10+
Microcontrollers are usually rather non-demanding when it comes to power consumption.
11+
Couple hudreds mW is the most you may expect a hobby project would use.
12+
13+
Sometimes, even that is not low enough.
14+
Power your project from a battery, and it'd benefit greatly from consuming less.
15+
16+
Common scenario for such projects is sleeping most of the time, and only rarely briefly wake up to query sensors and execute actions.
17+
The main caveat here is if not configured properly, microcontroller and peripherals continue to consume power while your program "sleeps".
18+
19+
The standard way to pause execution in Go is to use `time.Sleep()` function that is available in TinyGo too. Depending on the chip and effort put into its support, the efficiency of this function may vary. The only thing certain: this is _not worse_ than busy looping until a certain time has passed.
20+
Still, with such high-level function as `time.Sleep()` it is not always possible to disable everything that consumes power as the decisions may depend on the application, presense of peripherals and the board used.
21+
22+
Most microcontrollers have one or more "low power" modes, also known as "deep sleep" and, sometimes, "dormant".
23+
In such modes microcontroller may consume as low as milli- or even micro-Watts.
24+
TinyGo gives you low level access to hardware to try and make most of it.
25+
26+
## Implementations
27+
28+
Manufacturers implement different modes, depending of capabilites of their products and name these modes differently too.
29+
Hence no naming consistency across microcontrollers, unfortunately.
30+
31+
Always consult "Power consumption" part of a respective datasheet to understand capabilities of your hardware.
32+
When reading datasheets, keep in mind peripherals that draw power too. These include \[power\] LEDs, various sensors or co-processors usually present on development boards.
33+
34+
Capabilities of different chips:
35+
- Some very good chips (like the nRF series) can go to a very low power state (just a few µA) with RAM retention and waking up from a low-power RTC.
36+
- Some limited chips (like the esp32) can't really "sleep" with low power -- they can disable the core and memory and reset after a predefined time losing state stored in memory.
37+
- Other chips need to use a special feature to go into deep sleep mode.
38+
39+
Especially the distinction between waking up with or without RAM is important, because it greatly affects how you write software.
40+
41+
The common way to wake up from deep sleep is to use [interrupts](compiler-internals/interrupts), such as timer, real-time-clock or an interrupt on a pin change.
42+
43+
### RP2040
44+
45+
Minimal achievable power consumption is 0.18mA in "Dormant" and 0.39mA in "Sleep" modes.
46+
See [RP2040 datasheet](https://datasheets.raspberrypi.com/rp2040/rp2040-datasheet.pdf#page=621), section 5.7 Power Consumption.
47+
48+
### nRF Family
49+
50+
[nRF series chips](https://www.nordicsemi.com/Products) are exceptionally efficient and is recommended choice for low-power projects.
51+
Even with [BLE broadcasting enabled](https://devzone.nordicsemi.com/power/w/opp/2/online-power-profiler-for-bluetooth-le) it can use less power than RP2040 in its lowest power state!
52+
53+
Minimal achievable power consumption is in the area of µA.
54+
55+
TinyGo implements standard `time.Sleep()` very efficiently for nRF chips so you can just use it and have great results.
56+
The only thing you may want to tweak is to disable the UART with help of `-serial=none` flag to go even lower than default.
57+
58+
## The Way to Low Power
59+
60+
> Attached [debugger](../guides/debugging) usually blocks the low power state in chip.
61+
> The best way to measure when using a debugger is to flash the code, do a power cycle, and then measure.
62+
63+
> The changes discussed in this paragraph shall be made in TinyGo and not in your application code.
64+
> These are `runtime` and/or `machine` packages, in files related to your target.
65+
66+
Following steps shall help you achieve low power consumption:
67+
68+
- Put a `for { arm.Asm("wfi") }` loop before anything else is initialized (at the beginning of [Reset_Handler](https://github.com/tinygo-org/tinygo/search?q=%22export+Reset_Handler%22)).
69+
_`wfi` pauses the processor, puts it in "wait for interrupt" state. And when inserted before any initialisation, this ensures no internal subsystem is running consuming power._
70+
- Measure the current, this should be the lowest consumption as advertised for the chip.
71+
- If it is higher than that, investigate why (it could be a power LED, regulator, some clock that's enabled by the bootloader, maybe other things).
72+
_Usually this ranges somewhere between 1µA and 100µA, depending on the low-power capabilities of the chip. Don't continue until you really do reach the lowest possible power consumption._
73+
- Slowly move the loop to later in the code, until you move it into the main function.
74+
- There are probably things initialized by default that consume current, like UART, PLLs, different clocks. Disable them before continuing, or investigate why they consume power.

0 commit comments

Comments
 (0)