Internet Rzeczy w pomiarach środowiskowych (20). Obsługa czujnika BME688 w języku C++ z użyciem rdzenia RISC-V procesora RP2350

Internet Rzeczy w pomiarach środowiskowych (20). Obsługa czujnika BME688 w języku C++ z użyciem rdzenia RISC-V procesora RP2350

Autonomiczne układy wymagają optymalnego zarządzania pobieraną mocą zasilania. Przy typowej organizacji pracy, polegającej na wykonaniu odczytu z czujników i jego przetwarzaniu co pewien czas, optymalnym rozwiązaniem jest wyłączanie (w czasie oczekiwania na następny pomiar) wszystkich nieużywanych elementów, w tym wielu modułów procesora. Bardzo dobrze nadaje się do tego celu procesor RP2350 firmy Raspberry Pi.

Podziękowania dla Pana Macieja Michny z Centrum Badań i Rozwoju Nordic Semiconductor w Krakowie za udostępnienie zestawów sprzętowych Power Profiler Kit II (PPK2).

Celem projektu było opracowanie autonomicznego i energooszczędnego systemu badania stężenia dymu w celu wykrywania pożaru. Wyniki pomiarów powinny być wyświetlane w sposób czytelny na wyświetlaczu typu e-Paper. Projekt obejmuje opracowanie układu wykrywania dymu bazującego na czujniku BME688, z oprogramowaniem napisanym w języku C/C++ i działającym na rdzeniu RISC-V mikrokontrolera RP2350, umieszczonego na płytce Raspberry Pi Pico 2.

W ramach projektu została zastosowana dwuwarstwowa, sztuczna sieć neuronowa, analizująca na wejściu cztery ostatnie próbki, odczytane z czujnika BME688. Sieć stwierdza, czy w pomieszczeniu wykryto pożar. Model wytrenowany został na danych pozyskanych przez ręczne umieszczenie ognia w pobliżu czujnika dymu i rejestrację jego wpływu na odczyty sensora.

Rdzeń RISC-V Hazard3

Rdzeń RISC-V Hazard3 [13] zawiera trójstopniowy procesor potokowy o architekturze obsługującej listę instrukcji RV32IMAC z dodatkowymi rozszerzeniami: Zba – instrukcje generowania adresów (indeksowania), Zbb, Zbs, Zbkb – operacje bitowe, Zcb – rozszerzony zestaw instrukcji 16-bitowych, Zcmp – push/pop i podwójne przesłania, Zicsr – dostęp do rejestrów sterujących oraz Hh3power, Xh3bextm – własne instrukcje rdzenia Hazard3. Sterownik przerwań użyty w rdzeniu ma funkcjonalność równoważną z ARM NVIC.

Płytka RPi Pico2 firmy Raspberry Pi

Nowe płytki Pico2 i Pico 2W firmy Raspberry Pi z procesorem RP2350 są zgodne pod względem elektrycznym z płytkami Pico pierwszej serii (Pico/Pico W) [7]. Na płytkach zostały zastosowane układy pamięci NOR Flash z serii W25Q (Winbond) o częstotliwości pracy do 133 MHz (przepustowość do 66 MB/s) [15]. Dokładny opis został zamieszczony w artykule „Płytka Raspberry Pi Pico 2/2W z procesorem RP2350” [17].

Płytka Pico 2 zawiera przetwornicę buck-boost, która dostarcza napięcie 3,3 V (do zasilania RP2350 i obwodów zewnętrznych) z szerokiego zakresu napięć wejściowych (od 1,8 do 5,5 V), co zapewnia znaczną elastyczność w zasilaniu urządzenia z różnych źródeł, takich jak pojedyncze ogniwo litowo-jonowe lub 3 ogniwa AA połączone szeregowo. Najprostszym sposobem zasilania Pico 2 jest skorzystanie z umieszczonego na płytce gniazdka Micro USB. W dokumentacji płytki pokazano ponadto, jak poprzez dodanie tranzystora MOS można zrealizować podtrzymanie bateryjne zasilania płytki [13].

Środowisko uruchomieniowe

Do realizacji projektu użyto środowiska uruchomieniowego bazującego na Microsoft Visual Studio Code. Po jego zainstalowaniu i uruchomieniu należy zainstalować rozszerzenie Raspberry Pi Pico. Po poprawnej instalacji w pasku bocznym pojawi się ikona Raspberry Pi Pico Project.

Wbudowane oprogramowanie płytki Pico umożliwia łatwe ładowanie kodu do pamięci mikrokontrolera. Oprogramowanie do załadowania ma postać pliku w formacie UF2.

Do debugowania oprogramowania niezbędny jest odpowiedni interfejs; można w tym celu użyć drugiej płytki Pico, ładując do niej oprogramowanie interfejsu debugowania, dostępne w postaci gotowego pliku UF2. Użycie RPi Pico do debugowania innego modułu Pico 2 wymaga wykonania połączeń zgodnie ze schematem zamieszczonym w dokumentacji [16]. Zastosowanie na płytce Pico/Pico2 diody pomiędzy szyną VBUS i VSYS umożliwia jednoczesne dołączenie kabli USB do płytki Pico2 oraz płytki pracującej jako debuger.

Mikrokontrolery serii RP235x, używane w Pico 2, umożliwiają wybór jednego z dwóch typów rdzeni procesora podczas inicjalizacji oprogramowania. Aktywacja rdzenia jest wykonywana przez wbudowane oprogramowanie mikrokontrolera, zawarte w jego pamięci stałej, na podstawie informacji odczytanej z zewnętrznej pamięci Flash. Interfejs debugowania komunikuje się wyłącznie z aktywnym rdzeniem procesora.

Aktualnie dostępne oprogramowanie narzędziowe nie umożliwia późniejszej zmiany aktywnego rdzenia w trakcie pracy modułu, np. przy użyciu interfejsu debugowania. Oznacza to, że jedyną aktualnie dostępną metodą zmiany aktywnego rdzenia (ARM Cortex-M33/RISC-V Hazard) jest załadowanie (w trybie bootowania) dowolnego pliku UF2, zawierającego oprogramowanie działające na wybranym rdzeniu. Oprogramowanie to nie musi nawet poprawnie działać, istotny jest jedynie sam fakt załadowania go do pamięci.

Aktualny wybór aktywnego rdzenia może zostać odczytany z płytki w trybie bootowania przy użyciu narzędzia picotool.

SDK (Software Development Kit) to kolekcja narzędzi i kodu źródłowego do interakcji z zasobami sprzętowymi mikrokontrolera. Jest ona instalowana przez rozszerzenie Raspberry Pi Pico. Przy tworzeniu pierwszego projektu na architekturę RISC-V następuje dosyć czasochłonna instalacja oprogramowania narzędziowego do obsługi tego rdzenia.

Po skompilowaniu projektu należy załadować go w trybie bootowania, używając ikony Run w dolnym pasku. Jest to niezbędne, jeśli uprzednio na płytce działało oprogramowanie korzystające z rdzenia Cortex-M. Tylko w ten sposób następuje aktywowanie rdzeni RISC-V, co stanowi warunek konieczny do późniejszego podłączenia debuggera do tych rdzeni. Przy kolejnych poprawkach projektu można używać funkcji debugowania, bez wprowadzania mikrokontrolera w tryb bootowania.

Debugowanie RISC-V uruchamiamy używając konfiguracji Pico Debug (Cortex-Debug).

Debugger używany przez rozszerzenie Raspberry Pi Pico nie umożliwia wyświetlania zawartości rejestrów ani deasemblacji kodu maszynowego procesora RISC-V. Jest możliwe jedynie debugowanie na poziomie kodu źródłowego C. Pełne debugowanie RISC-V wymaga zainstalowania i skonfigurowania debuggera gdb dla RISC-V.

Czujnik BME688

Czujnik BME688 firmy Bosch [9], służący do detekcji temperatury, wilgotności, ciśnienia oraz stężeń VOC i VSC, skalibrowany został w trybie forced, zgodnie z przykładami dostarczonymi przez producenta na stronie biblioteki. Biblioteka ta została użyta w celu komunikacji z czujnikiem.

Wyświetlacz E-Ink

Wyświetlacz Pico-Inky firmy Pimoroni [8] skonfigurowany został z wykorzystaniem SDK dostarczonego przez producenta [3]. Ze względu na skąpą dokumentację, w celu połączenia z mikrokontrolerem konieczne było zapoznanie się z dostarczonym przez producenta kodem źródłowym pakietu picographics [4] w języku MicroPython. Dzięki temu odkryto, że w przypadku wyświetlacza Pico-Inky konieczne jest skorzystanie ze sterownika układu UC8151 oraz interfejsu SPI. Znaleziono również informację o rozmiarze bufora ramki dla tego wyświetlacza. Opracowana metoda obsługi wyświetlacza e-Ink znajduje się w pliku src/fire_detector/logger/pico_inky_logging_resource.cpp.

Podłączenie peryferiów

Czujnik BME688 [1] został dołączony do interfejsu I2C0 mikrokontrolera, dostępnego na liniach portów GPIO4 (SDA) i GPIO5 (SCL). Wyświetlacz Pico-Inky dołączono do interfejsu SPI0 (linie GPIO17 (CS), GPIO18 (SCK), GPIO19 (MOSI) i GPIO20 (DC)) [8]. Do monitorowania działania oprogramowania można użyć interfejsu UART0 na liniach GPIO0 (TX) i GPIO1 (RX), łącząc go z szyną UART na płytce interfejsu debugowania, udostępnianą po stronie komputera PC jako wirtualny port szeregowy [2]. W przypadku niekorzystania z debuggera, w projekcie w pliku src/main.cpp należy zainicjalizować zmienną s_Logger wartością nullptr (15 linijka) oraz usunąć zmienną s_UartResource w celu zmniejszenia nakładu obliczeniowego potrzebnego do formatowania tekstów, wypisywanych przez oprogramowanie debuggera.

Struktura projektu

Projekt został podzielony na kilka mniejszych modułów. Na rysunku 1 pokazano strukturę katalogu plików źródłowych src. Wszystkie te pliki, z wyłączeniem main.cpp, mają własne pliki nagłówkowe, które znajdują się w katalogu include. W projekcie nie ma plików nagłówkowych nieposiadających mapowania na pliki źródłowe.


Rysunek 1. Organizacja plików źródłowych w projekcie [18]

W następujących plikach zostały zawarte funkcjonalności (rysunek 1):

  • BME688 (hpp/cpp) – wrapper biblioteki dostarczonej przez producenta [1], służącej do komunikacji z czujnikiem BME688 [9]. Implementuje w pełni komunikację za pomocą protokołu I²C,
  • logger (hpp/cpp) – zawiera interfejs loggera oraz zasobu logującego. Z założenia logger jest uchwytem do zasobu logującego, co pozwala korzystać z różnych loggerów naraz, w różnych miejscach kodu,
  • pico_inky_logging_resource (hpp/cpp) – zawiera implementację zasobu logującego, wypisującego informacje na ekranie Pico-Inky,
  • uart_logging_resource (hpp/cpp) – zawiera implementację zasobu logującego, wysyłającego dane na wskazany port UART,
  • classifier – zawiera implementację bezstanowego klasyfikatora, wskazującego obecność dymu,
  • fire_detector_logic (hpp/cpp) – zawiera implementację całego klasyfikatora, łącznie z elementem przechowującym stan klasyfikatora oraz kwantowaniem danych,
  • power_manager (hpp/cpp) – zawiera managera pozwalającego na sterowanie domenami poboru mocy mikrokontrolera, umożliwia też planowanie ponownego włączenia mikrokontrolera,
  • main (cpp) – punkt wejściowy programu, mający zdefiniowane stałe oraz wykonujący pomiary.

Oprócz tego w projekcie znajduje się katalog cmake, w którym zdefiniowano plik cmake, służący do włączenia biblioteki BME68x [1] do projektu.

Uruchomienie rozwiązania

W opisywanym projekcie zastosowano narzędzie pico tool w wersji 2.1.0. W przypadku nowszych edycji może pojawić się potrzeba modyfikacji tej komendy, a także zainstalowania SDK raspberry pico, programu cmake oraz programu ninja, jeżeli nie były one zainstalowane wcześniej.

W celu uruchomienia projektu należy na początku pobrać projekt z repozytorium  https://ep.com.pl/files/hjw/13746-internet_rzeczy_w_pomiarach_srodowiskowych_20.zip. Następnie należy zdecydować, czy potrzebne jest wysyłanie danych diagnostycznych poprzez port UART0. Jeżeli nie, to należy usunąć definicję UartLoggingResource, znajdującą się w linijce 13 pliku main.cpp oraz zainicjować zmienną s_Logger wartością nullptr.

Następnie należy skonfigurować projekt komendą:

cmake -S . -B build -G Ninja
Uwaga! Zadeklarowanie zmiennej środowiskowej PICO_SDK_PATH może być konieczne, jeżeli SDK Pico nie zostało zainstalowane w domyślnym katalogu.

Następnie można zbudować projekt za pomocą komendy:

ninja -C build -j X

gdzie X oznacza przydzieloną liczbę wątków.

Skompilowany program można wpisać płytkę za pomocą komendy:

sudo $PICO_SDK_PATH/picotool/2.1.0/picotool/picotool load $PWD/build/project_riscv.elf -fx

Architektura klasyfikatora dymu

Klasyfikator jest siecią neuronową (rysunek 2) złożoną z warstwy wejściowej (17 wejść), warstwy neuronów ukrytych (4 neurony) i jednego neuronu w warstwie wyjściowej. W warstwie ukrytej używana jest funkcja aktywacji LeakyReLU (o nachyleniu dla ujemnych wartości wejściowych równym 0,2). Funkcją aktywacji neuronu wyjściowego jest funkcja sigmoidalna.

Rysunek 2. Struktura sieci neuronowej służącej do wykrywania dymu w pomieszczeniu [18]

Na wejścia podawane są cztery ostatnie wartości pomiarów temperatury, ciśnienia, VOC oraz ostatniej predykcji modelu. Model dokonuje oceny, czy obecnie w pomieszczeniu znajduje się ogień.

Sieć została wytrenowana na wygenerowanych danych (z dodanym szumem w celu uniknięcia przeuczenia), których charakterystyka odpowiada danym zarejestrowanym przez czujnik. Zbiór treningowy zawierał 100 000 próbek. Proces uczenia ograniczono do 5 epok. Trening przeprowadzono za pomocą zestawu skryptów w języku Python, zawartych w pliku fire_detection.ipynb (https://ep.com.pl/files/aww/13747-fire_detection.zip), który można wczytać i uruchomić w środowisku Jupyter Notebook (np. na platformie cocalc.com). Do trenowania modelu skrypty korzystają z bibliotek Pytorch [5] oraz Lightning [6].

Podczas procesu trenowania monitorowano metrykę straty na zbiorze treningowym. Potwierdzono, że model osiągnął zbieżność oraz że jego uczenie nie jest zbyt stabilne, co jest częstym problemem płytkich modeli. Wagi modelu można wyświetlić instrukcją:

for param in model.parameters(): print(param.data)

Klasyfikacja w programie mikrokontrolera została zaimplementowana w pliku src/fire_detector/logic/classifier.cpp. Wagi obliczone z użyciem skryptów w języku Python zostały umieszczone w tablicach kFirstLayerWeightMatrix, kFirstLayerBiasMatrix, kSecondLayerWeightMatrix, oraz kSecondLayerBias.

Kwantyzacja danych pomiarowych

Dane otrzymane z czujnika zostały skwantowane tak, aby zmieściły się w 256-bitowej strukturze. Jest to ważne ze względu na optymalizację zużycia prądu. Zapisywane są trzy ostatnie pomiary oraz wartość ostatniej predykcji. Poniżej zaprezentowano sposoby kwantowania wartości:

  • Temperatura (pomnożona przez 100) zapisywana jest jako wartość typu int16.
  • Wilgotność (pomnożona przez 100) zapisywana jest jako wartość typu uint16.
  • Wynik pomiaru VOC zapisywany jest jako wartość typu uint32.
  • Ciśnienie zapisywane jest jako wartość typu uint32.
  • Ostatnia wartość predykcji zapisywana jest jako jeden bit: 1 – wystąpił ogień, 0 – brak ognia.

Skwantowane pomiary trafiają do struktury FireDetectorMemory zadeklarowanej w pliku src/fire_detector/fire_detector_logic.cpp i mają postać pokazaną na rysunku 3.

Rysunek 3. Alokacja przestrzeni w rejestrze przechowującym dane pomiarowe [18]

Optymalizacja poboru mocy

W celu minimalizacji poboru mocy wykorzystano najnowszy dodatek SDK RP2350, czyli bibliotekę Powman [11]. Umożliwia ona sterowanie domenami zasilania RP2350, które pokazano na rysunku 4. Zawsze aktywna jest domena AON (Always on Power Domain). Zawiera ona zegar o rozdzielczości milisekundowej, pozwalający na zaplanowany powrót do starej domeny. Umożliwia ona również na budzenie urządzenia w przypadku wystąpienia zdarzenia zewnętrznego, np. sygnału na GPIO. Wyższe domeny kontrolują wykorzystanie rdzeni procesora (SWCORE), pamięci SRAM boota (XIP) oraz głównych pamięci SRAM (SRAM0 i SRAM1). Biblioteka Powman pozwala zatem całkowicie wyłączyć urządzenie i zaplanować jego ponowne uruchomienie. Wadą tego rozwiązania jest całkowity restart programu oraz wymazanie wszystkich zmiennych w pamięci (w przypadku wyłączenia pamięci SRAM). Domena AON dostarcza również 256-bitowy rejestr scratch [12], pozwalający na przechowywanie danych ulotnych bez względu na stan zasilania rdzenia. Dzięki kwantyzacji trzy ostatnie pomiary mieszczą się w tym rejestrze, przez co możliwe jest całkowite wyłączenie procesora RP2350 w momencie oczekiwania na kolejny pomiar. Za zarządzanie domenami odpowiada klasa zaimplementowana w pliku źródłowym src/fire_detector/power/power_manager.cpp, gdzie znajduje się ponadto kod wyłączający port USB i obsługujący inne optymalizacje. Domeny zasilania opisane zostały w sekcji 6.2 dokumentacji mikrokontrolera RP2350 [13]. Przykładowe użycie biblioteki Powman zostało dokładnie opisane w repozytorium [14].

Rysunek 4. Domeny zasilania mikrokontrolera RP2350 [13]

Badania

W ramach projektu została przetestowana detekcja ognia z użyciem opracowanego programu. Pomiary były wykonywane co sekundę. Układ prawidłowo wykrywał dym (fotografia tytułowa). Dzięki zastosowaniu klasyfikatora neuronowego oraz okna historii układ potrafił szybciej wykryć zgaszenie ognia, gdyż brał również pod uwagę zmianę wartości w czasie. Choć po usunięciu źródła dymu poziom oporu gazu nie wzrósł gwałtownie (bez ognia wynosił około 120 000) oraz temperatura nie zdążyła powrócić do normy, model był w stanie wykryć koniec symulowanego pożaru.

Pobór mocy

Do dynamicznego pomiaru prądu zasilania bardzo dobrze nadaje się zestaw Power Profiler Kit II (PPK2) firmy Nordic Semiconductor. Do badań został zastosowany PPK2 w trybie zasilania, z napięciem 5 V dołączonym do szyny VSYS. System wykonywał pomiar i aktualizację wyświetlania co 1,316 s, prąd średni wynosił 9,62 mA (rysunek 5). Na początku ramki wykonywane są obliczenia, a potem realizowany jest pomiar za pomocą czujnika BME688: czas ok. 100 ms, prąd średni 13,79 mA, prąd maksymalny 37,91 mA (szpilka i narastająca rampa).

Rysunek 5. Profil poboru prądu

Następnie wykonywane są obliczenia (prąd średni ok. 11,23 mA) i układ RP2350 wchodzi w stan uśpienia: czas ok. 91 ms, prąd średni 3,39 mA, prąd maksymalny 22,38 mA (rysunek 6). Przetwornica doładowuje kondensatory wyjściowe rzadko wykonywanymi szpilkami prądowymi. Układ zostaje wyłączony i domena AON ma za zadanie wybudzić układ po upływie określonego czasu.

Rysunek 6. Wprowadzanie układu RP2350 w uśpienie

Dzięki zastosowaniu biblioteki Powman, przy zasilaniu szyny VSYS napięciem 3,3 V, w okresie uśpienia procesora udało się zejść z zużyciem prądu do średnio 107,25 μA, z rzadkimi pikami do ok. 20 mA (rysunek 7).

Rysunek 7. Prąd podczas uśpienia procesora [18]

Podczas włączania zasilania płytki Pico 2 występuje – przez 0,88 ms – prąd rozruchowy o maksymalnej wartości 0,63 A. Może to stwarzać problemy dla źródeł zasilania małej mocy (np. odnawialnych).

Możliwości kontynuacji

Model do działania potrzebuje często wykonywanych odczytów czujnika, co wymusiło wybór próbkowania co jedną sekundę. Patrząc na zużycie energii można by się pokusić o wydłużenie odstępu między pomiarami, jednakże w tym przypadku niszczyłoby to responsywność modelu. W przypadku nowej implementacji źródło, do którego logika klasyfikatora zapisuje dane, może zostać wyciągnięte do osobnej klasy definiowanej interfejsem, dzięki czemu implementacja klasyfikatora oraz miejsce zapisywania danych zostałyby od siebie oddzielone.

Podsumowanie

Czujnik parametrów środowiska BME688 dobrze nadaje się do wykrywania dymu, szczególnie pojawiającego się w wyniku pożaru. Przy stosunkowo niedużym zapotrzebowaniu na moc zasilania, można go zastosować do budowy układów działających długo z zasilaniem lokalnym. Przy sporych odstępach czasu oczekiwania na następny pomiar, pojawia się konieczność ograniczenia poboru mocy przez procesor. Biblioteka Powman w języku C++ dla procesora RP2350 pozwala na dynamiczne zarządzanie domenami zasilania procesora. Umożliwia to skonfigurowanie stanu uśpienia z niskim poborem prądu.

Opisany projekt spełnił oczekiwania. Udało się zrealizować detekcję dymu i osiągnąć niski poziom mocy zasilania. Dodatkowo został zastosowany rdzeń RISC-V, który nabiera coraz większego znaczenia na rynku systemów wbudowanych i Internetu Rzeczy. Jest to pierwsze podejście do tego zagadnienia, więc wymagane są dalsze badania, szczególnie dotyczące zastosowanej sieci neuronowej.

Opis i realizacja oprogramowania bazuje na projekcie „Praca rdzeni RISC-V płytki Raspberry Pi Pico 2”, wykonanego w ramach przedmiotu „Systemy dla Internetu Rzeczy” na Wydziale Elektroniki i Technik Informacyjnych Politechniki Warszawskiej przez zespół w składzie: Grzegorz Czarnecki, Jakub Sprawka, Kamil Sulkowski.

Autorzy dziękują Panu Zbigniewowi Szymańskiemu za wsparcie w dziedzinie sztucznej inteligencji.

Henryk A. Kowalski
Grzegorz Mazur
Instytut Informatyki
Politechnika Warszawska

Bibliografia:
[1] BME688 breakout board Bosch air quality sensor, Python Library for BME68x on the Raspberry Pi, pi3g, https://pi3g.com/products/bme688-breakout-board/
[2] Pico 2 family, Raspberry Pi Pico 2, https://www.raspberrypi.com/documentation/microcontrollers/pico-series.html#pico-2-family
[3] Pimoroni Pico MicroPython for RP2350/Pico2 boards, https://github.com/pimoroni/pimoroni-pico-rp2350
[4] Pico Graphics, Pimoroni, https://github.com/pimoroni/pimoroni-pico/tree/main/micropython/modules/picographics
[5] Pytorch, https://pytorch.org/
[6] PyTorch Lightning, https://lightning.ai/docs/pytorch/stable/
[7] Raspberry Pi Pico 2, https://www.raspberrypi.com/products/raspberry-pi-pico-2/
[8] Pico Inky Pack, PIM634, Pimoroni, https://shop.pimoroni.com/products/pico-inky-pack?variant=40044626051155
[9] Bosch gas sensor BME688, https://www.bosch-sensortec.com/products/environmental-sensors/gas-sensors/bme688/#documents
[10] Profilowanie mocy z zastosowaniem Power Profiler Kit II, Henryk A. Kowalski, EP 5/2022, https://ep.com.pl/kursy/15267-systemy-dla-internetu-rzeczy-60-profilowanie-mocy-z-zastosowaniem-power-profiler-kit-ii
[11] Pico C SDK, Power Management API, hardware_powman, RP2350, Raspberry Pi, https://www.raspberrypi.com/documentation/pico-sdk/hardware.html#group_hardware_powman
[12] powman.h, “io_rw_32 scratch[8];”, Raspberry Pi, https://github.com/raspberrypi/pico-sdk/blob/95ea6acad131124694cda1c162c52cd30e0aece0/src/rp2350/hardware_structs/include/hardware/structs/powman.h#L293
[13] RP2350 Datasheet, 2024-10-16, Raspberry Pi, https://datasheets.raspberrypi.com/rp2350/rp2350-datasheet.pdf
[14] raspberrypi/pico-examples, https://github.com/raspberrypi/pico-examples/compare/master...peterharperuk:pico-examples:powman
[15] Raspberry Pi Pico 2 Datasheet, 2024-10-15, Raspberry Pi, https://datasheets.raspberrypi.com/pico/pico-2-datasheet.pdf
[16] Getting Started with Pico-series Microcontrollers. 2024-10-15, Raspberry Pi, https://datasheets.raspberrypi.com/pico/getting-started-with-pico.pdf
[17] Płytka Raspberry Pi Pico 2/2W z procesorem RP2350, Henryk A. Kowalski, EP 3/2025, https://ep.com.pl/projekty/moduly-w-aplikacjach/16453-internet-rzeczy-w-pomiarach-srodowiskowych-15-plytka-raspberry-pi-pico-2-2w-z-procesorem-rp2350
[18] „Praca rdzeni Risc-V płytki Raspberry Pi Pico 2”, Grzegorz Czarnecki, Jakub Sprawka, Kamil Sulkowski, Raport projektu, Wydział Elektroniki i Technik Informacyjnych Politechniki Warszawskiej

Artykuł ukazał się w
Elektronika Praktyczna
sierpień 2025
Elektronika Praktyczna Plus lipiec - grudzień 2012

Elektronika Praktyczna Plus

Monograficzne wydania specjalne

Elektronik listopad 2025

Elektronik

Magazyn elektroniki profesjonalnej

Raspberry Pi 2015

Raspberry Pi

Wykorzystaj wszystkie możliwości wyjątkowego minikomputera

Świat Radio listopad - grudzień 2025

Świat Radio

Magazyn krótkofalowców i amatorów CB

Automatyka, Podzespoły, Aplikacje listopad - grudzień 2025

Automatyka, Podzespoły, Aplikacje

Technika i rynek systemów automatyki

Elektronika Praktyczna grudzień 2025

Elektronika Praktyczna

Międzynarodowy magazyn elektroników konstruktorów

Elektronika dla Wszystkich grudzień 2025

Elektronika dla Wszystkich

Interesująca elektronika dla pasjonatów