Rozdíly
Zde můžete vidět rozdíly mezi vybranou verzí a aktuální verzí dané stránky.
| Následující verze | Předchozí verze | ||
| it:iot:baxi:arduino-wemos-d1-r2-uno-esp8266 [2023/12/03 19:37] – vytvořeno Petr Nosek | it:iot:baxi:arduino-wemos-d1-r2-uno-esp8266 [2024/01/01 21:19] (aktuální) – Petr Nosek | ||
|---|---|---|---|
| Řádek 37: | Řádek 37: | ||
| + | ===== Začátky s vývojovou destičkou Wemos ===== | ||
| + | |||
| + | Při zprovozňování destičky mi pomohly tyto návody: | ||
| + | |||
| + | * https:// | ||
| + | * https:// | ||
| + | * https:// | ||
| + | |||
| + | |||
| + | {{youtube> | ||
| + | |||
| + | |||
| + | ==== Instalace vývojového prostředí Arduino IDE ==== | ||
| + | |||
| + | Na [[https:// | ||
| + | |||
| + | Uživatel, který spouští Arduino IDE musí být ve skupině **dialout**. Po rozbalení stačí spustit | ||
| + | |||
| + | <code bash> | ||
| + | ./ | ||
| + | </ | ||
| + | |||
| + | {{: | ||
| + | |||
| + | |||
| + | === Zprovoznění programování ESP8266 skrze Arduino IDE === | ||
| + | |||
| + | Nejprve zvolit menu Soubor -> vlastnosti | ||
| + | |||
| + | {{: | ||
| + | |||
| + | V nastavení přidat správce dalších desek tuto URL: http:// | ||
| + | |||
| + | {{: | ||
| + | |||
| + | |||
| + | Skrze odkaz umožníme do prostředí IDE přidat podporu pro ESP8266. | ||
| + | |||
| + | Skrze menu **Tools -> Board -> Board Manager** přidat destičky ESP8266. Napsat **esp8266** a nainstalovat. | ||
| + | |||
| + | {{: | ||
| + | |||
| + | |||
| + | Jakmile je destička nainstalovaná, | ||
| + | |||
| + | Pak je možné připojit přes USB kabel zařízení, | ||
| + | |||
| + | {{: | ||
| + | |||
| + | |||
| + | |||
| + | === Program blikání LED diod === | ||
| + | |||
| + | Jako první ukázkový program je připraveno blikání dvěma dostupnými LED diodami. První LED dioda je přímo na modulu, ke které máme přístup v Arduino IDE přes klíčové slovo LED_BUILTIN. Tato LED dioda je zvláštní v tom, že má obrácenou logiku řízení, tedy pokud jí chceme zapnout, je nutné na ní přivést logickou nulu. Druhá LED dioda je připojena na pin 14 a je řízena klasickým způsobem. Po nastavení obou LED diod jako výstupních v podprogramu setup se přesuneme rovnou na nekonečnou smyčku loop, kde jako první blikneme rychleji vestavěnou LED diodou a následně blikneme pomaleji LED diodou na pinu 14. | ||
| + | |||
| + | <code c> | ||
| + | // ESP8266 blikání dvou LED diod | ||
| + | |||
| + | // nastavení propojovacího pinu LED diody | ||
| + | #define LEDka 14 | ||
| + | |||
| + | void setup() { | ||
| + | // nastavení obou LED diod jako výstupních | ||
| + | pinMode(LED_BUILTIN, | ||
| + | pinMode(LEDka, | ||
| + | } | ||
| + | |||
| + | void loop() { | ||
| + | // blikání vestavěnou diodou na ESP, | ||
| + | // pro zapnutí musíme přivést logickou 0 - LOW | ||
| + | digitalWrite(LED_BUILTIN, | ||
| + | delay(500); | ||
| + | digitalWrite(LED_BUILTIN, | ||
| + | delay(500); | ||
| + | // blikání LED diodou na desce, | ||
| + | // pro zapnutí musíme přivést logickou 1 - HIGH | ||
| + | digitalWrite(LEDka, | ||
| + | delay(1000); | ||
| + | digitalWrite(LEDka, | ||
| + | delay(1000); | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | |||
| + | === Program skenování Wi-Fi sítí === | ||
| + | |||
| + | Druhý ukázkový program už je praktičtější a obsahuje skener WiFi sítí v okolí modulu ESP8266. Program na začátku obsahuje připojení potřebné knihovny a poté v podprogramu setup jako první nastavení komunikace po sériové lince. Pro úspěšné vyhledávání WiFi sítí je nutné jako další krok nastavit WiFi modul do módu stanice a pro jistotu provést odpojení od jakékoliv sítě. V nekonečné smyčce loop vytiskneme informaci o zahájení skenování po sériové lince a následně načteme do vytvořené proměnné počet sítí v okolí včetně všech dostupných informací o těchto sítích. Poté zkontrolujeme počet načtených sítí a v případě nuly pouze vypíšeme informaci o nedostupnosti viditelných sítí. Pokud ale máme nějaké sítě v dosahu, provedeme v následujících řádcích vytištění informací o nich. Jako první tedy vytiskneme celkový počet načtených sítí a následně pomocí for smyčky vytiskneme pro každou WiFi síť její název, sílu signálu a druh zabezpečení. Na konci celého programu pak už jen vyčkáme pět vteřin před novým načtením seznamu sítí. | ||
| + | |||
| + | <code c> | ||
| + | // ESP8266 WiFi skener | ||
| + | |||
| + | // připojení potřebné knihovny | ||
| + | #include " | ||
| + | |||
| + | void setup() { | ||
| + | // zahájení komunikace po sériové lince | ||
| + | Serial.begin(9600); | ||
| + | // nastavení WiFi do módu stanice a odpojení od předchozí sítě | ||
| + | WiFi.mode(WIFI_STA); | ||
| + | WiFi.disconnect(); | ||
| + | delay(100); | ||
| + | } | ||
| + | |||
| + | void loop() { | ||
| + | Serial.println(" | ||
| + | // načtení WiFi sítí v okolí a uložení jejich počtu do proměnné | ||
| + | int n = WiFi.scanNetworks(); | ||
| + | // v případě nulového počtu sítí vypíšeme informaci | ||
| + | // po sériové lince | ||
| + | if (n == 0) { | ||
| + | Serial.println(" | ||
| + | } | ||
| + | // pokud byly nalezeny WiFi sítě v okolí, | ||
| + | // vypíšeme jejich počet a další informace | ||
| + | else { | ||
| + | Serial.print(n); | ||
| + | Serial.println(" | ||
| + | // výpis všech WiFi sítí v okolí, | ||
| + | // vypíšeme název, sílu signálu a způsob zabezpečení | ||
| + | for (int i = 0; i < n; ++i) | ||
| + | { | ||
| + | Serial.print(i + 1); | ||
| + | Serial.print(": | ||
| + | Serial.print(WiFi.SSID(i)); | ||
| + | Serial.print(" | ||
| + | Serial.print(WiFi.RSSI(i)); | ||
| + | Serial.print(" | ||
| + | Serial.println((WiFi.encryptionType(i) == ENC_TYPE_NONE)?" | ||
| + | delay(10); | ||
| + | } | ||
| + | } | ||
| + | // ukončení výpisu | ||
| + | Serial.println("" | ||
| + | // pauza po dobu pěti vteřin před novým skenováním | ||
| + | delay(5000); | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Po nahrání druhého ukázkového kódu do Arduino ESP8266 desky dostaneme například tento výsledek: | ||
| + | |||
| + | < | ||
| + | Zahajeni skenovani.. | ||
| + | 3 WiFi siti v okoli. Seznam: | ||
| + | 1: SilentB (-25)* | ||
| + | 2: ** (-69)* | ||
| + | 3: *** (-74)* | ||
| + | </ | ||
| + | |||
| + | |||
| + | === Program webserver v domácí síti === | ||
| + | |||
| + | Třetí ukázkový kód obsahuje jednoduchý příklad využití ESP jako webserveru v domácí síti. Na začátku programu se nachází připojení všech potřebných knihoven a vytvoření proměnných s uloženým nastavením názvu a hesla pro WiFi síť, do které se budeme připojovat. Jako další je provedena inicializace webserveru na portu 80 a nastaven propojovací pin indikační LED diody. Podprogram zpravaHlavni obsahuje kód, který se provede při přístupu na hlavní stránku. Jako první tedy zapneme LED diodu a poté vytvoříme proměnné s načtením informací o analogové hodnotě z pinu A0 společně s časem od spuštění Arduina. Následně vytvoříme proměnnou se zprávou, do které postupně přidáme všechny chtěné informace. Na konci provedeme příkazem send vytištění zprávy se statusem 200, tedy OK, a vypneme LED diodu. Podprogram zpravaNeznamy funguje obdobným způsobem, jen slouží pro informování o přístupu na neexistující odkaz webserveru. Opět tedy blikneme LED diodou a vypíšeme kompletní informace o neexistujícím odkazu včetně metody a argumentů, s kterými bylo přistupováno. Podprogram setup na svém začátku obsahuje nastavení LED diody jako výstupní společně s jejím vypnutím. Následně zahájíme komunikaci po sériové lince a zahájíme komunikace s WiFi routerem pomocí našich uložených přihlašovacích údajů. Po zahájení následuje while smyčka, která vyčkává na potvrzení připojení a v mezičase tiskne tečky po sériové lince. Jakmile jsme úspěšné připojení, | ||
| + | |||
| + | <code c> | ||
| + | // ESP8266 Web Server | ||
| + | |||
| + | // připojení potřebných knihoven | ||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | |||
| + | // vytvoření proměnných s názvem WiFi sítě a heslem | ||
| + | const char* nazevWifi = " | ||
| + | const char* hesloWifi = " | ||
| + | |||
| + | // incializace webserveru na portu 80 | ||
| + | ESP8266WebServer server(80); | ||
| + | |||
| + | // propojovací pin indikační LED diody | ||
| + | #define LEDka 14 | ||
| + | |||
| + | // podprogram s hlavní zprávou, která je vytištěna | ||
| + | // při zadání IP adresy do prohlížeče | ||
| + | void zpravaHlavni() { | ||
| + | // zapnutí LED diody | ||
| + | digitalWrite(LEDka, | ||
| + | // načtení hodnoty analogového pinu a času | ||
| + | // od spuštění Arduina ve formátu String | ||
| + | String analog = String(analogRead(A0)); | ||
| + | String cas = String(millis()/ | ||
| + | // vytvoření zprávy, která bude vytištěna | ||
| + | // v prohlížeči (\n znamená nový řádek) | ||
| + | String zprava = "Ahoj Arduino svete!\n"; | ||
| + | zprava += " | ||
| + | zprava += analog; | ||
| + | zprava += "\nCas od spusteni Arduina je "; | ||
| + | zprava += cas; | ||
| + | zprava += " vterin."; | ||
| + | // vytištění zprávy se statusem 200 - OK | ||
| + | server.send(200, | ||
| + | // vypnutí LED diody | ||
| + | digitalWrite(LEDka, | ||
| + | } | ||
| + | |||
| + | // podprogram s chybovou zprávou, která je vytištěna | ||
| + | // při zadání IP adresy s neexistující podstránkou | ||
| + | void zpravaNeznamy() { | ||
| + | // zapnutí LED diody | ||
| + | digitalWrite(LEDka, | ||
| + | // vytvoření zprávy s informací o neexistujícím odkazu | ||
| + | // včetně metody a zadaného argumentu | ||
| + | String zprava = " | ||
| + | zprava += "URI: "; | ||
| + | zprava += server.uri(); | ||
| + | zprava += " | ||
| + | zprava += (server.method() == HTTP_GET)?" | ||
| + | zprava += " | ||
| + | zprava += server.args(); | ||
| + | zprava += " | ||
| + | for (uint8_t i=0; i< | ||
| + | zprava += " " + server.argName(i) + ": " + server.arg(i) + " | ||
| + | } | ||
| + | // vytištění zprávy se statusem 404 - Nenalezeno | ||
| + | server.send(404, | ||
| + | // vypnutí LED diody | ||
| + | digitalWrite(LEDka, | ||
| + | } | ||
| + | |||
| + | void setup(void) { | ||
| + | // nastavení LED diody jako výstupní a její vypnutí | ||
| + | pinMode(LEDka, | ||
| + | digitalWrite(LEDka, | ||
| + | // zahájení komunikace po sériové lince | ||
| + | Serial.begin(9600); | ||
| + | // zahájení komunikace po WiFi s připojením | ||
| + | // na router skrze zadané přihl. údaje | ||
| + | WiFi.begin(nazevWifi, | ||
| + | // čekání na úspěšné připojení k routeru, | ||
| + | // v průběhu čekání se vytiskne každých | ||
| + | // 500 milisekund tečka po sériové lince | ||
| + | while (WiFi.status() != WL_CONNECTED) { | ||
| + | delay(500); | ||
| + | Serial.print(" | ||
| + | } | ||
| + | // odřádkování a výpis informací o úspěšném připojení | ||
| + | // včetně přidelené IP adresy od routeru | ||
| + | Serial.println("" | ||
| + | Serial.print(" | ||
| + | Serial.println(nazevWifi); | ||
| + | Serial.print(" | ||
| + | Serial.println(WiFi.localIP()); | ||
| + | // kontrola funkčnosti MDNS | ||
| + | if (MDNS.begin(" | ||
| + | Serial.println(" | ||
| + | } | ||
| + | // nastavení vytištění hlavní zprávy po přístupu | ||
| + | // na samotnou IP adresu | ||
| + | server.on("/", | ||
| + | // pokud chceme vytisknout pouze menší zprávy, není | ||
| + | // nutné je vytvářet v podprogramech jako zpravaHlavni, | ||
| + | // viz. ukázka níže | ||
| + | | ||
| + | // nastavení vytištění jiné zprávy po přístupu na | ||
| + | // podstránku ukazka, tedy např. 10.0.0.31/ | ||
| + | server.on("/ | ||
| + | String zprava = " | ||
| + | server.send(200, | ||
| + | }); | ||
| + | // nastavení vytištění informací o neznámém | ||
| + | // odkazu pomocí podprogramu zpravaNeznamy | ||
| + | server.onNotFound(zpravaNeznamy); | ||
| + | // zahájení aktivity HTTP serveru | ||
| + | server.begin(); | ||
| + | Serial.println(" | ||
| + | } | ||
| + | |||
| + | void loop(void) { | ||
| + | // pravidelné volání detekce klienta, | ||
| + | // v případě otevření stránky se provedou | ||
| + | // funkce nastavené výše | ||
| + | server.handleClient(); | ||
| + | delay(10); | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | |||
| + | Po nahrání třetího ukázkového kódu do Arduino ESP8266 desky dostaneme například tento výsledek v Sériovém monitoru a v prohlížeči při přístupu na samotnou IP adresu: | ||
| + | |||
| + | < | ||
| + | Pripojeno k WiFi siti SilentB | ||
| + | IP adresa: 10.0.0.31 | ||
| + | MDNS responder je zapnuty. | ||
| + | HTTP server je zapnuty. | ||
| + | Ahoj Arduino svete! | ||
| + | Analogovy pin A0: 3 | ||
| + | Cas od spusteni Arduina je 54 vterin. | ||
| + | </ | ||
| + | |||
| + | |||
| + | |||
| + | ==== Připojení k zabezpečenému MQTT ==== | ||
| + | |||
| + | Toto už jsem připravoval vlastní kód. Je to základní kód pro připojení k MQTT serveru. Tady je chování: | ||
| + | |||
| + | * připojí se k nadefinované Wi-Fi. Pokud dojde k výpadku Wi-Fi, tak se pokouší znovu připojit. Měl by se o to pokoušet do té doby, dokud se nepodaří spojení obnovit. | ||
| + | * poté se připojí k MQTT serveru. Opět může docházet k výpadkům MQTT serveru, takže se kód postará o vytvoření nového připojení. | ||
| + | * připojení k MQTT je zabezpečeno pomocí [[it: | ||
| + | * program zapne LED diodu na zařízení a posílá zprávu každou vteřinu do MQTT kanálu | ||
| + | |||
| + | Program řeší základní problematiku navázání a obnovení síťových spojení. | ||
| + | |||
| + | <code cpp> | ||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | |||
| + | |||
| + | #include " | ||
| + | #include " | ||
| + | #include " | ||
| + | |||
| + | |||
| + | const char* WiFiName = " | ||
| + | const char* WiFiPassword = " | ||
| + | |||
| + | |||
| + | // MQTT connection | ||
| + | const char* clientName = " | ||
| + | const char* mqttBroker = " | ||
| + | const int mqttPort = 8883; | ||
| + | const char* mqttUser = " | ||
| + | const char* mqttPassword = " | ||
| + | const char* mqttTopic = " | ||
| + | |||
| + | |||
| + | #define LED_SCK 14 | ||
| + | |||
| + | WiFiClientSecure espClient; | ||
| + | PubSubClient mqttClient(espClient); | ||
| + | |||
| + | |||
| + | void setupWiFi() { | ||
| + | | ||
| + | | ||
| + | WiFi.mode(WIFI_STA); | ||
| + | WiFi.begin(WiFiName, | ||
| + | | ||
| + | // connect to WiFi | ||
| + | Serial.print(" | ||
| + | | ||
| + | // wait for connecting to the server | ||
| + | // during this waiting it will write dot to serial link | ||
| + | while (WiFi.status() != WL_CONNECTED) { | ||
| + | delay(500); | ||
| + | Serial.print(" | ||
| + | } | ||
| + | |||
| + | // write new line, Wi-Fi network and IP address of connection | ||
| + | Serial.println("" | ||
| + | Serial.print(" | ||
| + | Serial.println(WiFiName); | ||
| + | Serial.print(" | ||
| + | Serial.println(WiFi.localIP()); | ||
| + | |||
| + | WiFi.setAutoReconnect(true); | ||
| + | WiFi.persistent(true); | ||
| + | |||
| + | } | ||
| + | |||
| + | |||
| + | |||
| + | |||
| + | void reconnectMQTT() { | ||
| + | |||
| + | int retryCount = 0; | ||
| + | |||
| + | while (!mqttClient.connected()) { | ||
| + | |||
| + | Serial.println(" | ||
| + | |||
| + | // SSL/TLS certificate and key settings | ||
| + | // The BearSSL:: | ||
| + | // for the duration of their usage by espClient. If these objects are defined | ||
| + | // within a separate function and used here, they will be destroyed when that | ||
| + | // function exits, leading to undefined behavior and potential device resets. | ||
| + | // A solution to this is to declare them as global variables if they need to | ||
| + | // be used across multiple functions. | ||
| + | BearSSL:: | ||
| + | BearSSL:: | ||
| + | BearSSL:: | ||
| + | |||
| + | |||
| + | espClient.setInsecure(); | ||
| + | // | ||
| + | espClient.setClientRSACert(& | ||
| + | |||
| + | mqttClient.setServer(mqttBroker, | ||
| + | |||
| + | |||
| + | if (mqttClient.connect(clientName, | ||
| + | Serial.println(" | ||
| + | // Subscribe to topics here if necessary | ||
| + | // mqttClient.subscribe(" | ||
| + | } else { | ||
| + | Serial.print(" | ||
| + | Serial.print(mqttClient.state()); | ||
| + | Serial.println(" | ||
| + | delay(5000); | ||
| + | |||
| + | retryCount++; | ||
| + | |||
| + | if (retryCount > 5) { // Restart the ESP if it fails to connect 5 times | ||
| + | // | ||
| + | } | ||
| + | |||
| + | } | ||
| + | } | ||
| + | |||
| + | } | ||
| + | |||
| + | |||
| + | |||
| + | void setup() { | ||
| + | |||
| + | // put your setup code here, to run once: | ||
| + | |||
| + | // set LED diode as OUTPUT a turn on the diode | ||
| + | pinMode(LED_SCK, | ||
| + | |||
| + | // start communication on serial line | ||
| + | Serial.begin(9600); | ||
| + | |||
| + | setupWiFi(); | ||
| + | | ||
| + | reconnectMQTT(); | ||
| + | |||
| + | } | ||
| + | |||
| + | |||
| + | void loop() { | ||
| + | // put your main code here, to run repeatedly: | ||
| + | |||
| + | if (!mqttClient.connected()) { | ||
| + | reconnectMQTT(); | ||
| + | } | ||
| + | mqttClient.loop(); | ||
| + | |||
| + | // Odesílání zprávy každou vteřinu | ||
| + | static unsigned long lastMsg = 0; | ||
| + | unsigned long now = millis(); | ||
| + | if (now - lastMsg > 1000) { | ||
| + | lastMsg = now; | ||
| + | // Tvořte zde svou zprávu | ||
| + | const char* message = "Hello MQTT"; | ||
| + | mqttClient.publish(mqttTopic, | ||
| + | } | ||
| + | |||
| + | |||
| + | } | ||
| + | |||
| + | </ | ||