Programowanie w środowisku MicroPython (7). Dostęp do Wi-Fi

Programowanie w środowisku MicroPython (7). Dostęp do Wi-Fi

Łączność bezprzewodowa to jedna z najważniejszych funkcji (a także zalet) modułów ESP32. Mamy do dyspozycji Wi-Fi, Bluetooth oraz ESP-NOW. W dzisiejszym odcinku zobaczymy, jak wyszukiwać sieci Wi-Fi, a następnie połączymy się z Internetem w celu pobrania aktualnej godziny oraz plików.

W poprzednich odcinkach najpierw omawialiśmy różne moduły MicroPythona oraz klasy w nim udostępnione, a dopiero po wstępie teoretycznym pokazywaliśmy przykłady praktyczne. Moduły związane z Wi-Fi są tak rozbudowane, że na ich temat można by napisać książkę, a nie odcinek kursu do czasopisma. Dlatego tym razem przejdziemy od razu do praktycznych przykładów, które pokażą, jak można zrealizować pewne typowe czynności.

Wyszukiwanie sieci Wi-Fi

Weźmy pod lupę kod przedstawiony na listingu 1. Jego zadaniem jest wykrycie wszystkich sieci Wi-Fi dostępnych w pobliżu i wyświetlenie ich na konsoli w formie tabelki.

# Plik wifi_scan.py
import network # 1

station = network.WLAN(network.STA_IF) # 2
station.active(True) # 3
nets = station.scan() # 4

counter = 0 # 5
authmodes = ["Open", "WEP", "WPA", "WPA2", # 6
"WPA/WPA2", "WPA2-Ent", "WPA3",
"WPA2/WPA3", "WAPI”, "OWE"]

print("Nr | Channel | RSSI | Security | Hidden | SSID") # 7
for net in nets: # 8
print(f"{counter:2d} | {net[2]:7d} | {net[3]:4d} | # 9
{authmodes[net[4]]:9s} | {net[5]:6d} | {net[0]:s}")
counter += 1

Listing 1. Kod pliku wifi_scan.py

Aby wykonywać jakiekolwiek operacje związane z Wi-Fi, najpierw musimy zaimportować moduł network (linia 1). Następnie trzeba utworzyć instancję klasy WLAN, co czynimy w linii 2. W zależności od zastosowanego argumentu konstruktora tej klasy, możliwe są dwa tryby pracy:

  • network.STA_IF – ESP32 łączy się z istniejącym access pointem, który wskażemy w kolejnych liniach, podobnie jak łączą się z nim komputery, smartfony, itp. W taki sposób możemy uzyskać dostęp do Internetu.
  • network.AP_IF – ESP32 tworzy swój własny access point, do którego mogą podłączyć się inne urządzenia. W tym trybie pracy możemy stworzyć własny serwer HTTP i DNS, aby generować strony WWW, które mogą być przeglądane na komputerze lub smartfonie. Omówimy ten temat w przyszłości.

Następnie w linii 3 musimy uaktywnić naszą klasę, po czym wywołujemy metodę scan (linia 4). Ta metoda zwraca listę krotek, po jednej na każdą znalezioną sieć. Każda krótka składa się z następujących danych:

  • nazwy sieci (SSID),
  • BSSID, czyli hardware’owej nazwy sieci,
  • numeru kanału,
  • RSSI, czyli wartości mocy sygnału,
  • rodzaju zabezpieczeń,
  • informacji o tym, czy sieć jest ukryta.

Tak otrzymaną listę zapisujemy do zmiennej nets. Jak zapewne się spodziewasz, reszta programu służy jedynie do zdekodowania i wyświetlenia otrzymanych informacji w formie zrozumiałej dla człowieka. Każdą sieć oraz odpowiadające jej informacje wyświetlimy w osobnych liniach.

W linii 5 tworzymy zmienną, która będzie przydatna do wyświetlania liczby porządkowej, a następnie budujemy listę authmodes, która ma służyć do przekształcenia numeru zabezpieczenia na zrozumiały komunikat. „Open” oznacza, że każdy może połączyć się z daną siecią bez podawania hasła.

W linii 7 wyświetlamy nagłówek tabeli, a następnie rozpoczynamy pętlę, która iteruje po wszystkich elementach listy nets. W każdym obiegu pętli wyświetlamy informacje z kolejnej krotki (linia 9), po czym inkrementujemy licznik counter.

Uruchamiamy kod klawiszem F5. Efekt skanowania sieci widzimy na rysunku 1.

Rysunek 1. Efekt skanowania sieci Wi-Fi

Czas NTP

W tym przykładzie zobaczymy, jak można połączyć się z siecią Wi-Fi oraz jak pobrać aktualny czas z serwera NTP. Najpierw jednak poznamy prostą sztuczkę pozwalającą bezpiecznie przechowywać nazwę sieci SSID oraz hasło, aby przypadkiem nie opublikować jej na GitHubie czy w inny sposób. Zobacz kod pokazany na listingu 2. Jest to plik Wi-Fi_config.py, który składa się tylko z dwóch linijek. Musimy ten plik przegrać do pamięci ESP32, a następnie zapisać w nim nazwę sieci oraz hasło. W ten sposób wrażliwe dane przechowujesz tylko w pamięci wewnętrznej ESP32, a na dysku w komputerze pozostaje plik z pustymi zmiennymi, niczym szablon gotowy do wypełnienia.

# Plik config.py
ssid = ""
password = ""

Listing 2. Kod pliku config.py

Możemy teraz przejść do analizy pliku sync_ntp_time.py, którego kod znajduje się na listingu 3. Na początku, jak zawsze, importujemy potrzebne moduły, w tym również moduł Wi-Fi_config zawierający nazwę i hasło do sieci Wi-Fi (linia 1).

# MicroPython 1.24.1 ESP32-S3 Octal SPIRAM

import network
import ntptime
import time
import wifi_config # 1

def wifi_connect(): # 2
station = network.WLAN(network.STA_IF)
station.active(True)
if not station.isconnected(): # 3
print("Łączenie z siecią", end="")
station.connect(wifi_config.ssid, wifi_config.password) # 4
while not station.isconnected(): # 5
print(".", end="")
time.sleep_ms(250)
print()

print(f"Adres IP: {station.ifconfig()[0]}") # 6

def print_system_time(): # 7
Y, M, D, h, m, s, w, _ = time.localtime()
days = ["Poniedziałek", "Wtorek", "Środa", "Czwartek",
"Piątek", "Sobota", "Niedziela"]
print(f"{Y}.{M:02}.{D:02} {h:02}:{m:02}:{s:02} {days[w]}")

print("Czas przed synchronizacją: ", end="") # 8
print_system_time()
wifi_connect() # 9
ntptime.settime() # 10
print("Czas po synchronizacji: ", end="")
print_system_time()

Listing 3. Kod pliku sync_ntp_time.py

W linii 2 definiujemy funkcję Wi-Fi_connect, której celem jest nawiązanie połączenia z siecią Wi-Fi. Pierwsze dwie linie są identyczne, jak w poprzednim przykładzie. W linii 3 sprawdzamy czy połączenie z siecią już zostało nawiązane, aby uniknąć próby powiązania z access pointem, do którego jesteśmy już podłączeni. W linii 4 wywołujemy metodę connect, do której przekazujemy nazwę i hasło sieci, odczytane z modułu Wi-Fi_config.

Łączenie z siecią trwa kilka sekund. Aby pokazać na konsoli proces łączenia, w linii 5 mamy pętlę while, która wykonuje się tak długo, aż metoda isconnected() zwróci True. Jeżeli zwróci False, wówczas na konsoli wyświetlamy kropkę i czekamy 250 ms przed kolejnym sprawdzeniem. Finalnie, kiedy jesteśmy już połączeni z siecią Wi-Fi, możemy wyświetlić adres IP, jaki został nam przydzielony.

W linii 7 mamy funkcję wyświetlającą aktualny czas systemowy. Była ona omówiona w 3 odcinku kursu, opublikowanym w EP 07/2025.

Przechodzimy wreszcie do właściwego programu. W linii 8 wyświetlamy czas, jaki aktualnie jest ustawiony w mikrokontrolerze. W tym momencie jeszcze nie mamy połączenia z siecią, a czas jaki nam się ukaże, pochodzi z programu Thonny. Jeżeli synchronizacja czasu z Thonny jest wyłączona w ustawieniach, zamiast właściwej godziny zobaczymy odczyt: 00:00 w dniu 1 stycznia 2000 r.

W linii 9 wywołujemy funkcje: Wi-Fi_connect, a następnie settime z modułu ntptime. Funkcja pobierze aktualny czas i zapisze w systemie, po czym ponownie wyświetlimy czas systemowy, aby zobaczyć, że nasz program pracuje prawidłowo. Efekt działania tego kodu pokazuje rysunek 2.

Rysunek 2. Efekt synchronizacji czasu z NTP

Zwróć uwagę na to, że pobrany z serwera czas nie uwzględnia naszej strefy czasowej ani czasu letniego/zimowego. Musimy o to zadbać sami.

Ściąganie plików

Kolejny praktyczny przykład to pobieranie plików z Internetu. Opisaną poniżej metodę można wykorzystać do pobierania nie tylko plików HTML, ale także dowolnych danych zupełnie innego typu. Nic nie stoi na przeszkodzie, by były to pliki Pythona pobrane z GitHuba. Czy widzisz już, jaką funkcjonalność możemy zrobić? Bardzo łatwo możemy zrealizować program, który sam siebie zaktualizuje, kiedy tylko zauważy, że na GitHubie pojawiły się nowe pliki.

Zobaczmy kod pliku download_file.py, widoczny na listingu 4. Na początku importujemy m.in. moduł requests (linia 1), który obsługuje zapytania HTTP. W tym kodzie wykorzystamy funkcję Wi-Fi_connect (linia 2), którą omawialiśmy w poprzednim przykładzie.

# Plik download_file.py

import network
import requests # 1
import time
import wifi_config

def wifi_connect(): # 2
station = network.WLAN(network.STA_IF)
station.active(True)
if not station.isconnected():
print("Łączenie z siecią", end="")
station.connect(wifi_config.ssid, wifi_config.password)
while not station.isconnected():
print(".", end="")
time.sleep_ms(250)
print()

print(f"Adres IP: {station.ifconfig()[0]}")

def download_file(url): # 3
result = requests.get(url) # 4

if result.status_code == 200: # 5
return result.text
else:
return f"Error {result.status_code}"

if __name__ == "__main__": # 6
wifi_connect()
data = download_file("https://raw.githubusercontent.com/
leonow32/micropython/refs/heads/main/
Kurs_Elektronika_Praktyczna/
05_Wyswietlacz_OLED/ssd1309.py")
print(data)

Listing 4. Kod pliku download_file.py

Przejdźmy do linii 3, gdzie tworzymy funkcję pobierającą z Internetu plik, którego adres podajemy poprzez argument url. Cała magia sprowadzona jest do wywołania funkcji get z modułu requests (linia 4). Funkcja ta zwraca krotkę, którą zapisujemy do zmiennej result. W tej krotce znajdziemy mnóstwo informacji, ale nas najbardziej interesują zmienne status_code oraz text.

Po ściągnięciu danych z Internetu musimy najpierw sprawdzić, czy w ogóle udało nam się pobrać żądany plik. W linii 5 sprawdzamy, czy serwer HTTP odpowiedział kodem 200, tzn. przesłał żądany plik. Jeżeli nie uda się pobrać pliku, najczęściej dostaniemy kod błędu 404. Funkcja download_file zwraca zawartość pobranego zbioru lub kod błędu, jeżeli nie udało się go pobrać.

Czas na zasadniczą część naszego programu, który zaczyna się w linii 6 i składa się zaledwie z trzech linijek. Łączymy się z Internetem przy pomocy funkcji Wi-Fi_connect. Następnie próbujemy pobrać plik i zapisać go do zmiennej data, po czym wyświetlamy rezultat funkcją print. To wszystko!

W naszym przykładzie pobieramy plik ssd1309.py (omawiany w 5 części kursu) z repozytorium kursu na GitHubie. W taki sposób możemy pobrać każdy plik i zapisać go w pamięci systemu plików MicroPythona. Nic nie stoi na przeszkodzie, by pobrać program napisany w Pythonie, a następnie go uruchomić.

Rysunek 3. Pobieranie pliku z Internetu

Ping

Przypatrzmy się jeszcze adresowi IP, który jest wyświetlany w logach. Każde urządzenie, połączone z routerem Wi-Fi dostaje unikalny adres IP. Dzięki temu urządzenia znajdujące się w jednej sieci, tzn. podłączone do tego samego routera, mogą komunikować się między sobą.

Możemy przesłać testowy pakiet danych z komputera do ESP32, aby sprawdzić komunikację. W tym celu musimy uruchomić konsolę systemową, wchodząc (w przypadku systemu Windows) do menu Start i wpisując „cmd”. Następnie, kiedy otworzy się konsola, wpisujemy polecenie ping wraz z adresem IP, jaki zobaczyliśmy na konsoli MicroPythona. Komputer prześle cztery testowe pakiety do ESP32 i jeżeli nie będzie żadnych błędów, to powinniśmy zobaczyć efekt analogiczny do tego z rysunku 4. Adres IP w Twoim przypadku oczywiście może być inny.

Rysunek 4. Pingowanie adresu IP, pod którym dostępny jest ESP32

Adresy wszystkich urządzeń znajdujących się w Twojej sieci Wi-Fi możesz uzyskać logując się do ustawień routera. Wskazówkę jak to zrobić, znajdziesz na naklejce z tyłu routera. Zwykle wystarczy otworzyć przeglądarkę internetową i w pasku adresu wpisać IP routera 192.168.0.1. W moim przypadku wygląda to tak, jak na rysunku 5. Widać tam adresy wszystkich urządzeń, w tym mikrokontrolera ESP32 pod nazwą mpy-esp32s3 i pod adresem IP 192.168.0.112.

Rysunek 5. Strona konfiguracyjna routera Wi-Fi

To, co widać na rysunku 5, jest stroną HTML – ale pobraną nie z Internetu, lecz z routera. Cały kod HTML, pliki CSS, pliki graficzne, itp. generowane są przez oprogramowanie routera i przesyłane do urządzenia, które z nim się połączyło. W ten sposób urządzenie bez wyświetlacza i klawiatury zostało wyposażone w rozbudowany i łatwy w obsłudze interfejs użytkownika, wyświetlany na komputerze, smartfonie, tablecie czy dowolnym innym urządzeniu wyposażonym w Wi-Fi i przeglądarkę internetową.

A gdyby tak nasz ESP32 mógł też robić takie cuda… Może!

W następnym odcinku stworzymy własny serwer HTTP. Dzięki niemu będziemy mogli połączyć się ESP32 przy pomocy dowolnej przeglądarki internetowej na komputerze lub telefonie, aby poprzez Wi-Fi kontrolować kolor diody WS2812, a także odczytywać temperaturę.

Zobacz więcej:
• Repozytorium kursu na GitHubie https://github.com/leonow32/micropython
• Dokumentacja modułu network https://docs.micropython.org/en/latest/library/network.html

Dominik Bieczyński
leonow32@gmail.com

Elektronika Praktyczna Plus lipiec - grudzień 2012

Elektronika Praktyczna Plus

Monograficzne wydania specjalne

Elektronik styczeń 2026

Elektronik

Magazyn elektroniki profesjonalnej

Raspberry Pi 2015

Raspberry Pi

Wykorzystaj wszystkie możliwości wyjątkowego minikomputera

Świat Radio styczeń - luty 2026

Ś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 luty 2026

Elektronika dla Wszystkich

Interesująca elektronika dla pasjonatów