Kurs ESP8266 & MicroPython #7: JSON-y i stacja pogodowa z użyciem SSD1306 i DHT11

Tym razem ESP8266 zadziała jako samodzielne urządzenie, pobierające dane z Internetu i czujnika wilgotności i temperatury DHT11 oraz wyświetlające je na wyświetlaczu OLED zgodnym ze sterownikiem SSD1306. Powstanie z tego stacja pogodowa, która nie wymaga użycia czujników na zewnątrz domu. Dane dotyczące aktualnej pogody uzyskamy z OpenWeatherMap w postaci JSON-a. Finalny efekt zbliżony będzie do tego:

ESP8266 Weather Station

JSON
JSON, czyli JavaScript Object Notation to tekstowy format wymiany danych, łatwy do zrozumienia przez człowieka i z obsługą zaimplementowaną w wielu językach programowania, w tym – co interesuje nas najbardziej – przez Pythona. W tym formacie udostępniana jest prognoza pogody w serwisie OpenWeatherMap. Po zarejestrowaniu i utworzeniu klucza API, możemy otworzyć adres w formacie http://api.openweathermap.org/data/2.5/weather?units=metric&id=IdMiasta&appid=KluczAPI, aby zobaczyć udostępniany JSON (oczywiście podstawiając odpowiednie ID miasta i klucz API). Przydatne będą także strony, które przedstawiają JSON-y w bardziej przystępny sposób, jak na przykład ta.

JSON
Przykładowy JSON

Do obsługi JSON-a w postaci tekstowej służy metoda loads z modułu ujson. Używa się jej bardzo prosto: p = ujson.loads(json). Zwracanym typem jest zagnieżdżony słownik. Ale JSON-a najpierw należałoby uzyskać korzystając z modułu socket, co zajęłoby kilka linijek. Na nasze szczęście to wszystko można zrobić szybciej korzystając z modułu urequest, wówczas zagnieżdżony słownik uzyskamy wywołując tylko jedną linijkę:
p = urequests.get('http://api.openweathermap.org/data/2.5/weather?units=metric&id=IdMiasta&appid=KluczAPI').json()

Jak widać na obrazku, temperatura jest zagnieżdżona w main. Aby uzyskać ją z obiektu p należy wywołać temp = p['main']['temp']. Tak samo postępujemy, jeśli chcemy uzyskać inne wartości za wyjątkiem tych znajdujących się w weather, które jest tablicą. W tym przypadku wywołanie nieznacznie się różni i wygląda tak: p['weather'][0]['id'], ponieważ indeks tablicy jest liczbą, a nie ciągiem znakowym.

utime
w JSON-ie zawarta jest jeszcze między innymi informacja o wschodzie i zachodzie Słońca – czas podany jako tzw. Unix Timestamp, czyli ilość sekund, które upłynęły od 1 stycznia 1970 roku. Do konwersji takiej wartości na bardziej przystępny format można użyć funkcji localtime z modułu utime. Jest tylko jeden haczyk – jako “początku czasu” używa ona 1-go stycznia 2000 roku, więc konieczne jest odjęcie 946681200 sekund od wartości z JSON-a. Całe wywołanie wygląda tak:
sunrise = utime.localtime(p['sys']['sunrise'] - 946681200)
Zwracanym typem jest tuple, czyli w dużym skrócie nieedytowalna lista w formacie (rok, miesiąc, dzień, godziny, minuty, sekundy, dzień_tygodnia, dzień_roku), do której odwołujemy się tak, jak do elementów tablicy w C, czyli na przykład sunrise[0].

DHT11
DHT11 to kolejny po DS18B20 czujnik obsługiwany natywnie przez MicroPythona na ESP8266. Czujnik ten poza pomiarem temperatury pozwala jeszcze na pomiar wilgotności względnej powietrza. Również korzysta on z magistrali OneWire, choć tym razem obsługa jest nieco prostsza i zawrzeć ją można w kilku linijkach, bez konieczności używania timerów czy opóźnień.

1
2
3
4
5
import machine, dht
dh = dht.DHT11(machine.Pin(0))
dh.measure()
dh.temperature() #zwraca temperaturę w stopniach Celsjusza
dh.humidity() #zwraca wilgotność względną w procentach

Pomiary nie powinny być częstsze niż raz na sekundę. Przy zastosowaniu jako czujnik temperatury w domu można ograniczyć się do pomiaru raz na 30 minut, w końcu temperatura wewnątrz nie zmienia się zbyt szybko. Schemat podłączenia czujnika OneWire pokazywałem w poprzedniej lekcji, dlatego nie będę go powielał. Jeśli posiadasz ten czujnik w postaci modułu na PCB, na którym jest też rezystor, to jest to rezystor podciągający – możesz zatem połączyć linię danych bezpośrednio do ESP8266, bez dodatkowego podciągania.

SSD1306
Na koniec pozostała sprawa wyświetlenia pobranych danych na ekranie OLED. Poza podłączeniem zasilania 3.3V, pozostałe piny, tj. SCL (SCK) i SDA podłączamy odpowiednio do D1 i D2. Najpierw konfigurujemy wyświetlacz, wybierając piny oraz częstotliwość pracy magistrali I2C (która i tak nie wynosi 400 kHz, tylko maksymalnie około 170 kHz):

1
2
3
4
import machine
import ssd1306
i2c = machine.I2C(scl=machine.Pin(5), sda=machine.Pin(4), freq=400000)
d = ssd1306.SSD1306_I2C(128, 64, i2c)

Po czym możemy zacząć wyświetlanie. Obsługiwane polecenia to:
d.fill(val) – wypełnia lub czyści ekran, w zależności od val (0 lub 1)
d.text('tekst', x, y) – wypisuje ciąg znaków na pozycji (x, y) – lewy górny róg
d.pixel(x, y, col) – wstawia piksel o kolorze col na pozycji (x,y)
d.scroll(dx, dy) – przesuwa obraz o (dx,dy)
d.show() – dopiero ta komenda powoduje odświeżenie ekranu i wyświetlenie zadanej ramki

Ponadto istnieją jeszcze polecenia, które nie wymagają odświeżenia ekranu po ich użyciu:
d.invert(val) – odwraca kolory jeśli val=1
d.contrast(val) – zmienia kontrast w zakresie od 0 do 255

Nie zalecam natomiast używania d.poweroff() – analogiczna funkcja poweron nie istnieje, więc sam możesz domyślić się (lub sprawdzić), czym to poskutkuje. Na koniec jeszcze jedna ważna uwaga – przed każdym wypisywaniem nowego tekstu ekran należy wyczyścić korzystając z fill, w przeciwnym wypadku znaki będą się pokrywać i będą nieczytelne.

Tym razem nie zamieszczam gotowego kodu, a jedynie dokładną instrukcję, jak wykorzystać NodeMCU z MicroPythonem jako stację pogodową. W razie problemów zachęcam do komentowania.

Kurs ESP8266 & MicroPython #6: Prosty serwer WWW i termometr DS18B20

Pora wkroczyć w świat Internetu Rzeczy. W tej lekcji zajmiemy się odczytem temperatury z termometru DS18B20 i wyświetleniem jej na stronie WWW, dostępnej z poziomu każdego urządzenia w Twojej sieci domowej.

DS18B20 jest czujnikiem temperatury wykorzystującym interfejs One-Wire. Oznacza to, że do komunikacji wykorzystywana jest tylko jedna linia, ale odbywa się to kosztem prędkości transmisji. Ponadto czujnik może być zasilany pasożytniczo z linii danych, co ogranicza ilość przewodów do dwóch przy założeniu, że linię danych podciągniemy do zasilania przy samym module. Schemat połączenia czujnika przedstawiony jest na obrazku poniżej.

ESP8266 DS18B20

Dzisiejszy program bardzo łatwo podzielić na dwie części – pierwsza będzie dotyczyć obsługi termometru, zaś druga zapytań od przeglądarki.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import machine, onewire, ds18x20, socket
dat = machine.Pin(5)
ds = ds18x20.DS18X20(onewire.OneWire(dat))
tim = machine.Timer(-1)
tim2 = machine.Timer(-1)
roms = ds.scan()
temp = 0
 
def getTemp(p):
    global temp
    temp = round(ds.read_temp(roms[0]))
 
def startConv(p = 0):
    ds.convert_temp()
    tim2.init(period=750, mode=machine.Timer.ONE_SHOT, callback=getTemp)
 
startConv()
tim.init(period=60000, mode=machine.Timer.PERIODIC, callback=startConv)

Ta część nie wymaga chyba zbyt dokładnego wyjaśniania. Warto zwrócić uwagę na to, że metoda scan() zwraca listę adresów czujników, ponieważ do tej samej linii danych możesz podłączyć więcej niż jeden DS18B20. Po wysłaniu sygnału rozpoczęcia konwersji należy poczekać 750 milisekund, zanim będzie można odczytać temperaturę z czujnika. Warto też za pierwszym razem ręcznie wywołać odczyt temperatury, żeby nie czekać 60 sekund po włączeniu modułu. Wywoływanie konwersji przez timer ma tę zaletę, że aktualna temperatura będzie zawsze dostępna w zmiennej temp i po otrzymaniu zapytania od przeglądarki będzie mogła być od razu wysłana, bez oczekiwania 750 ms na zakończenie pomiaru.

20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]
s = socket.socket()
s.bind(addr)
s.listen(1)
 
f = open('page.html')
html = f.read()
f.close()
 
while True:
    conn, address = s.accept()
    print('Connection from: ', addr)
    while True:
        line = conn.readline()
        print(line)
        if not line or line == b'\r\n':
            break
    conn.send(html[:994])
    conn.send(html[994:].format(temp)) 
    conn.close()

Najpierw określamy adres IP i port na którym chcemy nasłuchiwać. Jest tylko jeden haczyk – ESP już dostało swój adres IP i nie można go w tym momencie zmienić, dlatego najbezpieczniej wpisać 0.0.0.0. Następnie tworzymy gniazdo s, przypisujemy do niego dostępny adres IP i rozpoczynamy nasłuchiwanie. Liczba 1 jako argument metody listen oznacza, że kolejkowane będzie maksymalnie jedno połączenie. Wróćmy jeszcze na chwilę do adresu 0.0.0.0 – oznacza on, że zostaną przypisane wszystkie dostępne adresy IP, czyli w przypadku ESP8266 tylko jeden. Gdybyś wpisał tam adres swojego modułu, serwer też działałby prawidłowo, ale tylko do czasu, gdy router przydzieliłby modułowi inny adres IP. Nawet jeśli wykorzystujesz adres 0.0.0.0, polecam w routerze powiązać adres MAC modułu z konkretnym adresem IP.

Wyświetlana będzie strona, którą możesz pobrać klikając na ten odnośnik: page.html. Z jakiegoś powodu (którego jeszcze nie odkryłem) MicroPython nie może wysłać podczas jednego połączenia więcej niż 1072 znaki, dlatego plik nie zawiera tabulacji i komentarzy. Program MicroPython File Uploader umożliwia wysłanie pliku HTML do modułu.

Następnie akceptujemy połączenie, wyświetlamy adres IP klienta oraz treść zapytania, po czym wysyłamy plik HTML uzupełniony o temperaturę. Obiekt conn służy zarówno do odebrania, jak i wysłania danych. Metoda format zastępuje znaczniki {} wartością liczbową lub tekstem. Ponieważ nawiasy klamrowe znajdują się także w kodzie HTML, plik należy podzielić tak, aby uniknąć konfliktów. Innym rozwiązaniem jest “uciekanie” każdego nawiasu klamrowego, ale ten sposób jest nieco bardziej pracochłonny.

Po wgraniu obu plików (main.py i page.html) i wpisaniu w przeglądarce adresu Twojego modułu, np. 192.168.0.106, zobaczysz taki przyjemny dla oka termometr:

ESP8266 Thermometer

Jeśli posiadasz publiczny adres IP, możesz w routerze przekierować port 80 na adres Twojego modułu. Dzięki temu będziesz miał dostęp do temperatury z każdego miejsca na świecie. Dla pewności wyłączyłbym jednak WebREPL w pliku boot.py, żeby nikt nieupoważniony nie próbował bawić się Twoim modułem.

Kod HTML pochodzi ze strony http://jsfiddle.net/mirceageorgescu/gBW3Y/.

Kurs ESP8266 & MicroPython #5: Przerwania zewnętrzne, timery i debouncing

Załóżmy, że chciałbyś stworzyć program, który natychmiast zareaguje na wciśnięcie przycisku, a w międzyczasie będzie robił jeszcze coś innego co określony czas. Do tego właśnie służą przerwania i timery, którymi zajmiemy się dzisiaj. Przy okazji pokażę ulepszony względem poprzedniego debouncing.

Trochę teorii
Timer jest licznikiem, odliczającym określoną ilość czasu. W MicroPythonie możemy stworzyć dwa rodzaje timerów – jednorazowe i okresowe. Jak łatwo się domyślić, pierwszy wywoła funkcję (callback) tylko raz, a drugi będzie to robił cały czas w równych odstępach czasu. Przerwania natomiast mają za zadanie natychmiastowe przechwycenie jakiegoś zdarzenia, na przykład wciśnięcia przycisku czy sygnału z przerwania z czujnika. Obsługa timerów i przerwań znajduje się w module machine.

Standardowo zacznijmy od układu, ale szybko przejdziemy do programu. Wszystkie elementy wyjaśniałem w poprzednich lekcjach, więc jeśli nie rozumiesz podłączenia diody lub przycisku – wróć do poprzednich lekcji.

ESP8266 - LED & Button

Program
Program jest dosyć długi w porównaniu z poprzednimi, więc wkleję go od razu w całości i opiszę po kolei.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import machine
 
btn = machine.Pin(4, machine.Pin.IN, machine.Pin.PULL_UP)
rLed = machine.Pin(5, machine.Pin.OUT)
bLed = machine.Pin(16, machine.Pin.OUT)
tim = machine.Timer(-1)
tim2 = machine.Timer(-1)
tim3 = machine.Timer(-1)
stable = 0;
pressed = 0;
 
def rLedOff(p = 0):
    rLed.high()
 
def rLedOn():
    rLed.low()
    tim3.init(period=1000, mode=machine.Timer.ONE_SHOT, callback=rLedOff)
 
def bLedToggle(p):
    bLed.value(not bLed.value())
 
def debounce(p):
    global stable, pressed
    if btn.value() == 1:
        return
    if p == btn:
        stable = 0
    stable += 1
    if stable < 20:
        tim2.init(period=1, mode=machine.Timer.ONE_SHOT, callback=debounce
    else:
        rLedOn()
        pressed += 1
        print(pressed)
 
rLedOff()
btn.irq(trigger=machine.Pin.IRQ_FALLING, handler=debounce)
tim.init(period=100, mode=machine.Timer.PERIODIC, callback=bLedToggle)

Do 6-go wiersza wszystko powinno być jasne. Tworzymy w tym miejscu timer o nazwie tim. W ESP8266 istnieją same wirtualne timery, dlatego wszystkie mają ID równe -1. Kolejną nowością jest definicja funkcji rLedOff z domyślnym parametrem p. Przy wywołaniu takiej funkcji można użyć argumentu, ale nie trzeba i wtedy zostanie on zastąpiony domyślną wartością.
W funkcji rLedOn znajduje się inicjalizacja timera do pracy w trybie “jednorazowym”, czyli po upływie 1000ms wywoła on funkcję rLedOff tylko raz. Funkcje wywoływane przez timery i przerwania muszą przyjmować jeden argument i jest to zdarzenie, które wywołało funkcję – właśnie dlatego funkcja rLedOff przyjmuje jeden argument, chociaż do niczego nie jest on potrzebny.
Zajmijmy się teraz debouncingiem. Jak już zapewne wiesz, po wciśnięciu przycisku może się on zachowywać, jakby został wciśnięty kilka razy. Rozwiązaniem na to może być odczekanie kilkudziesięciu milisekund, lub nieco bardziej skomplikowany sposób, który teraz opiszę. Polega on na tym, żeby sprawdzać stan pinu co 1 milisekundę i jeśli przez określony czas (w tym przypadku 20 milisekund) stan będzie nieprzerwanie niski to znaczy, że przycisk został wciśnięty.
Najpierw deklarujemy, że użyjemy zmiennych globalnych, ponieważ chcemy zatrzymać ich wartość pomiędzy kolejnymi wywołaniami funkcji debounce. Jeśli przycisk nie będzie wciśnięty, nie chcemy, żeby wykonywała się dalsza część kodu. Można to zrobić za pomocą else, ale można też tak jak tutaj zakończyć funkcję poprzez return. Dalej – jeśli funkcja została wywołana poprzez przerwanie zdefiniowane w wierszu 37, wyzerujmy licznik czasu, przez który przycisk był wciśnięty i zacznijmy jego odliczanie. Można by w tym przypadku poczekać w pętli 20 razy po jedną milisekundę, każdorazowo sprawdzając stan pinu, ale w tym przypadku zablokowaliśmy wykonywanie programu w pętli głównej (jeśli jakikolwiek by był – w tym przypadku go nie ma). Zamiast tego można zainicjować timer, który po jednej milisekundzie wywoła tę samą funkcję, co właśnie tutaj jest zrobione. Na koniec, jeśli wartość licznika stable nie jest mniejsza od 20 (czyli jest równa 20, bo nigdy nie przekroczy tej wartości), wywołujemy funkcję rLedOn. Timer tim2 nie jest inicjowany po raz kolejny, dlatego funkcja debounce wywoła się kolejny raz dopiero poprzez przerwanie od przycisku btn.
Na koniec jeszcze słowo wyjaśnienia do btn.irq(trigger=machine.Pin.IRQ_FALLING, handler=debounce). Jeśli chciałbyś, żeby przerwanie następowało w przypadku zbocza narastającego, użyj machine.Pin.IRQ_RISING. Warunki możesz połączyć w ten sposób: machine.Pin.IRQ_RISING | machine.Pin.IRQ_FALLING i wtedy przerwanie nastąpi przy obu zboczach sygnału. Jeśli natomiast chciałbyś pozbyć się timera migającego diodą, użyj tim.deinit().

Jak widzisz, ESP wykonuje kilka rzeczy na raz, a przy tym w ogóle nie ma programu w pętli głównej. Przerwania i timery są bardzo przydatne i warto z nich korzystać. Często czujniki posiadają wyjścia, które sygnalizują jakieś zdarzenie (na przykład swobodny spadek akcelerometru) lub zakończenie pomiaru i wtedy użycie przerwań jest konieczne.

Kurs ESP8266 & MicroPython #4: Wejścia cyfrowe i analogowe

W tej lekcji kursu MicroPythona dla ESP8266 pokażę obsługę wejść układu – zarówno cyfrowych, jak i analogowych. W przykładach wykorzystam przycisk oraz fotorezystor, ale możesz użyć jakiegokolwiek czujnika z wyjściem analogowym albo chociażby potencjometru.

Konwerter analogowo-cyfrowy
Konwerter analogowo-cyfrowy, czyli ADC, konwertuje napięcie analogowe na liczbę. W przypadku ESP8266 ADC ma szczególnie ważną cechę – akceptuje napięcia wyłącznie do wartości 1.0V. Wyższe napięcie spowoduje uszkodzenie przetwornika, dlatego zwróć na to szczególną uwagę. Czujniki zasilane napięciem 3.3V zwykle mają wyjście z zakresu 0-3.3V, dlatego musisz użyć dzielnika napięcia. Ale mam też dobrą wiadomość – większość NodeMCU ma dzielnik na płytce, możesz go rozpoznać po rezystorach znajdujących się przy pinie A0 lub mierząc napięcie na własnym dzielniku napięcia. Jeśli przy mierzeniu napięcia o wartości około 1V (ale nie więcej!) otrzymasz wynik w okolicach 320-330 lub mniej, to znaczy, że bezpiecznie możesz mierzyć napięcia do 3.3V bez dodatkowego dzielnika. Przejdźmy teraz do konkretów.

Jeśli masz NodeMCU z wbudowanym dzielnikiem napięcia, zbuduj układ jak na obrazku poniżej. Na ADC mierzony jest spadek napięcia na rezystorze. Jeśli jego rezystancja będzie zbyt mała, to możesz nie widzieć różnicy pomiędzy kompletną ciemnością, a lekkim oświetleniem fotorezystora. Dobierz ją eksperymentalnie – w moim przypadku dobre wyniki daje rezystor 10k, ale wszystko zależy od fotorezystora i jego parametrów. Spokojnie możesz przeprowadzać próby dla rezystancji od kilkuset omów.

NodeMCU ADC

Jeśli natomiast nie masz wbudowanego dzielnika napięcia, to pomiędzy 3.3V, a fotorezystor, dodaj rezystor o wartości pierwszego rezystora pomnożonej przez 2,3 lub więcej. Dzięki temu na pierwszym rezystorze nigdy nie odłoży się więcej niż 1V.

Wejście cyfrowe
Jeśli chodzi o GPIO, to nie ma tu żadnej filozofii. Wejścia przyjmują napięcia od 0 do 3.3V, więc tylko na to musisz zwrócić uwagę. Podłączenie przycisku pokazałem na poprzednim rysunku.

Program
Pora na najważniejszą część, czyli skrypt w Pythonie. Jeśli chodzi o GPIO, to konfiguracja wygląda następująco:

btn = machine.Pin(5, machine.Pin.IN, machine.Pin.PULL_UP)

PULL_UP oznacza, że podciągamy wejście do napięcia zasilania za pomocą wewnętrznego rezystora. Bez tego w naszym układzie wejście byłoby pływające, a po wciśnięciu przycisku i jego puszczeniu stan nadal wynosiłby 0. Gdyby w zbudowanym układzie z przyciskiem zastosować rezystor podciągający, wtedy zamiast machine.Pin.PULL_UP można by napisać None lub zupełnie pominąć trzeci argument. Analogiczne machine.Pin.PULL_DOWN nie zadziała, natomiast dla pinu 16 (D0) nie zadziała nawet PULL_UP. Stan wejścia możesz odczytać poprzez btn.value(). Ze względu na podciągnięcie do góry powinieneś otrzymać wartość 1.

Obsługa ADC jest równie prosta, co GPIO. Wystarczy tylko jedna linijka:

pr = machine.ADC(0)

i już można odczytywać mierzone napięcie poprzez pr.read(). ADC jest 10-bitowy, dlatego metoda będzie zwracać wartości od 0 dla napięcia 0V do 1024 dla napięcia 1.0V.

Sklejmy to wszystko razem i stwórzmy program, który zmierzy napięcie na porcie analogowym po wciśnięciu przycisku. Będzie on wyglądał jak niżej:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import time
import machine
pr = machine.ADC(0)
btn = machine.Pin(5, machine.Pin.IN, machine.Pin.PULL_UP)
prevState = False
while True:
    if btn.value() == 0 and prevState == False:
        prevState = True
        print("PRESSED")
        print("ADC value: " + str(pr.read()))
    elif btn.value() == 1 and prevState == True:
        prevState = False
        print("RELEASED\n")
    time.sleep_ms(50)

Możesz go wgrać za pomocą programu MicroPython File Uploader dostępnego w dziale Download zamiast używać do tego WebREPL.
Poprzez zapisywanie poprzedniego stanu przycisku program reaguje tylko wtedy, gdy coś się zmienia. Dzięki temu po wciśnięciu przycisku wartość wyświetli się tylko raz, nawet jeśli przycisk będzie przytrzymany. Odczekanie kilkudziesięciu milisekund to bardzo prosty, ale działający sposób na poradzenie sobie z drganiami styków podczas wciskania przycisków (debouncing). Bez tego jedno przyciśnięcie mogłoby poskutkować wielokrotnym wyświetleniem wyniku. Do wyjaśnienia pozostała jeszcze linijka print("ADC value: " + str(pr.read())). Metoda read() zwraca liczbę całkowitą. Konkatenacja (łączenie łańcuchów tekstu) w Pythonie działa wyłącznie dla typu string, dlatego liczba całkowita musi być wcześniej rzutowana i służy do tego str().

W kolejnej lekcji zobaczysz, jak wykorzystać przerwania w podobnym przykładzie.

MicroPython File Uploader

Tym razem nieco inaczej. Postanowiłem nieco ułatwić Wam (i sobie) wgrywanie skryptów i innych plików na ESP8266 i przygotowałem prostą aplikację służącą do tego celu. Aplikacja jest jeszcze w trakcie rozwoju, ale wszystkie opcje, w które możecie kliknąć już działają. Jeśli nie będziecie próbować szukać luk (które z pewnością są), to wszystko będzie działać jak należy. Możecie wgrywać nie tylko skrypty Pythona, ale także wszystkie inne pliki. Testowałem aplikację ze zdjęciem o wielkości 80KB i zadziałało. Póki co nie ma ustawionego żadnego limitu. Jeśli chcesz sprawdzić możliwości aplikacji, to możesz to zrobić i podzielić się efektami – w najgorszym wypadku będziesz musiał wyczyścić pamięć i wgrać MicroPythona jeszcze raz.

Tryb REPL też jest dostępny i powinien działać tak samo jak w WebREPL. Tekst wprowadza się pod terminalem. Jeśli będziesz chciał opuścić np. definicję funkcji, wciśnij Backspace w pustym polu i wciśnij Enter.

fileuploader

Myślę, że używanie tej aplikacji znacząco przyspieszy pracę z ESP8266 z MicroPythonem. Skończą się obawy o przypadkowe rozłączenie z siecią i konieczność ciągłego wpisywania hasła. Wszystko będzie działać nawet po hard-resecie. W miarę możliwości będę przygotowywał kolejne wersje (można już zauważyć, że będzie dostępne pobieranie i usuwanie plików). Będę wdzięczny za wszelkie uwagi, zauważone błędy i propozycje nowych funkcjonalności – podzielcie się nimi w komentarzu.

Program możecie pobrać klikając w linka poniżej. Do działania wymaga .NET Frameworka w wersji 4.5.2 do pobrania stąd (ale bardzo prawdopodobne, że masz już go zainstalowanego).

Pobierz “MicroPython File Uploader” MicroPython File Uploader.exe – Pobrano 15019 razy – 75 KB