Za poslední tři měsíce jsme si v našem seriálu Pojďme programovat elektroniku vyzkoušeli ledacos od primitivního sledování teploty pomocí tepelného senzoru po ultrazvukový dálkoměr, infračervený detektor pohybu anebo bezdrátovou komunikaci pomocí Bluetooth.
Při svých jednoduchých demonstracích jsem však zapomněl na to nejdůležitější – na internet. Co by to bylo za chytrou krabičku, kdyby nebyla dostupná v síti jako další z mnoha prvků internetu věcí?
Hlavním důvodem bylo Arduino samotné, jehož základní modely zpravidla komunikovat v internetu neumějí. Abyste tedy třeba takové Arduino UNO připojili do domácího LANu, musíte si nejprve obstarat ethernetový modul, shield, anebo některý z drobných obvodů, které připojí mikropočítač do Wi-Fi.
Bastlíři milovaný čip ESP8266
Jedním z těch nejpopulárnějších je 2,4GHz 802.11bgn čip ESP8266 (komunitní fórum) od společnosti Espressif, který se v posledních letech dočkal ohromné popularity mezi domácími bastlíři zejména proto, že je levný a sakra výkonný!
Samotný ESP8266
Výrobce jej totiž navrhnul tak, aby měl čip dostatečný výkon a prostředky nejen k samotné bezdrátové komunikaci, ale i pro kód nějakého dalšího programu, který do něj nahrajete. Třeba kód ovladače bezdrátové RGB žárovky a dalších IoT drobností, které budou mít k dispozici až 80 % prostředků.
O výpočty se proto stará 32bitový procesor Tensilica L106, který lze taktovat až na 160 MHz. Suma sumárum, samotný ESP8266 je mnohem výkonnější než obvyklé modely čipů ATmega, které se starají o běh prototypovacích mikropočítačů Arduino, a tak by byla škoda, kdybych třeba k Arduino UNO připojil ESP8266 jen jako Wi-Fi vysílač.
A takto ESP8266 vypadá v jednom z mnoha minimalistických provedení Wi-Fi vysílače ESP-01 nejen pro bastlíře. Přibyla destička s anténou, flash pamětí a piny pro SPI komunikaci.
Holý ESP8266 je nicméně maličký – je opravdu určený pro instalaci v nějakém hotovém zařízení a nikoliv pro rychlé domácí prototypování. Proto se před lety na scéně objevil celý zástup modulů a prototypovacích desek, které se podobají těm od Arduina, mají USB konektor pro komunikaci s PC a napájení, hlavně ale piny pro analogovou a digitální komunikaci a jako mozek ESP8266 (zpravidla z šenčenské fabriky Ai-Thinker).
Na internetu tak dnes seženete třeba Wemos D1 R2, který supluje Arduino UNO, maličký Wemos D1 Mini, který je zase odpovědí spíše na Arduino Nano a Arduino Pro Mini, nebo destičky NodeMCU.
Wemos D1 R2, D1 Mini Pro a NodeMCU
Všechny tyto prototypovací mikropočítače postavené na ESP8266 lze zároveň snadno a tradiční cestou programovat v editoru Arduino IDE, což potěší zejména začátečníky, kteří po dlouhém učení konečně oživili třeba zrovna Arduino UNO a děsí se představy, že by měli rázem studovat něco naprosto odlišného. Třeba (sic jednoduchý) jazyk Lua, který používají zmíněné destičky NodeMCU.
V Arduino IDE stačí nastavit dodatečný zdroj (http://arduino.esp8266.com/stable/package_esp8266com_index.json) programovatelných desek a v manažeru desek poté zvolit k instalaci nový balíček ESP8266. Po stažení všech dat potřebných pro překládání programů pro tuto architekturu pak již v seznamu desek najdete i ty s ESP8266 a můžete začít psát svůj první program.
Instalace podpory desek s ESP8266 v Arduino IDE
Kupuji NodeMCU
Mikropočítač NodeMCU seženete na eBay za částku okolo 80 korun. Wemos D1 je pak o něco dražší – stojí asi dvojnásobek. Já se rozhodl pro tu první možnost a do schránky mi po několika týdnech dorazila obálka s několika exempláři.
Cena mikropočítače NodeMCU se na eBay pohybuje okolo 80 korun
Na internetu se potuluje hned několik variant NodeMCU, přičemž dnes se zpravidla dostanete k neoficiální modifikaci v3 od výrobce LoLin, která přináší vedle pracovního 3,3V zdroje napětí i 5V (resp. napětí z připojeného USB). Rozdíly mezi jednotlivými verzemi najdete třeba na tomto blogu.
Model LoLin NodeMCU v3 a rozložení jeho pinů (kroužkem je vyznačena změna oproti předchozím verzím: pin VU s napětím USB portu)
Světýlko s ovládáním ve webovém prohlížeči
Takže mám mikropočítač s nativní podporou Wi-Fi a nastavené Arduino IDE pro jeho vývoj, čili teď už se konečně mohu vrhnout na psaní prvního programu. Nebude to nic složitého.
K mikropočítači připojím červenou LED diodu, kterou budu ovládat z webového prohlížeče. Aby to bylo možné, NodeMCU se po spuštění připojí do domácí Wi-Fi a spustí si jednoduchý webový server. Jakmile zadám do prohlížeče IP adresu mikropočítače, webový server vrátí HTML kód s tlačítkem pro zapnutí a vypnutí světla.
Primitivní zapojení: červená LED dioda je skrze 220R rezistor připojená na digitální pin D1 a obvod uzavírá pin G, tedy ground (zem). Po spuštění se mikropočítač připojí k domácí Wi-FI a spustí jednoduchý webový server, na který se budu moci připojit z prohlížeče a pomocí webového formuláře zapnout/vypnout LED diodu. Zcela vpravo pak výstup sériové linky s provozními informacemi.
Jinými slovy si postavím jednoduchý Wi-Fi spínač a je už vlastně docela jedno, jestli se bude spínat jednoduchá LED dioda, anebo pomocí magnetického relé velká lampa či jakýkoliv jiný 230V spotřebič.
Komentovaný kód aplikace
#include <ESP8266WiFi.h>
// Nazev Wi-Fi site, do ktere se mam pripojit
const char* ssid = "Klobouk";
// Heslo Wi-Fi site, do ktere se mam pripojit
const char* password = "***********";
// Ma svitit lampicka?
bool svetlo = false;
// Webovy server pobezi na portu 80 (HTTP komunikace)
WiFiServer server(80);
void setup(){
// Nastartuj seriovou linku, do ktere budu vypisovat provozni informace
Serial.begin(9600);
// Nastav pin D1 na zapis a nastav nizkou hodnotu (LED dioda nesviti)
pinMode(D1, OUTPUT);
digitalWrite(D1, LOW);
// Pripojeni k Wi-Fi
Serial.println();
Serial.print("Pripojuji k ");
Serial.println(ssid);
WiFi.begin(ssid, password);
// Dokud nejsem pripojeny k Wi-Fi,zapisuj do seriove linky tecky progressbaru
while (WiFi.status() != WL_CONNECTED) {
delay(100);
Serial.print(".");
}
// Jsem pripojeny k Wi-Fi a mohu pokracovat
Serial.println();
Serial.println("WiFi pripojena!");
// Spusteni serveru
server.begin();
Serial.println("Server spusten");
// Napis IP adresu, kterou mikropocitac dostal
Serial.print("Pouzij k pripojeni tuto adresu: ");
Serial.print("http://");
Serial.println(WiFi.localIP());
}
// Smycka loop se opakuje stale dokola
void loop() {
// Pokud ma promenna svetlo hodnotu pravda, posli na pin D1 napeti a rozsvit LED diodu
if(svetlo == true) digitalWrite(D1, HIGH);
else digitalWrite(D1, LOW);
// Cekej, dokud se nepripoji nejaky klient
WiFiClient client = server.available();
if (!client) {
return;
}
// Cekej, dokud klient neposle nejaka data
Serial.println("Novy klient!");
while(!client.available()){
delay(1);
}
// Precti a vypis prvni radek od klienta s URL dotazem
String request = client.readStringUntil('\r');
Serial.println(request);
client.flush();
// Pokud je v radku vyraz ZapnoutSvetlo, nastav promennou svetlo na pravdu
if(request.indexOf("ZapnoutSvetlo") > -1) svetlo = true;
// Pokud je v radku vyraz VypnoutSvetlo, nastav promennou svetlo na nepravdu
if(request.indexOf("VypnoutSvetlo") > -1) svetlo = false;
// Posli pripojenemu klientu HTML kod stranky s tlacitky
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println("");
client.println("<!DOCTYPE html>");
client.println("<html><body>");
client.print("<h1>Moje Wi-Fi lampicka</h2>");
// Tlacitko pro zapnuti lampicky vede na adresu /ZapnoutSvetlo
client.println("<a href=\"/ZapnoutSvetlo\"><button>Zapni svetlo</button></a>");
// Tlacitko pro vypnuti lampicky vede na adresu /VypnoutSvetlo
client.println("<a href=\"/VypnoutSvetlo\"><button>Vypni svetlo</button></a><br />");
client.println("</body></html>");
// To je vse, ted jeste 1 ms pockam a cela smycka se muze zopakovat
delay(1);
Serial.println("Klient odpojen");
Serial.println("");
}
Stmívatelná lampička pomocí PWM
Každá chytrá žárovka toho ale umí více. Ty, které jsou vybavené RGB diodou, dokážou měnit barevný odstín, ale i ty bílé nabízejí alespoň nastavení úrovně jasu.
To samé zvládne i hloupá LED dioda připojená na digitální pin. Stačí, když mikropočítač ovládá PWM – pulzně-šířkovou modulaci. Digitální piny, které jsou k PWM určené, jsou na mikropočítačích Arduino označené vlnkou ~ a v případě NodeMCU to není třeba, PWM totiž nabízení všechny.
Pokud pro zapnutí LED diody použiji funkci digitalWrite(D1, HIGH), do vodiče začne proudit pracovní napětí 3,3 voltů. Díky PWM ale mohu použít i funkci analogWrite(D1, 0-255). Jak je to možné? V digitálním světě přece platí, že obvodem buď prochází proud a jedná se o logickou jedničku, anebo neprochází (nebo je velmi nízký) a jedná se o logickou nulu. To jsou dva možné stavy a já jich najednou mohu mít 256?
To je právě kouzlo PWM modulace. Která těchto 256 možných stavů moduluje – „zakóduje“ pomocí elektrických pulzů. Při nízkých hodnotách číselného parametru budou krátké pulzy střídat delší proluky a při vyšších hodnotách naopak krátké proluky. LED dioda bude vlastně podle délky těchto pulzů blikat, bude to však natolik rychlé, že si toho nevšimnete. Podstatné je to, že se to projeví jejím sníženým, anebo naopak zvýšeným jasem.
--
Princip fungování PWM na Arduinu s pracovním napětím 5V (Více na stránkách arduino.cc)
Namísto binárních tlačítek pro zapnutí a vypnutí světýlka bych tedy mohl do kódu ovládací stránky umístit HTML5 značku posuvníku <input type="range">, která bude mít číselný rozsah 0-255. Na hodnotě 0 bude lampička zhasnutá, na hodnotě 255 pak bude díky PWM svítit na plný výkon.
Namísto on/off tlačítka posuvník pro nastavení jasu v rozmezí 0-255
Obdobně upravím i kód mikropočítače. Namísto proměnné světlo se stavy pravda/nepravda použiji proměnnou osmibitového celého čísla jas a namísto posílání URL adres /ZapnoutSvetlo a /VypnoutSvetlo budu na server posílat adresu ve formátu /svetlo=XXX při každé změně posuvníkového ovladače.
Různý jas LED diody od 0 po 255
Komentovaný kód se stmívatelnou LED diodou
#include <ESP8266WiFi.h>
const char* ssid = "Klobouk";
const char* password = "***********";
// Nova promenna pro hodnotu jasu
uint8_t jas = 0;
WiFiServer server(80);
void setup() {
Serial.begin(9600);
pinMode(D1, OUTPUT);
digitalWrite(D1, LOW);
// Pripojeni k Wi-Fi
Serial.println();
Serial.print("Pripojuji k ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(100);
Serial.print(".");
}
Serial.println();
Serial.println("WiFi pripojena!");
// Spusteni serveru
server.begin();
Serial.println("Server spusten");
// Vypis IP adresu
Serial.print("Pouzij k pripojeni tuto adresu: ");
Serial.print("http://");
Serial.println(WiFi.localIP());
}
void loop() {
// Namisto digitalWrite nyni pouziji analogWrite pro PWM
analogWrite(D1, jas);
// Pripojil se nejaky klient?
WiFiClient client = server.available();
if (!client) {
return;
}
// Cekej, dokud klient neposle nejaka data
Serial.println("Novy klient!");
while(!client.available()){
delay(1);
}
// Precti a vypis prvni radek od klienta s URL dotazem
String request = client.readStringUntil('\r');
Serial.println(request);
client.flush();
// Pokud odpoved klienta obsahuje HTTP pozadavek na adresu /svetlo=XXX,
// Ziskam hodnotu XXX, prevedu ji na cislo a ulozim do promenne jas
if(request.indexOf("svetlo") > -1){
jas = request.substring(12, request.lastIndexOf(' ')).toInt();
Serial.print("Jas nastaveny na: ");
Serial.println(jas);
}
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println("");
client.println("<!DOCTYPE html>");
client.println("<html><body>");
client.print("<h1>Nastav jas lampicky</h2>");
// Pri zmene hodnoty posuvniku se stranka pomoci Javascriptu presmeruje na adresu /svetlo=XXX
client.print("<input onchange=\"javascript:location.href='/svetlo=' + this.value\" type=\"range\" min=\"0\" max=\"255\" value=\"");
client.print(jas);
client.println("\" />");
client.println("</body></html>");
delay(1);
Serial.println("Klient odpojen");
Serial.println("");
}
A to je celé. Při každé změně posuvníku se během okamžiku změní i jas LED diody.
Dnes jsme si tedy vyzkoušeli jednoduché spuštění webového serveru na mikropočítači připojeném do Wi-Fi. Stejně tak by mohl NodeMCU sám aktivně posílat data kamsi na web pomocí HTTP GET a POST a provádět mnohem sofistikovanější úkony. To je ale námět zase pro jiný článek.
LED dioda se stala součástí mého IoT, tak ať svítí co nejdéle.