Rozdíly
Zde můžete vidět rozdíly mezi vybranou verzí a aktuální verzí dané stránky.
Obě strany předchozí revize Předchozí verze Následující verze | Předchozí verze | ||
it:iot:baxi:arduino-wemos-d1-r2-uno-esp8266 [2023/12/03 19:45] – Petr Nosek | it:iot:baxi:arduino-wemos-d1-r2-uno-esp8266 [2024/01/01 21:19] (aktuální) – Petr Nosek | ||
---|---|---|---|
Řádek 44: | Řádek 44: | ||
* https:// | * https:// | ||
* https:// | * https:// | ||
+ | |||
+ | |||
+ | {{youtube> | ||
Řádek 50: | Řádek 53: | ||
Na [[https:// | Na [[https:// | ||
- | Po rozbalení stačí spustit | + | Uživatel, který spouští Arduino IDE musí být ve skupině **dialout**. |
<code bash> | <code bash> | ||
Řádek 59: | Řádek 62: | ||
+ | === 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, | ||
+ | } | ||
+ | |||
+ | |||
+ | } | ||
+ | |||
+ | </ | ||