ESP8266

Az ESP8266 chip

Áttekintés

Ez az oldal az Arduino wifis kiegészítése. Az Arduino önmagában nem képes wifire csatlakozni, erre az ESP8266 jelű chipet tudjuk használni. Ez egy külön világgá nőtte ki magát (az én esetemben is; kezdetben ugyanis az Arduino-s oldal része volt), használata viszont - ahogy látni fogjuk - jóval bonyolultabb, mint az Arduino-é. Kicsit nyersebben megfogalmazva: amíg az Arduino egy igényesen megalkotott mikrovezérlő, az ESP8266-osokon viszont - noha sokkal többet tudnak - látszik az igénytelenség. Olyan lépéseket kell végrehajtani, melyek valójában feleslegesek, macerásak, ráadásul rosszul dokumentáltak; nagyon sok napom, hetem elment arra, mire rájöttem, miként lehet ezeket használni. Az Arduino esetében mindenkinek jó szívvel ajánlom a tanulást, a wifis eszközöket viszont csak az elszántabbaknak. Ugyanakkor azt is vegyük figyelembe, hogy ez az a terület, melyen a jövőben robbanásszerű fejlődés várható: a már szinte filléres, wifi-vel ellátott mikrovezérlőkben hatalmas potenciál van.

Az ESP8266 beállítása az Arduino IDE-ben

Ahhoz, hogy az ESP8266 mikrovezérlőket használni tudjuk, először is néhány beállítást végre kell hajtanunk az Arduino IDE-ben. A művelet végrehajtásához internet kapcsolatra van szükség. (Zárójeles kérdésem: miért is? Miért nincs benne automatikusan?)

A lépés eredménye: a Tools -> Board alatt megjelent számos új programozható lapka.

Az ESP8266-os chipet tartalmazó mikrovezérlők

Mielőtt belemennénk az egyes mikrovezérlőkkel való megismerkedésbe, lássunk egy általános összefoglalót arról, hogy milyen eszközök léteznek! A felsorolás messze nem teljes.

  • ESP8266-01: ez egy 8 lábas, valóban mikro méretű mikrovezérlő, melyet (az írás pillanatában) kétféle formában hoztak forgalomba: a kék színű 0,5 MB memóriával rendelkezik, míg a fekete 1 MB-os. A memóriamérete tehát jóval nagyobb mint az Arduino UNO-é, hátránya viszont a kevés láb (a 8-ból mindössze 2 használható általános célra), a nehézkes lábkiosztás és a nehézkes programozás.
  • WeMos: erre tekinthetünk úgy, mint az Arduino UNO és az ESP8266 összegyúrása: kinézete ugyanis az Arduino UNO-ra emlékeztet, a méretei is ugyanakkorák, olyannyira, hogy az Arduino UNO bővítőlapkájával is kompatibilis. Ez is 32 lábas, csakúgy mint az Arduino UNO.
  • NodeMCU: kompakt, méretre kisebb mint a WeMos, nem kompatibilis az Arduino UNO-val, tudása nagyjából a WeMos-nak felel meg. Ennek is 32 lába van.
  • Sonoff: ez lényegében egy ESP8266-os chip és egy relé összegyúrásából kialakított céleszköz; célja tehát nem az oktatás vagy a fejlesztés, hanem a felhasználás.

ESP8266-01

Áttekintés

Erre az eszközre úgy találtam rá, hogy utána néztem, hogyan lehet az Arduino UNO-val internetre kapcsolódni. Akkor még nem sejtettem, hogy ezzel egy teljesen új világ tárul elém. Ez az egy-másfél dollárnyi eszköz többnyire sem a kezdőcsomagnak nem része, sem a 37 szenzor csomagnak, így külön meg kell vásárolnunk. Érdemes programozót is vennünk hozzá együtt vennünk, melynek ára kb. ugyanannyi. Mint az idővel kiderült számomra, ez önmagában egy mikrokontroller, melynek a kapacitása ráadásul messze nagyobb mint az Arduino-é.

Az ESP8266-01 lábkiosztása a következő (a kép forrása: https://en.wikipedia.org/wiki/ESP8266):

ESP8266_01_PinOut.png

Néhány fontos észrevétel:

  • Az eszköz 3,3 Volton működik. 5 Volt esetén tönkre mehet, ezt vegyük figyelembe!
  • A soros adatkapcsolathoz van rajta TX és RX.
  • Mindössze két általános lába van: a GPIO0 és a GPIO2.

Az eszköz alapból egy olyan firmware-t tartalmaz, melynek segítségével AT parancsokat kiadva tudunk az internetre csatlakozni. Más programot feltölteni vagy a firmware-t frissíteni (ill. visszaállítani) nem egyszerű, de mivel az eszközben óriási potenciál van (pl. a memóriaméret 512 kB vagy 1024 kB, ellentétben az Arduino 32 kB-jával), érdemes ezzel is megismerkednünk. Ugyanis a beleégetett firmware-t le tudjuk cserélni egy olyanra, amit mi magunk készítettünk.

AT parancskészlet

Az ESP8266 alap firmware-e tehát olyan, hogy AT parancsok segítségével tudunk wifi hálózaton keresztül az internetre csatlakozni, ill. web szervert létrehozni. Mielőtt programozni kezdjük, próbáljuk ki, hogy működik-e! Ehhez lássuk a bekötést! Fordítsuk meg az ESP8266-ot úgy, hogy a tűk felül legyenek. Ennek alapján a következőképpen kössük rá az Arduino-ra:

  • ESP8266 első sor, első tű (TX) -> Arduino TX (nem tévedés!)
  • ESP8266 első sor, második tű (CH_PD) -> Arduino 3.3V
  • ESP8266 első sor, harmadik tű (RST) -> nem kell bekötni
  • ESP8266 első sor, negyedik tű (VCC) -> Arduino 3.3V
  • ESP8266 második sor, első tű (GND) -> Arduino GND
  • ESP8266 második sor, második tű (GPIO2) -> nem kell bekötni
  • ESP8266 második sor, harmadik tű (GPIO0) -> nem kell bekötni
  • ESP8266 második sor, negyedik tű (RX) -> Arduino RX (nem tévedés!)

Néhány észrevétel:

  • Első körben az Arduino-t arra használjuk, hogy továbbítsuk az eszköz felé az adatokat. Emiatt nem tévedés a TX-TX, RX-RX bekötés. Később ezt meg fogjuk fordítani.
  • Mivel két lábat is 3,3 V-ra kell kötnünk, fejlesztőpanelt kell használnunk. (Adódik a kérdés: miért is kell mindkét lábat 3,3 V-ra kötni? Miért nem oldja meg ezt maga belül? Majd látni fogjuk, hogy egy viszonylag összetett példában is csak emiatt kell próbapanelt használni.)

Kliens mód AT parancsokkal

Kód: most nincs, de biztos, ami biztos, töltsünk fel egy üres programot az Arduino-ra, még bekötés előtt (pl. File -> Examples -> 01. Basics -> BareMinimum). Ha már bekötöttük, és nem megy fel, akkor ideiglenesen húzzuk ki a TX-et és RX-et, majd feltöltés után dugjuk vissza. A Tools -> Board legyen Arduino/Genuino Uno (ez amiatt tarom fontosnak kihangsúlyozni, mert majd később, az ESP8266 közvetlen programozásakor a neki megfelelőt kell kiválasztani, most viszont nem, mert továbbra is az Ardino-t programozzuk). Nyissuk meg a Serial Monitort, a baud legyen 115200 (ez az ESP8266 alapértelmezett sebessége), a sor vége pedig legyen NL & CR. Itt kiadhatjuk az AT parancsokat, mellyel az internetre tudunk csatlakozni. Az AT parancsok specifikációja itt található: https://www.espressif.com/sites/default/files/documentation/4a-esp8266_at_instruction_set_en.pdf. Egy példa:

AT+RST - újraindítás (néha szükség van rá…)
AT+GMR - kiírja a verziót / verziókat
AT+CWMODE=1 - station módba kerül
AT+CWLAP - kiírja az elérhető wifi hálózatokat
AT+CWJAP="[ID]","[password]" - egy hálózatra csatlakozik
AT+CIFSR - kiírja a kapott IP-t
AT+CIPMUX=0 - egyszeres kapcsolatot állít be
AT+CIPSTART="TCP","[IP]",[port] - lekérdezést indít
AT+CIPSEND=[hossz] - a lekérdezés hossza bájtban
GET /… - pl. GET parancs esetén a szerveren belüli elérés
AT+CWQAP - lekapcsolódás a wifi hálózatról

A GET parancs eredménye a soros monitoron jelenik meg, kb. az alábbi formában:

OK
Linked

+IPD,[fogadott bájtok száma]:[tartalom]
OK

OK
Unlink

Szerver mód AT parancsokkal

A fenti példában az eszköz kliensként rácsatlakozott egy wifi hálózatra. AT parancsokkal szerver módba is tudjuk tenni; lássunk erre egy példát!

AT+CWMODE=2 - SoftAP módba teszi (megjegyzés: a 3-as kóddal egyszerre mindkét módba tehetjük)
AT+CIFSR - kiírja az IP-t (a tapasztalatom szerint ez mindig 192.168.4.1)
AT+CIPMUX=1 - lehetővé teszi a többszörös csatlakozást
AT+CIPSERVER=1,80 - létrehoz egy szervert a 80-as porton (az 1 jelenti azt, hogy létrehoz, a 0 azt, hogy töröl)
Ezen a ponton csatlakozzunk az eszköz által létrehozott wifi hálózatra (pl. FaryLink_23DE0C), majd egy böngészőből nyissuk meg a fenti IP-t, pl. http://192.168.4.1. Ekkor megjelenik egy hosszú, kb. 10 soros üzenet a soros monitoron, mely így kezdődik: +IPD,0,414:GET. Egy GET üzenet érkezett; az IPD utáni számot (jelene esetben a 0) jegyezzük fel.
AT+CIPSEND=0,13 - a 0 helyére a fent feljegyzett számot írjuk (első lekérdezéskor 0, második lekérdezéskor 1 stb.). A 13 az általunk kiküldendő üzenet hossza.
> Hello, world! - az üzenet, melyek a hosszát fent adtuk meg.
AT+CIPCLOSE=0 - a kapcsolat bezárása. (A fenti számot kell megadni 0 helyett.)

Ha mindent jól csináltunk, megjelenik egy Hello, world! üzenet a böngészőnkben.

Kapcsolódás az internetre AT parancsokkal programból

Ha meggyőződtünk arról, hogy működik, akkor lássunk egy élesben működő példát: hőmérsékletet és páratartalmat fogunk mérni és az interneten rögzíteni! Ezt a projektet egyébként itt találtam: https://www.ardumotive.com/iot-wifi-temp-and-humidity.html.

A ThingSpeak rendszeren fogjuk tárolni az adatokat, melyet kifejezetten IoT célokra hoztak létre. Szükséges lépések:

  • Regisztrálunk a thingspeak.com oldalon, majd lépjünk be.
  • Hozzunk létre egy új csatornát: Channels -> New Channel -> itt adjunk neki valamilyen nevet, és két mezőt töltsünk ki, az egyik legyen Hőmérséklet, a másik Páratartalom.
  • Ha ezzel készen vagyunk, a csatornán belül 6 fület kell látnunk. Ezek közül az egyik az API Keys. Itt jegyezzük fel a Write API Key-t.
  • Próbáljuk ki (bár ezzel össze fogjuk "szemetelni")! A böngészőnkbe írjuk be a következőt: http://184.106.153.149/update?key=[API Key]&field1=26.6&field2=56.3. (A 184.106.153.149 a szerver IP címe.) Ha mindent jól csináltunk, akkor a nézetben (Private View) meg kell jelennie egy pontnak.

A hőmérséklet és páratartalom méréshez szükségünk lesz a már megismert DHT11 (vagy DHT22) érzékelőre. Bekötés:

  • Az ESP8266-ot úgy kössük be, ahogy fent látható, egy kivétellel: a TX-et az RX-re kell kötni és fordítva. Ezt legegyszerűbben úgy tudjuk megtenni, hogy felcseréljük az Arduino-n az 0-ás és 1-es lábra kötött kábelt:
    • ESP8266 első sor, első tű (TX) -> Arduino RX
    • ESP8266 első sor, második tű (CH_PD) -> Arduino 3.3V
    • ESP8266 első sor, negyedik tű (VCC) -> Arduino 3.3V
    • ESP8266 második sor, első tű (GND) -> Arduino GND
    • ESP8266 második sor, negyedik tű (RX) -> Arduino TX
  • A DHT11-et (vagy DHT22-t) az Arduino oldalon bemutatottak szerint kössük be:
    • DHT11 S -> Arduino 2
    • DHT11 középső -> Arduino 5V
    • DHT11 - -> Arduino GND

A kód az egyszerűség érdekében nem tartalmaz hibakezelést:

#include <stdlib.h>
#include <DHT.h>
 
DHT dht(2, DHT11);
 
void setup() {
  Serial.begin(115200);
  Serial.println("AT");
  delay(5000);
  Serial.println("AT+CWMODE=1");
  delay(2000);
  Serial.println("AT+CWJAP=\"[SSID]\",\"[password]\""); 
  delay(5000);
}
 
void loop(){
  Serial.println("AT+CIPSTART=\"TCP\",\"184.106.153.149\",80"); 
  delay(2000);
  char buffer[10];
  String temperatureC = dtostrf(dht.readTemperature(), 4, 1, buffer);
  int humidity = dht.readHumidity(); 
  String cmd = "GET /update?key=[APIKey]&field1=" + temperatureC + "&field2=" + String(humidity) + "\r\n";
  Serial.print("AT+CIPSEND=");
  Serial.println(cmd.length());
  delay(2000);
  Serial.print(cmd);
  delay(60000);
}

Három dolgot ne felejtsünk el módosítani a kódon a feltöltés előtt:

  • SSID: a mi wifi-nk nevét adjuk meg itt
  • password: a wifi-nk jelszava kerüljön ide
  • APIKey: a fent feljegyzett API kulcs kerüljön ide

Feltöltés előtt ideiglenesen húzzuk ki a TX és RX kábeleket, mert az zavarja a feltöltést (hiszen a feltöltés is a soros interfészen keresztül történik), majd feltöltést követően dugjuk vissza. Ha mindent jól csináltunk, akkor a ThingSpeak oldalunkon percenként frissül a hőmérséklet és páratartalom, melyből diagramot rajzol.

Az ESP8266 programozása

Az ESP8266 programozása nem olyan egyszerű mint az Arduino-én. Az interneten található leírások szerint külön áramkört kell kialakítani, ez viszont nekem sehogy sem sikerült. Végül megtudtam, hogy létezik ehhez külön programozó is, igen jó áron, rendeltem egyet (keresőkulcs: ESP8266 programmer), ami már majdnem megoldást biztosított. Amiatt csak majdnem, mert össze kell kötni a GPIO0-t a GND-vel ahhoz, hogy programozni tudjuk. Ha megfordítjuk a programozót, és a tű végek vannak felül, akkor a második (USB-hez közelebbi) sor balról az első (GND) és harmadik (GPIO0) lábat kell összekötni. Az interneten jumperes megoldást javasolnak, és viszont fixen ráforrasztottam egy összekötő kábelt. Igaz, így soros adatkapcsolatként nem tudom használni, de mivel ennek az eszköznek a célja kizárólag a feltöltés, számomra ez megfelel. Csipesszel összekötve is működött egyébként, de a rövid végek miatt az elég instabil volt.

Tehát a forrasztás után lett egy programozóm, és ebbe belehelyezve már többnyire működik a feltöltés. Beállítások:

  • A bevezetőben leírtak szerint állítsuk be az Arduino IDE-t.
  • Dugjuk a programozóra az ESP8266-ot úgy, hogy a wifi-s fele az USB felé nézzen (tehát a programozó fölött legyen), a programozó USB-ját pedig a számítógép USB-jére.
  • A rendszer nem ismeri fel ezt az eszközt úgy, mint az Arduino UNO-t, így magunknak kell megállapítanunk az USB portot. Ez általában a legmagasabb sorszámú, de ha biztosra szeretnénk menni, akkor indítsuk el a Device Manager-t, azon belül nyissuk meg a Ports-ot, és ott kell találnunk egy USB-SERIAL CH340 (COM10) bejegyzést. Az ottani COM lesz a port szám.
  • Nyissuk meg a File -> Examples -> 01.Basics -> Blink programot
  • Szükséges beállítások az Arduino IDE-ben, a Tools alatt
    • Board: Generic ESP8266 Module
    • Upload Speed: 115200
    • CPU Frequency: 80 MHz
    • Crystal Frequency: 26 MHz
    • Flash Size: 512K (no SPIFFS)
    • Flash Mode: QIO
    • Flash Frequency: 40 MHz
    • Reset Method: ck
    • Debug Port: Disabled
    • Debug Level: None
    • IwIP Variant: v2 Lower Memory
    • VTables: Flash
    • Buildin Led: 1 (ezt át kellett állítani, különben nem működött, és kérdem: miért nem voltak képesek az alapértelmezettre állítani?)
    • Erase Flash: Only Sketch
    • Port: COM10 (ezt be kell kézzel állítani a fent megállapított értékre)

Majd a szokásos módon töltsük fel a programunkat (Ctrl + U). Tapasztalat: az Arduino UNO-hoz képest iszonyatosan hosszú ideig tart a feltöltés, különösen a feketéé. Ha mindent jól csináltunk akkor a lapkán található kék LED villogni fog.

Firmware visszaállítása

Ha a programozás után megpróbálnánk kiadni az AT parancsokat, akkor természetesen nem fog sikerülni. A firmware újbóli feltöltéséhez szükség van egy feltöltő programra és magára a firmware-re. Ezek innen letölthetőek: https://drive.google.com/file/d/0B3dUKfqzZnlwVGc1YnFyUjgxelE/. (Újabb igénytelenség! Ennél "hivatalosabb" forrást nem találtam, vagy ha igen, ott nem volt egyértelmű, hogy mit kell letölteni, ill. volt, hogy csak a forrást találtam, binárist nem. De miért nem teszi valaki letölthetővé a binárist, csak a forrást? És miért nem lehet azt a kb. fél megabájtos binárist beletenni a feltelepítve kb. százszor akkora Arduino IDE-be, vagy az ugyancsak több mint fél gigabájtot elfoglaló ESP8266 dolgok közé, ami nem mellesleg a c:\Users\[username]\AppData\Local\Arduino15 könyvtár alá került? Érthetetlen igénytelenség mindez!) Töltsük le, majd hajtsuk végre a következő lépéseket:

  • Helyezzük az eszközt a programozóra, a programozót meg az USB-re, a fent leírtak szerint.
  • Indítsuk el a esp8266_flasher.exe fájlt.
  • Kattintsunk a Bin nyomógombra, és válasszuk ki a ESP_8266_BIN0.92.bin fájlt.
  • A COM1-et kézzel írjuk át a megfelelő COM portra, pl. COM10.
  • A cím maradjon 0x00000.
  • Kattintsunk a Download gombra.
  • Ha mindent jól csináltunk, akkor egy Erasing flash bejegyzés után jön egy rakat Writing at … sor (amit szintén igénytelennek tartok amúgy…). De gyakran az is előfordul, hogy mindent jól csináltunk mégsem indul el a feltöltés. Ekkor le kell csatolni és újra be kell dugni az USB-t, reménykedve abban, hogy ezentúl működni fog…
  • A végén van egy Failed to leave Flash mode hibaüzenet, de ezzel nem kell foglalkoznunk (ami amúgy ismét egy megengedhetetlen igénytelenség szerintem).

Most a korábban bemutatott módon ismét tudunk AT parancsokat kiadni.

Kapcsolat az Arduino UNO és az ESP8266-01 között

Célszerű a két eszköz közötti kommunikációt soros interfészen keresztül megoldani. Az alábbi példában az Arduino a fogadott üzeneteket kiírja a soros monitorra.

Bekötés:

  • ESP8266 első sor, első tű (TX) -> Arduino 5 (ez lesz az RX)
  • ESP8266 első sor, második tű (CH_PD) -> Arduino 3.3V
  • ESP8266 első sor, negyedik tű (VCC) -> Arduino 3.3V
  • ESP8266 második sor, első tű (GND) -> Arduino GND
  • ESP8266 második sor, negyedik tű (RX) -> Arduino 6 (ez lesz a TX)

ESP8266 kód:

void setup() {
  Serial.begin(9600);
}
 
void loop() {
  Serial.println("This is a test message. 0123456789");
  delay(1000);
}

Arduino UNO kód:

#include <SoftwareSerial.h>
 
SoftwareSerial espSerial(5, 6); // RX, TX
 
void setup() {
  Serial.begin(9600);
  espSerial.begin(9600);
}
 
String payload;
 
void loop() {
  if (espSerial.available()) {
    Serial.write(espSerial.read());
  }
}

Teszt: figyeljük a soros monitort. Ha mindent jól csináltunk, akkor a kódban látható üzenet jelenik meg másodpercenként egyszer. Megjegyzés: 9600-as baud rátát használjunk, az ESP8266 alapértelmezett rátája, a 115200 zajossá teszi a kommunikációt (sok óra elment vele, mire rájöttem, hogy ez a hiba).

Kapcsolódás az internetre saját programmal

Amit azt láthattuk, AT parancsokkal is tudunk csatlakozni az internethez, viszont a programozása igen nehézkes és instabil. A fenti példában adatokat küldtünk, a fogadáshoz viszont elemezni (angolul parse) kellene az üzeneteket. Kissé meglepő módon egyébként nem találtam sem olyan könyvtárat, sem olyan példát, ami ezt a gyakorinak tűnő műveletet végrehajtaná. AZ oka ennek valószínűleg az, hogy a legegyszerűbb eseteket leszámítva nem AT parancsokkal programozzák az ESP-t, hanem saját firmware-t töltenek fel, és az eredményt a soros porton már feldolgozva küldi tovább. Lássunk egy példát, amely a djxmmx.net publikusan elérhető oldal 17-es portjára csatlakozik, ahonnan idézeteket lehet letölteni:

#include <ESP8266WiFi.h>
 
const char* ssid = "[SSID]";
const char* password = "[password]";
 
void setup() {
  Serial.begin(115200);
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
  }
}
 
void loop() {
  WiFiClient client;
  client.connect("djxmmx.net", 17);
  while (client.available() == 0) {}
  while (client.available()) {
    String line = client.readStringUntil('\r');
    Serial.print(line);
  }
  Serial.println();
  client.stop();
  delay(10000);
}

Az [SSID] és a [password] helyére értelemszerűen a saját wifi hálózatunk nevét és jelszavát írjuk. Ahhoz, hogy az eredményt láthassuk, vagy használjunk olyan programozót, melynek a megadott két lába nincs összeforrasztva, vagy csatlakoztassuk egy üres programot tartalmazó Arduino-hoz az AT parancsok kipróbálásánál megadott módon (azaz TX-TX és RX-RX). A soros monitoron láthatjuk a megjelenő idézeteket.

Web szerver létrehozása saját programmal

Amint azt láthattuk, az ESP8266-01 nemcsak kliensként, hanem szerverként is funkcionálhat. Töltsük fel az alábbi programot:

#include <ESP8266WiFi.h>
 
WiFiServer server(80);
int LED_PIN = 1;
 
void setup() {
  WiFi.mode(WIFI_AP);
  WiFi.softAP("ESP8266-wifi", "12345678");
  server.begin();
  IPAddress HTTPS_ServerIP= WiFi.softAPIP();
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, HIGH);
}
 
void loop() {
  WiFiClient client = server.available();
  if (!client) { 
    return; 
  } 
  String request = client.readStringUntil('\r'); 
  if (request.indexOf("/ON") != -1) {
    digitalWrite(LED_PIN, LOW);
  } else if (request.indexOf("/OFF") != -1) { 
    digitalWrite(LED_PIN, HIGH); 
  }
 
  String s = "HTTP/1.1 200 OK\r\n";
  s += "Content-Type: text/html\r\n\r\n";
  s += "<!DOCTYPE HTML>\r\n<html>\r\n";
  s += "<input type=\"button\" name=\"b1\" value=\"Turn LED ON\" onclick=\"location.href='/ON'\">";
  s += "<br><br>";
  s += "<input type=\"button\" name=\"b2\" value=\"Turn LED OFF\" onclick=\"location.href='/OFF'\">";
  s += "</html>\r\n";
  client.flush();
  client.print(s);
  delay(1);
}

A bekötés a programozásnál megadott legyen (TX-RX, RX-TX). Kapcsolódjunk számítógépünkkel a kódban megadott wifi hálózatra, az ott megadott jelszóval, majd egy böngészőből nyissuk meg ezt az oldalt: 192.168.4.1. Két nyomógombot látunk, melynek segítségével a lapkán található LED-et tudjuk be- ill. kikapcsolni, wifi-n keresztül. (A kódból az is látszik, hogy az ESP8266 fordított logikát használ: a LOW világít, a HIGH nem. De hogy miért…?)

WeMos

Áttekintés

Ahogy arról már szó volt a bevezetőben, a WeMos többé-kevésbé egyesíti az Arduino UNO és a ESP8266 előnyeit. A programozáshoz itt is először telepíteni kell a bevezetőben leírtak szerint az esp8266 komponenst. Az eszközök között a WeMos D1 R1-et kell kiválasztani. A WeMos-t a számítógéppel nem az Aruino UNO-nál megszokott, nyomtatóknál megszokott kábellel kell összekötni, hanem a mobil töltőkre emlékeztető USB kábellel. A tapasztalatom szerint nem működött mindegyikkel, így ha nem működik egy adott kábellel, érdemes kipróbálni másikkal. A portot ne felejtsük el beállítani. A feltöltési sebesség valahol az Arduino UNO és az ESP8266-01 között van. A tapasztalatom szerint a WeMos nem 100%-osan kompatibilis az Arduino UNO-val, néhány érzékelő esetén saját könyvtárat kell használni.

A WeMos lábkiosztása az alábbi:

WeMos_pinout.jpg

A programozás során használhatjuk a lapkára írt, D betűvel kezdődő megnevezéseket is, valamint a GPIO utáni számot.

Villogó LED

A programozás során a lapkára írt lábakat használjuk, pl. ami az Arduino UNO-n a 9-esnek felel meg, ott D7 áll, és ezt írjuk bele a kódba (viszont amint az azt a fenti lábkiosztásból láthatjuk, ez valójában a 13-as láb), pl. így (ha egy előtét ellenállással védett LED-et helyezünk az említett lábra):

void setup() {
  pinMode(D7, OUTPUT);
}
 
void loop() {
  digitalWrite(D7, HIGH);
  delay(1000);
  digitalWrite(D7, LOW);
  delay(1000);
}

Kapcsolódás wifi hálózatokhoz

Az ESP8266-01 fejezetben leírtak itt is használhatóak. Próbáljuk ki pl. a nap idézete példát: ez minden probléma nélkül ki fogja írni a soros portra a letöltött mondatokat.

NodeMCU

Áttekintés

Ha mindenképpen ESP8266-ot szeretnénk programozni minél natívabb módon, akkor a NodeMCU egy jó választás. A processzora megegyezik ugyanis a fentivel, ennek viszont (az Arduino UNO-hoz hasonlóan) már 32 lába van. Jóval kisebb mint az Arduino UNO, így méretre nem is kompatibilis vele. A lábak kezeléséhez a lapkára írt kódokat használjuk, mint a fenti WeMos példában. Az Arduino UNO-val ellentétben nem anyák, hanem apák vannak rajta, ráadásul a hátoldalán, így kissé nehézkes, vagy legalábbis szokatlan a használata. A WeMos-hoz hasonlóan itt is USB töltős kábelt kell használnunk, és itt se mindegy, melyiket. Az ESP8266 meghajtók feltelepítését követően a NodeMCU 1.0-t válasszuk ki, majd a portot is. A feltöltés kifejezetten lassú, így tanulási célra ez nem alkalmas. Ráadásul még beépített LED sincs rajta, csak egy, amelyik az adatátvitelt mutatja. Ugyanakkor előnye ennek az ára: olcsóbb mint az Arduino UNO.

Teszteléshez alakítsuk ki a WeMos-nál vázolt áramkört, és töltsük fel az ottani kódot. Ha mindent jól csináltunk, villogó LED-et kapunk.

Lábkiosztás

A tervezőket - úgy tűnik - komolyan foglalkoztatta a kérdés, hogy miért lenne könnyű az élet, ha bonyolítani is lehetne, aminek az eredménye az lett, hogy a lábkiosztás programozása nehézkessé vált. Lássuk a következő ábrát!

NodeMCU_pinout.png

Az egyes lába elérése az a szám, ami a GPIO után található. Ha tehát a D0-val jelölt, jobb felső lábat szeretnénk vezérelni, akkor az Arduino-ban a 16-os lábat kell használnunk. A NodeMCU -> Arduino leképezés az alábbi:

  • D0 -> 16
  • D1 -> 5
  • D2 -> 4
  • D3 -> 0
  • D4 -> 2
  • D5 -> 14
  • D6 -> 12
  • D7 -> 13
  • D8 -> 15
  • RX -> 3
  • TX -> 1
  • A0 -> A0
  • S3 -> 10
  • S2 -> 9

DHT példa

Az alap Arduino könyvtárak nem mindig működnek az ESP8266 családdal, például a népszerű DHT érzékelőé sem, ezt viszont elkészítették ESP8266-ra. A következő programoz telepítsük a DHT sensor library for ESPx nevű könyvtárat. Bekötés:

  • DHT11 - -> NodeMCU G
  • DHT11 középső -> NodeMCU 3V
  • DHT11 S -> NodeMCU D4

(A kiosztás olyan, hogy egymás mellé tudjuk helyezni a kábeleket.)

Kód:

#include "DHTesp.h"
 
DHTesp dht;
 
void setup() {
  Serial.begin(115200);
  dht.setup(2, DHTesp::DHT11);
}
 
void loop() {
  Serial.print(dht.getHumidity(), 1);
  Serial.print("%, ");
  Serial.print(dht.getTemperature(), 1);
  Serial.println("°C");
  delay(2000);
}

Teszt: nyissuk meg a soros monitort, közben változtassunk a hőmérsékletes és/vagy páratartalmon, pl. azzal, hogy rálehelünk az érzékelőre.

Kapcsolódás wifi hálózatokhoz

Hasonlóan a WeMos-hoz, az ESP8266-01 fejezetben leírtak itt is használhatóak.

Kapcsolat két eszköz között wifi-n keresztül

Az Arduino oldalon van egy fejezet, amely az Arduino eszközök közötti kommunikációs csatornákról szól. A wifi a lehetőségek közül a legnehezebb, ugyanakkor ez rejti magában a legnagyobb potenciált. Ebben a fejezetben egy klasszikus, látszólag egyszerű példát láthatunk, melyben az egyik eszköz időjárás adatokat mér, azt publikálja wifin keresztül, melyre egy másik rácsatlakozik, és LCD-n kiírja az eredményt. A "Lego kockák" már rendelkezésre állnak, viszont amint azt már láthattuk, igen sok nehézséggel kellett megküzdenünk.

A példában a szerver egy NodeMCU lesz, melyre egy DHT időjárás szenzort csatlakoztatunk. A kliens először egy Arduino UNO és egy ESP8266-01 összekapcsolásából keletkező páros lesz, melyben az Arduino-ra egy 2x16 soros LCD kijelzőt kötünk, majd egyszerűsítjük azt WeMos-szal. Lássuk!

NodeMCU wifi szerver létrehozása

Ebben a részben a már elkezdett időjárásos példát fejlesztjük tovább úgy, hogy wifi szerverként üzemeljen, és webes felületen tudjuk lekérdezni a páratartalmat és hőmérsékletet. A bekötés ugyanaz, mint amit korábban megadtunk, és az ott megadott könyvtárat is be kell állítani. A kódot a következőképpen egészítsük ki:

#include <ESP8266WiFi.h>
#include <DHTesp.h>
 
DHTesp dht;
WiFiServer server(80);
 
void setup() {
  dht.setup(2, DHTesp::DHT11);
  WiFi.mode(WIFI_AP);
  WiFi.softAP("NodeMCU", "12345678");
  server.begin();
}
 
void loop() {
  WiFiClient client = server.available();
  if (!client) { 
    return; 
  }
  client.println("Humidity: " + String(dht.getHumidity()) + "%");
  client.println("Temp.: " + String(dht.getTemperature()) + " C");
  delay(1);
}

Teszt: kapcsolódjunk bármelyik eszközünkkel a kódban megadott wifi hálózatra, a kódban megadott jelszóval, majd nyissuk meg egy böngészőből a 192.168.4.1 oldalt.

Kliens Arduino UNO-val és ESP8266-01-gyel

Ebben a példában az ESP8266-01 rákapcsolódik a fenti wifi szerverre, 2 másodpercenként kiolvassa az adatokat, és soros porton keresztül továbbítja az Arduino UNO-nak. Ez utóbbi beolvassa és egy 2x16 karakteres LCD kijelzőn megjeleníti.

Bekötés:

  • Az Arduino UNO-t a fent bemutatott módon kössük össze az ESP8266-tal (TX-RX, RX-TX).
  • Az Arduino UNO-ra az Arduino oldalon bemutatott módon kapcsoljuk a karakteres LCD kijelzőt (SCL - A5, SDL - A4, VCC - 5V, GND - GND).

Az ESP8266 kódja:

#include <ESP8266WiFi.h>
 
const char* ssid = "NodeMCU";
const char* password = "12345678";
 
void setup() {
  Serial.begin(9600);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
  }
}
 
void loop() {
  WiFiClient client;
  client.connect("192.168.4.1", 80);
  while (client.available() == 0) {}
  while (client.available()) {
    String line = client.readStringUntil('\r');
    Serial.print(line);
  }
  client.stop();
  delay(2000);
}

Az Arduino UNO kódja:

#include <SoftwareSerial.h>
#include <LiquidCrystal_I2C.h>
 
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
SoftwareSerial espSerial(5, 6); // RX, TX
 
void setup() {
  lcd.begin(16, 2);
  Serial.begin(9600);
  espSerial.begin(9600);
  delay(100);
  lcd.clear();
}
 
String humidity;
String temperature;
 
void loop() {
  if (espSerial.available()) {
    humidity = espSerial.readStringUntil('\n');
    temperature = espSerial.readStringUntil('\n');
    if (!humidity.equals("") && !temperature.equals("")) {
      Serial.println(temperature);
      Serial.println(humidity);
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print(humidity);
      lcd.setCursor(0, 1);
      lcd.print(temperature);
    }
  }
  delay(100);
}

A Serial. kezdetű sorok törölhetőek, azok valójában tesztelési céllal maradtak benne: a soros monitoron keresztül figyelhetjük a kapott adatokat. A tapasztalat szerint minden második beolvasás üres, emiatt van az üres string ellenőrzés. (Az okára nem sikerült rájönnöm.) Valamint ez sem stabil; néhány beolvasást követően értelmezhetetlen karakterek jelennek meg az LCD kijelzőn. Kipróbálásra viszont megfelelő.

WeMos időjárás kliens

Láthattuk, hogy az Arduino UNO és az ESP8266-01 kombinációjából kialakított kliens igen nehézkesen működik: már maga a kapcsolás is bonyolult, a kód számos nehézséget rejt magában, és a feltöltés is nehézkes és lassú. Ugyanez WeMos-szal lényegesen egyszerűbb. A megadott módon kössük a WeMos-ra az LCD kijelzőt; itt ráadásul a jelzések is segítenek, ugyanis rá van írva a lapkára, hogy melyik az SCA és melyik az SDL, nem kell keresni. Az alábbi programot töltsük fel:

#include <ESP8266WiFi.h>
#include <LiquidCrystal_I2C.h>
 
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
 
const char* ssid = "NodeMCU";
const char* password = "12345678";
 
void setup() {
  Serial.begin(9600);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
  }
  lcd.begin(16, 2);
  lcd.clear();
  delay(100);
}
 
String humidity;
String temperature;
 
void loop() {
  WiFiClient client;
  client.connect("192.168.4.1", 80);
  while (client.available() == 0) {}
  while (client.available()) {
    humidity = client.readStringUntil('\r');
    client.read();
    temperature = client.readStringUntil('\r');
    client.read();
    Serial.println(temperature);
    Serial.println(humidity);
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print(humidity);
    lcd.setCursor(0, 1);
    lcd.print(temperature);
  }
  client.stop();
  delay(2000);
}

A páratartalom és a hőmérséklet beolvasás után is beolvasunk egy-egy bájtot. Ennek az az oka, hogy a \r (kocsi vissza) karakterig olvassuk be, a \n (új sor) viszont ezt követően jön, ami a következő beolvasáskor szemétként jelenik meg; valójában ezt a bájtot olvassuk be ezzel az extra beolvasással. Ha mindent jól csináltunk, akkor megjelenik a kijelzőn a páratartalom és a hőmérséklet.

Összefoglalás

Láthatjuk tehát, hogy a fejezet felvezetőjében vázolt, egyszerűnek tűnő feladatot nem is olyan egyszerű megvalósítani. Az alábbi problémák kezelésével órák, napok mentek el, és adott esetben hónapok teltek el, mire sikerült eljutnom a megoldásig:

  • A DHT könyvtár alapból nem kompatibilis az ESP8266-tal.
  • Az ESP8266-01 programozásához külön áramkörre vagy programozóra van szükség. A programozóra rá kell forrasztani egy kábelt.
  • Az Arduino UNO és az ESP8266-01 nem képes stabilan kommunikálni az alapértelmezett 115200 rátán, azt érdemes 9600-ra lecsökkenteni.
  • Elég sok idő elment azzal is, mire sikerült megtalálni a megfelelő soros író-olvasó utasításokat, mert sokféle van, de nem mindegyik alkalmas a fenti feladat megvalósítására.

Néhány fent említett probléma megoldása még várat magára, sőt, reális annak az esélye, hogy nem térek vissza rá. Ugyanis ismerkedési, oktatási céllal ebben az állapotában is megfelelő, üzemszerű használathoz viszont nem érdemes Arduino-ra kötött ESP8266-01-et használnunk, hanem (az egyébként olcsóbb) NodeMCU-t vagy a WeMos-t.

A fenti leírásból azt gondolom egyértelműen kijelenthetjük, hogy az ESP8266 gyakorlatilag egy, az Arduino-tól független világ, úgy is érdemes kezelni.

Sonoff

A Sonoff tulajdonképpen egy gyakorlati okos otthon megvalósítás, ami tartalmaz egy wifire is kapcsolódni képes processzort és egy relét. Közvetlenül programozni nem tudjuk, vagy legalábbis nem arra tervezték, így egy kicsit kilóg a sorból, ugyanakkor mint gyakorlati alkalmazás, itt a helye. Segítségével mobiltelefonról, távolról tudjuk vezérelni az otthonunkat. A legolcsóbb megoldás kb. 5$-ba kerül, ebben az esetben viszont nekünk is kell tennünk pár lépést, hogy működésre bírjuk.

A gyári firmware használata

A következő lépéseket hajtsuk végre, értelemszerűen áramtalanított állapotban:

  • Vágjunk ketté egy hosszabbítót. Kössük be a következő módon: fázis a fázishoz (barna vagy fekete kábel), nulla a nullához (kék), a földelést (zöld-sárga) pedig közvetlenül. (Ha ügyesek vagyunk, akkor ezt utóbbit ne is vágjuk el).
  • Telepítsük fel az eWeLink nevű mobil alkalmazást.
  • Regisztráljunk (ehhez szükségünk van egy működőképes, "kéznél levő" e-mail címre, annál is inkább, mert küld egy 4 jegyű megerősítő számot, amit 1 percen belül be kell írnunk), majd lépjünk be.
  • Dugjuk áramra a hosszabbítót, melyre a Sonoff-ot helyeztük. Igyekezzünk nem meghalni áramütés miatt.
  • Nyomjuk meg a Sonoff-on levő gombot kb. 7 másodpercig, amíg zölden nem kezd villogni. (Ez a leírás arra az esetre vonatkozik, ha nem egyenletesen villog.)
  • Kattintsunk a fő képernyőn lent a + gombra, majd válasszuk ki a Quick Pairing-et.
  • Szükség van egy wifi hálózatra, amire csatlakozik a Sonoff, ráadásul ennek jelszavát is meg kell adni. (Ez az a lépés, ami miatt sokan visszariadnak a használatától, és saját firmware-t használnak.) Válasszuk ki tehát a wifi-t és adjuk meg a jelszót.
  • Várjunk a kapcsolódáshoz. (Először nem ment. Közelebb mentem a wifihez, valamint felkapcsoltam a mobilon a bluetooth-t, és utána már működött.)
  • Végül adjunk a kapcsolatban egy nevet.
  • Kapcsoljunk fel valamit, pl. villanyt, és dugjuk rá a hosszabbító végére. Elvileg most még nem működik.
  • Az eWeLink alkalmazásban kattintsunk az imént beállított eszköz kapcsolójára. Ha mindent jól csináltunk, akkor a villany felkapcsolódik. Ezt elvileg a világ tetszőleges pontjáról végre tudjuk hajtani!

A Tasmota firmware feltöltése

TODO: kipróbálni és leírni

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License