it:iot:baxi:arduino-wemos-d1-r2-uno-esp8266

WeMos D1 R2 UNO ESP8266

Verze Arduino UNO, která místo procesoru využívá mikrokontroler a wifi modul ESP8266. Výrazným rozdílem je logika která místo 5V je 3,3V.

Wemos D1 je Wifi vývojová deska, založená na ESP8266EX.

WeMos D1 obsahuje rozložení pinů skoro identické s Arduino UNO. Všechny I/O piny mají přerušení, PWM, I2C a 1-Wire , mimo pin D0.

Deska má USB Micro konektor a USB pro sériový (UART) převodník, takže je jednoduché tuto desku připojit ke svému počítači pomocí USB Micro kabelu.

Destičku jsem koupil zde: https://www.laskakit.cz/wemos-d1-r2-uno-esp8266/

Warning

Pozor - destička používá 3,3 V logiku.

  • Napájecí napětí: 9-24V
  • Pracovní napětí pinů: 3.3V
  • Řadič ESP8266
  • Flash paměť: 4 MB
  • I / O porty: 11
  • PWM výstupy: 10
  • Počet analogových vstupů: 1 (kanál A / C převodníku)
  • Konektor: microUSB
  • Řadič USB - UART: CH340G
  • Kompatibilní s: Arduino IDE a NodeMCU
  • Napájecí konektor: DC 5.5 x 2.1mm
  • Rozměry: 69 x 54 x 15 mm

Na této adrese jsem stáhnul vývojové prostředí Arduino IDE 2.2.1. Zvolil jsem ZIP file pro Linux.

Uživatel, který spouští Arduino IDE musí být ve skupině dialout. Po rozbalení stačí spustit

./arduino-ide

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://arduino.esp8266.com/stable/package_esp8266com_index.json

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á, tak vybrat destičku skrze menu Tools → Board → esp8266 → LOLIN(WEMOS) D1 R2 & mini.

Pak je možné připojit přes USB kabel zařízení, psát kód a odesílat kód skrze tlačítko do 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.

// 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, OUTPUT);
  pinMode(LEDka, OUTPUT);
}
 
void loop() {
  // blikání vestavěnou diodou na ESP,
  // pro zapnutí musíme přivést logickou 0 - LOW
  digitalWrite(LED_BUILTIN, LOW);
  delay(500);
  digitalWrite(LED_BUILTIN, HIGH);
  delay(500);
  // blikání LED diodou na desce,
  // pro zapnutí musíme přivést logickou 1 - HIGH
  digitalWrite(LEDka, HIGH);
  delay(1000);
  digitalWrite(LEDka, LOW);
  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í.

// ESP8266 WiFi skener
 
// připojení potřebné knihovny
#include "ESP8266WiFi.h"
 
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("Zahajeni skenovani..");
  // 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("Zadne viditelne WiFi site v okoli.");
  }
  // pokud byly nalezeny WiFi sítě v okolí,
  // vypíšeme jejich počet a další informace
  else  {
    Serial.print(n);
    Serial.println(" WiFi siti v okoli. Seznam:");
    // 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í, vytiskneme informace o připojení po sériové lince včetně názvu připojené sítě a přidělené IP adrese z routeru. Poté proběhne kontrola MDNS responderu. Jako další je nutné přidělit tištění zpráv k jednotlivým adresám. Pro přístup na IP adresu samotnou tedy například přidělíme volání podprogramu zpravaHlavni. Avšak není nutné pro každou zprávu vytvářet podprogram, proto tedy následuje ukázka s odkazem /ukázka, který obsahuje vytištění krátké zprávy. Pro přístup na jakoukoli jinou nedefinovanou stránku slouží nastavení onNotFound, ke kterému přidělíme náš podprogram zpravaNeznamy. Po veškerém nastavení pak stačí už jen zahájit aktivitu webserveru. Nekonečná smyčka loop v tomto případě obsahuje pouze kontrolování připojených klientů, kdy při detekci klienta už sám program provede veškerou práci skrze nastavení provedená v podprogramu setup.

// ESP8266 Web Server
 
// připojení potřebných knihoven
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
 
// vytvoření proměnných s názvem WiFi sítě a heslem
const char* nazevWifi = "nazev";
const char* hesloWifi = "12345";
 
// 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, HIGH);
  // 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()/1000);
  // vytvoření zprávy, která bude vytištěna
  // v prohlížeči (\n znamená nový řádek)
  String zprava = "Ahoj Arduino svete!\n";
  zprava += "Analogovy pin A0: ";
  zprava += analog;
  zprava += "\nCas od spusteni Arduina je ";
  zprava += cas;
  zprava += " vterin.";
  // vytištění zprávy se statusem 200 - OK
  server.send(200, "text/plain", zprava);
  // vypnutí LED diody
  digitalWrite(LEDka, LOW);
}
 
// 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, HIGH);
  // vytvoření zprávy s informací o neexistujícím odkazu
  // včetně metody a zadaného argumentu
  String zprava = "Neexistujici odkaz\n\n";
  zprava += "URI: ";
  zprava += server.uri();
  zprava += "\nMetoda: ";
  zprava += (server.method() == HTTP_GET)?"GET":"POST";
  zprava += "\nArgumenty: ";
  zprava += server.args();
  zprava += "\n";
  for (uint8_t i=0; i<server.args(); i++){
    zprava += " " + server.argName(i) + ": " + server.arg(i) + "\n";
  }
  // vytištění zprávy se statusem 404 - Nenalezeno
  server.send(404, "text/plain", zprava);
  // vypnutí LED diody
  digitalWrite(LEDka, LOW);
}
 
void setup(void) {
  // nastavení LED diody jako výstupní a její vypnutí
  pinMode(LEDka, OUTPUT);
  digitalWrite(LEDka, LOW);
  // 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, hesloWifi);
  // č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("Pripojeno k WiFi siti ");
  Serial.println(nazevWifi);
  Serial.print("IP adresa: ");
  Serial.println(WiFi.localIP());
  // kontrola funkčnosti MDNS
  if (MDNS.begin("esp8266")) {
    Serial.println("MDNS responder je zapnuty.");
  }
  // nastavení vytištění hlavní zprávy po přístupu
  // na samotnou IP adresu
  server.on("/", zpravaHlavni);
  // 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/ukazka
  server.on("/ukazka", []() {
    String zprava = "Ukazka odkazu pro vice stranek.";
    server.send(200, "text/plain", zprava);
  });
  // 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("HTTP server je zapnuty.");
}
 
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.

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í Self signed certificate. Dále je nakonfigurován MQTT server Mosquitto pro použití uživatelského jména a hesla. Čip ESP8266 nezvládá ověření self signed certifikátu, proto jsem to musel v kódu vypnout. V článku o Self signed certifikátech mám vysvětleno, jak jsem je dostal do kódu pro Arduino.
  • 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í.

#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>
#include <PubSubClient.h>
 
 
#include "client_crt.h"  // client certificate
#include "client_key.h"  // client key
#include "ca_crt.h"  // CA
 
 
const char* WiFiName = "Wifi_IoT";
const char* WiFiPassword = "supersecurepassword";
 
 
// MQTT connection
const char* clientName = "wemos";
const char* mqttBroker = "192.168.0.50";
const int mqttPort = 8883;
const char* mqttUser = "user";
const char* mqttPassword = "users_password";
const char* mqttTopic = "building/room/wemos";
 
 
#define LED_SCK 14
 
WiFiClientSecure espClient;
PubSubClient mqttClient(espClient);
 
 
void setupWiFi() {
 
 
  WiFi.mode(WIFI_STA);
  WiFi.begin(WiFiName, WiFiPassword);
 
  // connect to WiFi
  Serial.print("Connecting to WiFi...");
 
  // 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("Connected to WiFi ");
  Serial.println(WiFiName);
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
 
  WiFi.setAutoReconnect(true);
  WiFi.persistent(true);
 
}
 
 
 
 
void reconnectMQTT() {
 
  int retryCount = 0;
 
  while (!mqttClient.connected()) {
 
    Serial.println("Attempting to connect to MQTT server...");
 
    // SSL/TLS certificate and key settings
    // The BearSSL::X509List and BearSSL::PrivateKey objects must be in scope (alive)
    // 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::X509List cert(cert_der, cert_der_len);
    BearSSL::PrivateKey key(key_der, key_der_len);
    BearSSL::X509List caCert(ca_der, ca_der_len);
 
 
    espClient.setInsecure();
    //espClient.setTrustAnchors(&caCert);  // Setting the CA certification
    espClient.setClientRSACert(&cert, &key);  // Setting the client's cert and key
 
    mqttClient.setServer(mqttBroker, mqttPort);
 
 
    if (mqttClient.connect(clientName, mqttUser, mqttPassword)) {
      Serial.println("Connected");
      // Subscribe to topics here if necessary
      // mqttClient.subscribe("some/topic");
    } else {
      Serial.print("Failed, rc=");
      Serial.print(mqttClient.state());
      Serial.println(" trying again in 5 seconds");
      delay(5000); // 5-second delay between attempts
 
      retryCount++;
 
      if (retryCount > 5) {  // Restart the ESP if it fails to connect 5 times
        //ESP.restart();
      }
 
    }
  }
 
}
 
 
 
void setup() {
 
  // put your setup code here, to run once:
 
  // set LED diode as OUTPUT a turn on the diode
  pinMode(LED_SCK, HIGH);
 
  // 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, message);
  }
 
 
}
  • it/iot/baxi/arduino-wemos-d1-r2-uno-esp8266.txt
  • Poslední úprava: 2024/01/01 22:19
  • autor: Petr Nosek