Lab #7: Správa napájania a nízka spotreba
o tom, ako sa dá znížiť spotreba zariadenia pomocou softvérových a hardvérových prerušení, znížení pracovnej frekvencie, o režimoch spánku a spôsoboch prebudenia sa z neho
Motivácia
Jednou z hlavných výziev, ktorú priniesol Internet vecí, je dosiahnuť čo najnižšiu spotrebu energie zariadení. Efektívnym riadením spotreby dokážeme predĺžiť životnosť batériovo napájaných systémov z týždňov na mesiace či dokonca roky. V tomto cvičení si ukážeme niekoľko praktických spôsobov, ako znížiť spotrebu nášho chytrého senzora – znížením pracovnej frekvencie, využitím režimov spánku a prebúdzaním pomocou externého časovača alebo stlačením tlačidla.
Ciele
naučiť sa uspať zariadenie
naučiť sa zobudiť zariadenie pomocou externého prerušenia z tlačítka
naučiť sa softvérovo meniť frekvenciu zariadenia
porozumieť významu časovača Watchdog
časovač cez externý RTC modul
Postup
USB multimeter
Na meranie budeme v tomto cvičení používať USB multimeter (označovaný aj ako USB tester), napr. UM24. Zapája sa medzi zdroj napájania a merané zariadenie a meria všetko, čo cez jeho USB konektor prechádza.
USB multimeter zvyčajne zobrazuje tieto hodnoty:
- napätie (V) a prúd (A), ktorý zariadenie odoberá,
- výkon (W), ktorý je ich súčinom,
- náboj (mAh) a energiu (mWh), ktoré zariadenie od začiatku merania spotrebovalo, a
- čas, ako dlho meranie trvá.
Okamžité hodnoty prúdu a výkonu nám povedia, koľko zariadenie odoberá práve teraz. Kumulované hodnoty náboja a energie zase to, koľko spotrebovalo za celý čas merania. Práve tie sa budú hodiť, keď budeme chcieť porovnať, koľko energie spotrebuje jeden celý cyklus zariadenia od zobudenia až po opätovné uspanie.
Pri meraní dodržiavajte tieto všeobecné pravidlá:
- Poznajte rozlíšenie a presnosť svojho merača. Napríklad merač UM24 meria prúd s rozlíšením 1 mA a s presnosťou ±(0,8 % + 3 digity), teda pri malých prúdoch s chybou až niekoľko mA. Hodnota, ktorá je porovnateľná s chybou merača, je len orientačná.
- Používajte stabilný zdroj napájania. Zariadenie napájajte z USB nabíjačky. Ak ho napájate z počítača, meranie ovplyvní aj komunikácia cez USB. Powerbanka sa zase pri malom odbere môže sama vypnúť.
- Merajte ustálený stav a dostatočne dlho. Merač obnovuje hodnoty len niekoľkokrát za sekundu, takže krátke špičky prúdu (napr. pri vysielaní cez WiFi) nemusí zachytiť. Kumulované hodnoty ich však zahrnú.
- Pred každým meraním vynulujte kumulované hodnoty.
- Medzi meraniami meňte vždy len jednu vec. Používajte rovnaký kábel, rovnaký zdroj a rovnaké zapojenie, aby ste mohli výsledky navzájom porovnať.
- Zapisujte si podmienky merania spolu s nameranými hodnotami (čo zariadenie robilo, aké bolo zapojenie, ako dlho meranie trvalo).
Merač meria odber celej dosky pri napätí 5 V, teda nielen mikrokontroléra, ale aj stabilizátora napätia, WiFi čipu, LED diód a všetkých pripojených senzorov.
Task
Odmerajte odber zariadenia v prípadoch uvedených v tabuľke 1.
Zariadenie napájajte z USB nabíjačky cez USB multimeter. Namerané hodnoty budú slúžiť ako referenčné, s nimi budete porovnávať všetky ďalšie merania. Napätie, pri ktorom ste merali, si zapíšte pod tabuľku.
| Prípad | Prúd (mA) | Výkon (mW) |
|---|---|---|
| program, ktorý nič nerobí | ||
stav Init |
||
stav Measurement |
||
stav ConnectNetwork |
||
stav PublishData |
||
stav DisconnectNetwork |
||
stav Sleep |
Niektoré stavy trvajú tak krátko, že ich odber z merača neodčítate. Preto odmerajte aj náboj a energiu, ktoré zariadenie spotrebuje za jeden celý cyklus od štartu až po zaspanie, a zapíšte ich do tabuľky 2.
| Náboj (mAh) | Energia (mWh) | Čas (s) |
|---|---|---|
Zníženie pracovnej frekvencie
Jedným zo spôsobov, ako znížiť spotrebu zariadenia, je spomaliť jeho prácu znížením pracovnej frekvencie mikrokontroléra. Ako zistiť a zmeniť pracovnú frekvenciu a na čo si pri tom dať pozor, sa dozviete v kapitole Zmena frekvencie zariadenia.
Task
Odmerajte odber zariadenia pri pracovných frekvenciách uvedených v tabuľke 3.
Merajte program, ktorý nič nerobí, rovnako ako v prvom riadku tabuľky
1. Meniť sa bude len pracovná
frekvencia volaním funkcie machine.freq().
| Frekvencia (MHz) | Prúd (mA) | Výkon (mW) |
|---|---|---|
| 150 | ||
| 125 | ||
| 100 | ||
| 75 | ||
| 48 |
Uspanie zariadenia
Chytrý senzor bude merať teplotu a vlhkosť v pravidelných
intervaloch. Medzi meraniami však nemá čo robiť, a preto ho v tomto čase
uspíme. Stav Sleep zatiaľ činnosť zariadenia ukončí. Po
novom zariadenie v tomto stave zaspí a po zobudení bude pokračovať
ďalším meraním (pozri obrázok 2).
---
# spolocna konfiguracia stavovych diagramov THSensor; vklada sa ako prvy
# riadok bloku ```mermaid, za nim nasleduje "flowchart LR" a samotny diagram
config:
flowchart:
curve: basis
nodeSpacing: 40
rankSpacing: 60
themeVariables:
fontSize: 20px
themeCSS: ".edgeLabel, .edgeLabel p, .labelBkg { background-color: var(--bs-body-bg) !important; }"
---
flowchart LR
start@{ shape: f-circ } --> init("<div style='width:164px;height:48px;display:flex;align-items:center;justify-content:center;line-height:1.2'>Init</div>")
init --> measurement("<div style='width:164px;height:48px;display:flex;align-items:center;justify-content:center;line-height:1.2'>Measurement</div>")
init -- "<code>SVC_PIN</code><br>grounded" --> terminal("<div style='width:164px;height:48px;display:flex;align-items:center;justify-content:center;line-height:1.2'>Service<br>Terminal</div>")
init -- "long button<br>press" --> reset("<div style='width:164px;height:48px;display:flex;align-items:center;justify-content:center;line-height:1.2'>Factory<br>Reset</div>")
init -- "no/faulty<br><code>settings.json</code> /<br>short button press" --> configuration("<div style='width:164px;height:48px;display:flex;align-items:center;justify-content:center;line-height:1.2'>Configuration</div>")
measurement --> connect("<div style='width:164px;height:48px;display:flex;align-items:center;justify-content:center;line-height:1.2'>Connect<br>Network</div>")
connect -- "connected" --> publish("<div style='width:164px;height:48px;display:flex;align-items:center;justify-content:center;line-height:1.2'>Publish<br>Data</div>")
connect -- "connection<br>failed" --> disconnect("<div style='width:164px;height:48px;display:flex;align-items:center;justify-content:center;line-height:1.2'>Disconnect<br>Network</div>")
publish --> disconnect
disconnect --> sleep("<div style='width:164px;height:48px;display:flex;align-items:center;justify-content:center;line-height:1.2'>Sleep</div>")
sleep -- "wake up" --> measurement
terminal --> terminalEnd@{ shape: fr-circ }
reset --> resetEnd@{ shape: fr-circ }
configuration --> commissioning("<div style='width:164px;height:48px;display:flex;align-items:center;justify-content:center;line-height:1.2'>Commissioning</div>")
commissioning -- "verification<br>result" --> configuration
configuration -- "restart" --> configurationEnd@{ shape: fr-circ }
%% spolocne styly stavovych diagramov THSensor (farby podla
%% images/thsensor-state.diagram.complete.png); vklada sa na koniec diagramu
%% a stavy sa k nim priradia cez "class <stavy> <styl>"
classDef state fill:#cfe2ff,stroke:#9aa3ad,stroke-width:3px,color:#343a40,font-weight:bold
classDef service fill:#cbc3a3,stroke:#9aa3ad,stroke-width:3px,color:#343a40,font-weight:bold
classDef reset fill:#ffd6f5,stroke:#9aa3ad,stroke-width:3px,color:#343a40,font-weight:bold
classDef config fill:#fddba7,stroke:#9aa3ad,stroke-width:3px,color:#343a40,font-weight:bold
classDef error fill:#ffd7d9,stroke:#9aa3ad,stroke-width:3px,color:#343a40,font-weight:bold
classDef ota fill:#c3f5c8,stroke:#9aa3ad,stroke-width:3px,color:#343a40,font-weight:bold
classDef initial fill:#000,stroke:#fff,stroke-width:2px
classDef final fill:#fff,stroke:#000,stroke-width:2px
class init,measurement,connect,publish,disconnect,sleep state
class terminal service
class reset reset
class configuration,commissioning config
class start initial
class terminalEnd,resetEnd,configurationEnd final
Obr. 2: Stavový diagram zariadenia s opakovaným meraním
Na uspanie zariadenia použijeme ľahký spánok (pozri prednášku (Nízka) spotreba energie). Na mikrokontroléri RP2350 by nám hlboký spánok neušetril žiadnu energiu navyše a zariadenie by sa po zobudení reštartovalo.
Task
Pridajte do nastavení interval merania.
Nastavenia merania budú v samostatnom vnorenom modeli
Measurement, podobne ako nastavenia WiFi siete alebo
MQTT brokera. Zatiaľ bude obsahovať len položku
interval, ktorá určuje interval merania v sekundách.
Predvolená hodnota bude 900, teda 15 minút. V nastaveniach
bude model dostupný pod názvom measurement, takže interval
získate ako settings.measurement.interval.
Interval merania musí byť kladné celé číslo. Kontrolu môžete napísať
ako znovupoužiteľnú funkciu do modulu
models/validators.py.
Poznámka
Ak súbor settings.json položku measurement
ešte neobsahuje, model Settings pri jeho načítaní použije
predvolené hodnoty. Zariadenie preto po tejto zmene nebude potrebovať
novú konfiguráciu.
Task
Doplňte do formulára s nastaveniami pole na zmenu intervalu merania.
Task
Uspite zariadenie v stave Sleep na interval merania a po
zobudení pokračujte stavom Measurement.
Ľahký spánok zabezpečí funkcia lightsleep()
z modulu machine, ktorej parametrom je čas spánku v
milisekundách.
Upozornenie
Počas ľahkého spánku sa môže prerušiť spojenie medzi zariadením a počítačom cez USB. Pri ladení si preto nastavte krátky interval merania.
Task
Odmerajte odber zariadenia v stave Sleep a spotrebu za
jeden cyklus a porovnajte ich s hodnotami v tabuľkách 1 a 2.
Okamžité prebudenie zariadenia z režimu spánku
Nie vždy je vhodné čakať, kým sa zariadenie zobudí automaticky po uplynutí nastaveného času. V niektorých situáciách potrebujeme možnosť prebudiť ho skôr – napríklad pri zásahu používateľa. Keďže naše zariadenie je vybavené tlačidlom, môžeme ho využiť práve na tento účel. Po stlačení tlačidla sa zariadenie prebudí a reštartuje, čím získame kontrolu nad jeho prebudením aj mimo plánovaného cyklu spánku.
V tomto kroku teda vytvoríte prerušenie na pine, ku ktorému je pripojené tlačidlo. Ak je zariadenie v režime spánku, vznik externého prerušenia spôsobí jeho okamžité prebudenie.
Funkcia, ktorá bude spracúvať vzniknuté prerušenie, môže byť prázdna – dôležité je, aby bola zavolaná. V opačnom prípade prerušenie nebude ošetrené a zariadenie sa neprebudí.
Externý časovač pomocou RTC modulu
Náš chytrý senzor nebude aktívny neustále – väčšinu času strávi v úspornom režime spánku, aby šetril energiu. Takéto správanie je typické pre zariadenia v rámci Internetu vecí, kde je dôležité, aby jednotlivé komponenty pracovali len vtedy, keď je to skutočne potrebné. Zo spánku sa môže zariadenie prebudiť dvoma spôsobmi: buď manuálne, stlačením tlačidla používateľom, alebo automaticky po uplynutí vopred nastaveného časového intervalu.
Ak budeme senzor uspávať vždy na konštantný čas, musíme počítať s tým, že jeho následné prebúdzanie sa bude postupne posúvať o dobu, počas ktorej senzor vykonáva meranie a spracovanie dát. Aj keď nejde o závažný problém, v niektorých prípadoch môže viesť k neželanej používateľskej skúsenosti.
Ak si napríklad používateľ nastaví, aby sa meranie vykonávalo vždy na celú hodinu, už po jednom dni môže byť začiatok merania posunutý o približne jednu minútu.
Na odstránenie tohto problému a zabezpečenie, aby sa merania vykonávali vždy v presne stanovených intervaloch, máme dve možnosti:
Pred uspaním zariadenia vypočítať presnú dĺžku času, počas ktorého má zostať v spánku. Týmto spôsobom môžeme zabezpečiť, že sa prebudí práve v okamihu, keď sa má začať ďalšie meranie.
Uspať zariadenie na neurčitý čas a prebudiť ho externým signálom v presne určenom okamihu. Na tento účel je možné použiť externý hodinový modul, ktorý dokáže generovať zobúdzací signál na svojom výstupnom pine. Tento signál môžeme pripojiť k vstupu mikrokontroléra, ktorý pri jeho aktivácii zariadenie zobudí podobne, ako v prípade stlačenia tlačidla. Takýmto modulom je napr. DS3231.
Poznámka
Zariadenie je možné uspať na neurčito a spoliehať sa na to, že bude pravidelne zobúdzané pomocou vhodného RTC modulu. Môže ale nastať situácia, kedy napr. RTC modulu dôjde baterka a tým pádom naše zariadenie nezobudí už nikdy.
Aby sme tomuto problému predišli, zariadenie v tomto stave neuspávajte na neurčito, ale napr. na dvojnásobný čas, ktorý je uvedený v konfigurácii. Tým pádom vymeškáte max. jedno meranie.
Strážny pes
Počas prevádzky môže zariadenie niekedy „uviaznuť“ – dostať sa do stavu, z ktorého sa nedokáže zotaviť bez zásahu používateľa. Typickým príkladom je nekonečná slučka, v ktorej sa zariadenie pokúša pripojiť k neexistujúcej WiFi sieti, alebo neošetrená výnimka, ktorá spôsobí, že zariadenie zostane „visieť“.
Aby sa dokázalo automaticky zotaviť z takýchto situácií, používame špeciálny časovač s názvom Watchdog Timer. Ak zariadenie uviazne, Watchdog ho po uplynutí nastaveného času automaticky reštartuje.
V tomto kroku vo vhodnom okamihu zapnite a správne nakonfigurujte Watchdog Timer, aby sa predišlo zaseknutiu zariadenia a zabezpečila sa jeho stabilná prevádzka.
Správa napájania
Na nasledujúcom obrázku sa nachádza časť schémy zapojenia vývojovej dosky RPi Pico 2, ktorá súvisí s napájaním.
Na základe tejto schémy je možné povedať nasledovné:
Pin VBUS je priamo pripojený k USB. Ak je doska napájaná z USB portu, je možné z pinu VBUS odoberať priamo napätie 5V.
Pomocou pinu WL_GPIO2 vieme jednoducho overiť, či je doska napájaná z USB portu. Ak sa na ňom nachádza hodnota
1, doska je napájaná z USB portu. Ak sa na ňom nachádza hodnota0, doska nie je napájaná z USB portu.vbus = Pin('WL_GPIO2', Pin.IN, Pin.PULL_DOWN) if vbus.value() == True: print('Device is USB Powered.') else: print('Device is battery powered.')Ak je doska napájaná z pinu VSYS, vďaka Schottkyho dióde sa toto napätie nedostane späť na USB port, čo by mohlo mať zlé následky.
Upozornenie
Nikdy nenapájajte dosku súčasne z USB portu aj z pinu VSYS!
Vstupné napätie je možné aj odmerať priamo pomocou komponentov dosky
bez nutnosti zostavenia vlastného napäťového deliča. Tým pádom je možné
monitorovať aj aktuálny stav napájania a v prípade potreby notifikovať
nutnosť jeho výmeny. Na tento účel je možné použiť štvrtý kanál ADC
(ADC3), ktorý je pripojený priamo k pinu GP29.
Na doskách s WiFi modulom to však nestačí. V oficiálnej
dokumentácii v kapitole
venovanej rozloženiu pinov, sa dočítame, že ak chceme zistiť hodnotu
napätia na pine VSYS, musíme na
pine GP25 nastaviť hodnotu
1. Po ukončení merania je zase potrebné vrátiť všetko do
pôvodného stavu.
Pre odmeranie napätia na pine VSYS je možné použiť nasledujúcu funkciu:
def measure_vsys():
# prepare pins
Pin(25, Pin.OUT, value=1)
Pin(29, Pin.IN, pull=None)
# read and convert value
value = ADC(3).read_u16() * 3 * 3.3 / 2**16
# restore original state of pins
Pin(29, Pin.ALT, pull=Pin.PULL_DOWN, alt=7)
Pin(25, Pin.OUT, value=0, pull=Pin.PULL_DOWN)
return valuePred odchodom z cvičenia…
Upozornenie
Ak máte dosku RPi Pico 2 WH požičanú od cvičiaceho, pred odchodom z cvičenia prosím:
- Uložte si kód, ktorý ste na cvičení vytvorili.
- Zmažte obsah Flash pamäte mikrokontroléra nahratím firmvéru flash_nuke.uf2. Pozor! Mikrokontrolér neodpájajte od počítača, kým sa vo vašom počítači znova neobjaví ako USB zariadenie.
- Nahrajte na mikrokontrolér najnovší firmvér.
Ďalšie úlohy
- V prípade akýchkoľvek problémov nezabudnite prejsť do stavu
Errora reprezentovať vzniknutú chybu potrebným blikaním.
Ďalšie zdroje
Hackaday.io: Review 016: UM24 USB Meter
MicroPython Chapters: Časovač Watchdog
MicroPython: Quick reference for the RP2: General board control
MicroPython Chapters: Zmena frekvencie zariadenia
Last Minute Engineers: Interface DS3231 Precision RTC Module with Arduino
Random Nerd Tutorials: Raspberry Pi Pico: DS3231 RTC (Real-Time Clock) – Get Time and Set Alarms (MicroPython)
Workbench Wednesdays: Measuring the Raspberry Pi Pico W’s Power Consumption
Power for the Raspberry Pi Pico - Guide to using VBUS, VSYS and 3V3 for external power circuits