ESP8266 – pierwsze programy

No dobrze, po małej przerwie spowodowanej różnymi czynnikami czas na obiecany temat związany z podstawami kodowania 🙂 Ale najpierw będzie ilustracja, tym razem nie zdjęcie z netu, tylko moje własne: płytka stykowa z prototypem szkieletu nowej, lepszej wersji automatyki domowej:

O tejże automatyce będzie. Potem. Póki co zaś – najprostsze programy.

Jest taka specjalna klasa programów, które każdy początkujący programista, albo nawet nie początkujący, ale zaczynający działać z nową platformą po prostu musi napisać. Bez tego się nie da, trzeba i koniec, to jest jak wypowiadanie pierwszych słów, które w 99% przypadków brzmią „mama”, jak pierwsze kroki, jak pierwsze próby z rowerem, jak pierwsze piw… no dobra.
W przypadku nauki kodowania rzecz jest dwoista, zależy bowiem, czy ot tak po prostu uczymy się pisać programy, czy uczymy się programować jakieś urządzenie. Przy nauce „gołego” kodowania pierwszym programem jest niemal zawsze kod wyświetlający na ekranie (bądź konsoli) jakiś napis (kanonicznie: „hello world”, choć mogę się założyć, że początkujący przepisujący z samouczka przykład, zwykle podmieniają „hello world” na coś innego 😉  ). Przy nauce programowania sprzętu, typowym pierwszym programem jest soft do migania podłączonym do urządzenia LEDem. 

Zatem, jak takie pierwsze programy wyglądają w przypadku naszego ESP8266? W księżycówie, czyli w Lua / NodeMCU taki programik do migania ledem ma postać, jak widać:

1
2
3
4
5
6
7
8
gpio.mode(4, gpio.OUTPUT)
 
while true do
   gpio.write(4, gpio.HIGH)
   tmr.delay(500000)
   gpio.write(4, gpio.LOW)
   tmr.delay(500000)
end

Prosty, prawda? Ot, konfiguracja portu 4 jako wyjście (port 4 to ten w którym NodeMCU ma fabrycznie dołączoną diodę LED, więc dla przetestowania działania nie potrzebujemy nic więcej, prócz gołego modułu) i nieskończona pętla, w której port jest ustawiany na HI naprzemiennie z LO, a pomiędzy są dodane półsekundowe pauzy (wartość pauzy w mikrosekundach). Po uruchomieniu programu led zacznie (powinien) migać z częstotliwością 1Hz,
Tyle, że ten program jest do dupy! Problem jest taki, że jak wspominałem w poprzednim odcinku, Lua jest językiem skryptowym, wykonywanym wprost z pliku z kodem źródłowym i kompilowanym „w locie”. Gdy uruchomimy ten program, on owszem, będzie działał, ale pochłonie nam procesor bez reszty. Tenże będzie pracował z zamkniętej pętli, w której głownie będzie zajęty czekaniem (komendy delay), nie obsłuży więc nam nic więcej. W szczególności nie obsłuży nam już więcej samej platformy NodeMCU, bo nie będzie komu się do niej zgłosić i zapytać o to, co dalej ma robić, nie będziemy nawet w stanie przerwać działania programu, czy wgrać innego inaczej, niż przez fizyczny reset modułu.
Jak więc w Lua ten program wyglądać powinien? O, na przykład tak:

1
2
3
4
5
6
7
8
9
gpio.mode(4,gpio.OUTPUT)
 
tmr.alarm(0, 500, 1, function()
        if gpio.read(4) == 0 then
            gpio.write(4, gpio.HIGH)
        else    
            gpio.write(4, gpio.LOW)
        end   
end)

Program prościutki, pierwsza linijka identyczna, znów mamy konfiguracje portu, a zaraz za nim blok będący niczym więcej, jak zaprogramowaniem wewnątrzprocesorowego timera, żeby co 500ms wywoływał umieszczoną w pamięci procedurę, której wyłącznym zadaniem jest odwracanie stanu portu na przeciwny. Jeśli na porcie jest zero, ustaw 1 i vice versa.
Jaka jest różnica między oboma programami? Zasadnicza. O ile pierwszy z nich angażował procesor całkowicie, tak tu jedynie co 500ms wewnętrzne przerwanie zabierze procesor na krótki moment, by przełączyć stan portu. Po owej krótkiej chwili procesor będzie wolny i gotów do innych zadań. W tym przykładzie innych zadań brak, więc gotowość będziemy widzieć tylko w postaci oczekiwania na dalsze polecenia, ale program przecież mógłby być (i w realnych zastosowaniach zwykle będzie, nikt normalny nie będzie stosował docelowo procesora do migania diodą) dużo obszerniejszy, nasz procesor zamiast tracić czas na odmierzaniu pauz może przysłowiowe góry nam przenosić. 

Dla porównania to samo zadanie, czyli miganie LEDem w wersji Arduino ESP, czyli de facto w C++: 

1
2
3
4
5
6
7
8
9
10
void setup() {
  pinMode(2, OUTPUT);
}
 
void loop() {
  digitalWrite(2, HIGH);   
  delay(500);                       
  digitalWrite(2, LOW);    
  delay(500);                      
}

Trochę inna składnia, niż w LUA, inne też mapowanie portów (port 4 w LUA i port 2 w Arduino to fizycznie ten sam port), ale jej sens jest identyczny, jak w pierwszym przykładzie wyżej i ma zresztą te same wady, może poza wadą zasadniczą: tu nie musimy się martwić o utratę kontaktu procesora z platformą po uruchomieniu tego kodu, bowiem w przypadku Arduino C program jest do procesora wgrywany w skompilowanej postaci, co i tak wymaga jego resetu i przerwania wszelakiej innej działalności, jaka by ona nie była. Jak najbardziej można to też zrobić bardziej elegancko, na całe mnóstwo różnych sposobów, z wykorzystaniem przerwań, czy choćby poprzez śledzenie wyniku działania funkcji millis() zwracającej czas w milisekundach od włączenia procesora: 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int state = HIGH;      
long czas = 0;         
 
void setup()
{
  pinMode(2, OUTPUT);
}
 
void loop()
{
  if (millis() - czas > 500)
  {
    state = !state;
    czas = millis();
    digitalWrite(2, state);
  }
}

Definicje zmiennych, inicjalizacja portu jako wyjście i w pętli kontrolowanie, czy różnica między czasem bieżącym a zapamiętanym w trakcie ostatniego przełączenia portu (zmienna czas) przekroczyła wielkość 500ms, jeśli tak zmieniamy stan wyjścia portu na przeciwny. Robimy więc to samo, co w przykładzie wyżej, jednakże o ile wyżej procesor nam stał w miejscu wstrzymany komendą delay, tak tu nasza pętla loop może być duuuużo dłuższa i zawierać mnóstwo innych spraw do załatwienia. Tyle, że przy każdym jej przejściu przy okazji zostanie sprawdzony warunek, czy aby nie przyszła już pora na przełączenie LEDa.

A jak kanoniczny „mój pierwszy program” może wyglądać na innych platformach, które mamy do dyspozycji przy ESP8266? Posłużę się przykładami z internetów, wybaczcie, nie będę testował w praktyce 🙂
O i właśnie, to jest przy okazji znakomity przykład ilustrujący skutki wyboru takiej, czy innej platformy do pracy z naszym procesorem, bo napisawszy powyższe zdanie otworzyłem nową zakładkę przeglądarki i zacząłem szukać googlem obiecanych przykładów. Póki opisywałem LUA /NodeMCU, czy Arduino ESP, przykładów w necie były setki i tysiące, wystarczyło wpisać w google „ESP8266 blinking example”, czy nawet nawet po polsku „NodeMCU miganie diodą” i właściwie problemem wręcz było wyłowienie z potopu stron, tutoriali, blogów mniej lub bardziej dogłębnie zajmujących się tematem (do których niniejszy właśnie dołączył 🙂 ) czegoś odpowiednio ładnie temat podającego. Tymczasem, gdy chciałem znaleźć „esp basic blinking example” – czarna dziura, mnóstwo trafień i wszystkie nie na temat, przykład znalazłem dopiero grzebiąc na jedynej stronie wspierającej ten język. Easy ESP – nie znalazłem w ogóle. Dla SDK – po dłuższym szukaniu znalazłem jedynie zestaw komend do wgrania zewnętrznej aplikacji do migania diodą, aplikacja okazała się być napisana w C++. Jednakże, ów znaleziony przykład w ESP Basic pokażę (w formie printscreena, na wypadek, gdyby strona zawierająca oryginał „zmarła”), bo przy okazji fajnie prezentuje jak bardzo Basic jest „basic” 🙂

Blink_example_-_ESP8266_BASIC_-_Google_Chrome_2017-03-10_12-34-29

(https://www.esp8266basic.com/blink-example.html)

Taki bajer: nie tylko proste miganie ledem, ale od razu współpracujący przez sieć panel sterowania dostępny w przeglądarce internetowej, w której miganiem sterujemy 🙂 Do zabawy, nauki programowania od podstaw myślę, że może to być świetna sprawa choćby z uwagi na prostotę osiągania efektów typu sterowanie przez internet. niemniej, podejrzewam, że wiele więcej z tego języka się nie wyciśnie, a jeśli nawet się zacznie usiłować, to prędzej czy później zderzymy się ze ścianą braku gotowych rozwiązań, na których można się wzorować, przykładów, czy bibliotek.

Na zakończenie jeszcze jeden kanoniczny „mój pierwszy program”, tym razem specyficzny dla tych właśnie modułów, dla ESP8266. Bo o ile ledem dołączonym do portu możemy sobie migać na większości tego typu urządzeń, od całej gamy płytek Arduino począwszy, tak ESP wyróżnia się tym, że mamy w nim wbudowaną antenkę wifi wraz z niezbędnymi przyległościami. I chyba każdy świeżo upieczony posiadacz ESP8266 właśnie od tego zaczyna, często nawet nie od migania ledem, a od sprawdzenia „czy się łączy” 🙂

Wersja LUA, jeszcze z moich zabaw, jak widać:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
print("Node MCU")
print("Jarek.P")
print("02-2017")
print(" ")
print("szukam WIFI...")
wifi.setmode(wifi.STATION)
--dane sieci wifi: SSID, password
wifi.sta.config("J23","********")
wifi.sta.connect()
 
tmr.alarm(1, 2000, tmr.ALARM_AUTO, 
function() 
    if wifi.sta.getip()== nil then 
        print("IP niedostępne, czekam...") 
    else 
        tmr.stop(1)
        print("Zrobione, mój IP: "..wifi.sta.getip())
    end 
end
)

Wersja Arduino ESP, też moja: 

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
#include 
 
void setup() {
    Serial.begin(115200);
  WiFi.disconnect(false);
  WiFi.begin("ssid", "password");
  while (WiFi.status() != WL_CONNECTED) {
    delay(250);
    Serial.print(".");
  }
 
  Serial.println();
  if (WiFi.status() == WL_CONNECTED){
    Serial.println("WIFI uruchomione!");
    Serial.print("IP: ");
    Serial.println(WiFi.localIP());
  }
  else {
    Serial.println("Nie udalo sie polaczyc z WIFI");
  };
};
 
void loop() {
 
};

I tu ciekawostka, którą odkryłem czystym przypadkiem: powyższy kod (ten w C++) jest fragmentem wyciętym z większej całości (Automatyka domowa w nowej, lepszej wersji cały czas się rodzi) i w tejże całości wifi nie jest najistotniejszą sprawą, więc w kodzie prócz powyższego nawiązania połączenia nic więcej w temacie wifi nie ma. Będąc już w trakcie prac nad tą automatyka i generalnie siedząc w Arduino C, przy okazji pisania poprzedniego odcinka blogu, z czystej ciekawości zainstalowałem na próbę ESP Easy. Zgodnie z instrukcją załadowałem firmware, moje NodeMCU stało się po reboocie accesspointem nadającym własną sieć wifi, z SSID ESP_0F8FFD, do którego można było się podłączyć, z przeglądarki dokonać konfiguracji i tak dalej. Chwilę się tym pobawiłem, doszedłem do wniosku, że to nie dla mnie, po czym z powrotem na NodeMCU zainstalowałem swój soft z Arduino IDE, dokonując tym samym wymazania wcześniej wgranego softu Easy ESP. Tak mi się przynajmniej wydawało dopóty, dopóki nie zauważyłem przypadkiem, że mimo, iż mój soft działa w najlepsze, moduł NodeMCU łączy się z wifi jako klient (klient!), równolegle działa sobie cały czas jako accesspoint, z cały czas tym samym SSID. Co więcej, cały czas mogę się do tego SSID zalogować, otrzymuję nawet adres IP. Poniższe zdjęcie przedstawia właśnie tą sytuację (bez logowania się): sfotografowałem ekran swojego komputera z widocznymi dostępnymi sieciami, m.in. tym własnie tajemniczym SSID, a na tle ekranu prototyp mojej automatyki z ekranem OLED raportującym fakt zestawienia połączenia z siecią o SSID J23. I nie, z całą pewnością nie była to obca sieć, pochodząca z innego modułu. Wyłączenie modułu powodowało, że znikała i ona.

(zdjęcie robiłem w pracy, mając za ścianą nasze laboratorium, z którego jest rozsyłanych całe mnóstwo sieci o charakterze testowym, których nazwy… powiedzmy, że nie zawsze są poważne 😉 )

Świadczyłoby to o tym, że cały interfejs wifi wbudowany w ESP8266 jest osobnym i pracującym niezależnie od procesora modułem, który od procesora dostaje jedynie parametry, co ma robić i póki nic tych parametrów nie zmieni bądź nie nadpisze nowymi, robi to. W jaki sposób zaś dzieli czas i zasoby miedzy bycie klientem wifi, a bycie accesspointem – nie mam pojęcia, mogę tylko podejrzewać, że jest to podział w czasie (wifi naprzemiennie pracuje jako AP i jako klient. trochę na chwilę obecną brak mi pomysłu, jak to AP zablokować, proste wifi.disconnect() dodane do kodu niestety nie pomaga, ewidentnie potrzeba czegoś więcej.

I to by było na tyle, jeśli chodzi o pierwsze programy, w następnym odcinku może spróbuję podejść do podstawowych założeń automatyki.

This entry was posted in , . Bookmark: permalink.

5 Responses to ESP8266 – pierwsze programy

trash_bin
Commented:  11 marca 2017 at 17:14

Ekhm, ten pierwszy obrazek znowu wstydliwy, skrył się 😉

Bart
Commented:  12 marca 2017 at 22:26

Jako IDE do ESP8266 polecam Atom + PlatformIO (addon). Chyba najlepsze co znalazłem do programowania tych układów. Arduino IDE daje rade ale w miarę gdy projekt rośnie to zaczyna paru rzeczy brakować. Obił mi się o oczy jakiś dodatek do vima ale nie testowałem.
Jeśli chodzi o automatykę domową to zanim zabierzesz się za wynajdywanie koła od nowa (przepraszam 🙂 ) obczaj to
https://www.supla.org/en/
Jest jeszcze domoticz ale bliżej się nie przyglądałem

    Nie pisałem o tym, ale z Arduino IDE już sie pożegnałem, za namową kolegi (pisującego tu w komentarzach trash_bina, a niech się sam tłumaczy 😉 ) przesiadłem sie na Visual Studio z wtyczką do obsługi arduinopodobnych. VS to straszna kobyła, ile by komputer nie miał ramu, to zeźre, ale za to komfort pracy z nią jest faktycznie niesamowity, z bajerami typu dorzucany automatycznie przez kompilator debugger pracujący wprost w programowanym urządzeniu, a nie w żadnej symulacji. Atoma nie znam, jak znajdę chwilę, to obejrzę, dzięki.

    Co do supli – obiło mi się już parę razy o uszy, wydaje mi się, że jest to coś zbliżonego do domoticza. Do niego też jest dużo gotowych projektów modułów, ale mają jak dla mnie jedną poważną wadę: nie są „moje” 🙂 I nawet nie chodzi mi tu o kwestie własności projektu, czy zadowolenia z czegoś zrobionego od zera samemu, bardziej o możliwość dostosowania pod specyficzne, a niekoniecznie typowe potrzeby. Ta moja automatyka zresztą ma właśnie współpracować z domoticzem, więc choć może koło chcę odkrywać od nowa, to piastę tego koła, łożyska, oś, drążki skrętne i silnik chcę wziąć gotowe 🙂

    haes
    Commented:  13 kwietnia 2017 at 12:52

    Supla to w całości polski projekt i chyba nie ma wielkiego sensu czytać o nim po angielsku, lepiej https://www.supla.org/pl/
    Domoticz zdecydowanie wart jest uwagi, choćby dlatego że współpracuje z wielką ilością różnych urządzeń.
    Z ciekawością czytam tego bloga, dziękuję i czekam na więcej.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *

Archiwum

  • 2021 (3)
  • 2020 (2)
  • 2019 (8)
  • 2018 (9)
  • 2017 (24)
  • 2016 (66)
  • 2015 (39)

Wyszukiwanie

Licznik odwiedzin

0390967
Visit Today : 280
Hits Today : 359
Total Hits : 1245022
Who's Online : 3