ESP8266 MQTT – przykładowy kod Arduino, TLS, JSON, reconnect, NodeMCU, Wemos D1 Mini

Pytanie

esp8266 mqtt przykład kodu

Odpowiedź Sztucznej Inteligencji


Bezpośrednia odpowiedź na pytanie

  • Poniżej znajdziesz kompletny, gotowy do wgrania przykład kodu Arduino-C++ dla ESP8266 (NodeMCU/Wemos D1 Mini) pokazujący:
    • łączenie z Wi-Fi,
    • bezpieczne (TLS) i niezabezpieczone połączenie z brokerem MQTT,
    • subskrypcję i publikację wiadomości (także w formacie JSON),
    • obsługę automatycznego ponownego łączenia.
  • Kod bazuje na aktualnych bibliotekach ESP8266WiFi.h, WiFiClientSecure.h, PubSubClient.h (stabilna gałąź 2024-Q1).

Szczegółowa analiza problemu

1. Konfiguracja sprzętowo-programowa

  1. Płytka: dowolny moduł z układem ESP8266 (ESP-12E, NodeMCU 1.0, Wemos D1 Mini).
  2. Arduino IDE ≥ 2.2 lub PlatformIO, pakiet „esp8266 by ESP8266 Community” (aktualna wersja 3.1.2).
  3. Biblioteki:
    • PubSubClient 2.8.0 (szybkie, blokujące, QoS 0/1) ‑ przykład poniżej,
    • (alternatywa) AsyncMqttClient 0.8.2 ‑ zdarzeniowa, nieblokująca.
  4. Broker: lokalny Mosquitto ≥ 2.0 lub publiczny broker.emqx.io, broker.hivemq.com (port 1883 dla plain-TCP, 8883 dla TLS).

2. Kompletny kod (wersja produkcyjna, obsługa TLS / JSON / LED)

/*
 * ESP8266  ↔  MQTT  (TLS + JSON + reconnect + LED demo)
 * autor: inż. elektronik 2024-04
 * zależności: ESP8266WiFi, WiFiClientSecure, PubSubClient, ArduinoJson
 */
// ==================== USTAWIENIA UŻYTKOWNIKA ====================
const char* WIFI_SSID      = "TwojaSiecWiFi";
const char* WIFI_PASS      = "HasloWiFi";
// broker – wybierz jedną z opcji:
const char* MQTT_HOST      = "broker.emqx.io";   // publiczny
const uint16_t MQTT_PORT   = 8883;               // 1883 – bez TLS, 8883 – TLS
const char* MQTT_USER      = "emqx";             // "" jeśli niepotrzebne
const char* MQTT_PASS      = "public";           // "" jeśli niepotrzebne
// ścieżki tematów
const char* TOPIC_SUB      = "home/esp8266/cmd";
const char* TOPIC_PUB      = "home/esp8266/state";
// GPIO do demonstracji (LED wbudowana w NodeMCU = GPIO2)
const uint8_t LED_PIN      = LED_BUILTIN;
// ================================================================
#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>
// --------- obiekt transportu ---------
WiFiClientSecure net;       // dla TLS; przy połączeniu plain użyj „WiFiClient net;”
PubSubClient     mqtt(net); // klient MQTT
// --------- zmienne pomocnicze ---------
unsigned long lastSend  = 0;
uint32_t       counter  = 0;
void connectWiFi()
{
  Serial.printf("\nŁączenie z Wi-Fi  %s … ", WIFI_SSID);
  WiFi.mode(WIFI_STA);
  WiFi.begin(WIFI_SSID, WIFI_PASS);
  uint8_t retries = 20;
  while (WiFi.status() != WL_CONNECTED && retries--) {
    delay(500); Serial.print('.');
  }
  if (WiFi.status() != WL_CONNECTED) {
    Serial.println("\n[!] Brak Wi-Fi – restart");
    ESP.restart();
  }
  Serial.printf("\n✓  Wi-Fi OK, IP=%s RSSI=%ddBm\n",
                WiFi.localIP().toString().c_str(), WiFi.RSSI());
}
void connectMQTT()
{
  // --- bezpieczne połączenie TLS ---
  net.setInsecure();         // uproszczenie: brak weryfikacji certyfikatu
  // → w projekcie produkcyjnym zamiast setInsecure() wgraj CA lub fingerprint
  mqtt.setServer(MQTT_HOST, MQTT_PORT);
  mqtt.setCallback([](char* topic, byte* payload, unsigned int len)
  {
    String msg;
    for (uint16_t i=0;i<len;i++) msg += (char)payload[i];
    Serial.printf("⬇ [%s] %s\n", topic, msg.c_str());
    if (String(topic)==TOPIC_SUB) {
      if (msg=="LED_ON")  digitalWrite(LED_PIN, LOW);
      if (msg=="LED_OFF") digitalWrite(LED_PIN, HIGH);
    }
  });
  while (!mqtt.connected()) {
    Serial.print("MQTT – próba połączenia… ");
    String cid = "ESP8266-" + String(ESP.getChipId(), HEX);
    bool ok = (strlen(MQTT_USER))
                ? mqtt.connect(cid.c_str(), MQTT_USER, MQTT_PASS,
                               "home/esp8266/lwt", 0, true, "offline")
                : mqtt.connect(cid.c_str());
    if (ok) {
      Serial.println("✓");
      mqtt.publish("home/esp8266/lwt", "online", true);
      mqtt.subscribe(TOPIC_SUB);
    } else {
      Serial.printf("błąd rc=%d; powtórka za 5 s\n", mqtt.state());
      delay(5000);
    }
  }
}
void setup()
{
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, HIGH);   // LED wyłączona (logika odwrócona)
  Serial.begin(115200);
  connectWiFi();
  connectMQTT();
}
void loop()
{
  // utrzymanie sesji
  if (!mqtt.connected()) connectMQTT();
  mqtt.loop();
  // publikacja co 15 s
  if (millis() - lastSend > 15'000) {
    lastSend = millis();
    counter++;
    // payload w JSON
    StaticJsonDocument<200> doc;
    doc["uptime"]    = millis()/1000;
    doc["counter"]   = counter;
    doc["rssi"]      = WiFi.RSSI();
    String json;
    serializeJson(doc, json);
    mqtt.publish(TOPIC_PUB, json.c_str());
    Serial.printf("⬆ publikuje: %s\n", json.c_str());
  }
}

Kluczowe elementy:

  1. WiFiClientSecure net + setInsecure() → szybki start z TLS; w produkcie dostarcz certyfikat CA lub fingerprint.
  2. LWT („Last Will & Testament”) na temacie home/esp8266/lwt – broker opublikuje „offline”, gdy ESP utraci zasilanie.
  3. Payload JSON przygotowany przez ArduinoJson – ułatwia rozszerzanie danych.

3. Alternatywa asynchroniczna (AsyncMqttClient)

Przy wielu tematach lub wymogu maks. responsywności warto przejść na bibliotekę ESPAsyncTCP + AsyncMqttClient – działa zdarzeniowo (non-blocking). Składnia jest inna: rejestrujesz lambdy onMessage, onConnect, a funkcja loop() staje się niepotrzebna.

Aktualne informacje i trendy

  • MQTT v5.0 (2019) zyskuje wsparcie w nowszych brokerach (Mosquitto 2.x, EMQX 5.x). Biblioteka MQTTClient (256-by-Matthias Light) obsługuje v5 i jest portowana na ESP8266.
  • Publiczne brokery (EMQX, HiveMQ) w 2024 roku włączają domyślnie TLS i rate-limiting. W prototypach używaj portu 8883 z certyfikatem – plain 1883 często blokowany w sieciach firmowych.
  • Trend w IoT → lightweight OTA (Over-the-Air update) + MQTT (temat /$fw) do dystrybucji firmware, co redukuje ruch HTTP.

Wspierające wyjaśnienia i detale

  • QoS: PubSubClient obsługuje 0 i 1; jeśli potrzebujesz QoS 2 lub MQTT v5 – przejdź na MQTTClient lub async-mqtt-client.
  • Retained Message: przykładowo mqtt.publish(TOPIC_PUB, msg, true); – idealne do przechowywania ostatniego stanu LED-a.
  • Debug: mqtt.setBufferSize(1024); przy większych payloadach (np. struktury JSON > 256 B).
  • Bezpieczeństwo: fingerprint SHA-1 wygenerujesz:
    openssl x509 -in letsencrypt.pem -noout -fingerprint -sha1

Aspekty etyczne i prawne

  • Danych osobowych (np. lokalizacja, biometria) nie wysyłaj przez publiczny broker – obowiązuje RODO.
  • Przy pracy w pasmach nielicencjonowanych (2,4 GHz) pamiętaj o limicie EIRP 100 mW w UE.
  • Gdy urządzenie steruje elementami wykonawczymi (grzałki, siłowniki) – wymagania bezpieczeństwa funkcjonalnego (EN IEC 60730, IEC 61508).

Praktyczne wskazówki

  1. Diagnoza sieci: mosquitto_sub -h broker.emqx.io -t "home/esp8266/#" -v – sprawdzisz komunikację zanim napiszesz UI.
  2. OTA: włącz ArduinoOTA albo ESP8266HTTPUpdateServer, żeby aktualizować firmware bez kabli.
  3. Watchdog: dodaj ESP.wdtFeed(); w obszernych pętlach lub aktywuj WDT hardware (domyślnie ~8 s).
  4. Energooszczędność: tryb WiFi.setSleepMode(WIFI_LIGHT_SLEEP_T); zmniejsza pobór ~60 mA → ~20 mA (kosztem latencji MQTT).

Ewentualne zastrzeżenia lub uwagi dodatkowe

  • PubSubClient blokuje CPU podczas połączenia; przy integracji z paskami LED WS2812 lub czujnikiem DHT z długimi czasami bit-bang może wystąpić dropout Wi-Fi – wtedy wybierz AsyncMqttClient.
  • setInsecure() obniża poziom bezpieczeństwa – do produktu konieczny CA lub PSK.
  • ESP8266 ma ~40 kB RAM-u: JSON > 2 kB może spowodować reset przez heap overflow.

Sugestie dalszych badań

  • MQTT + WebSockets (port 8083) do łatwego podglądu w przeglądarce (JS Paho).
  • Protobuf zamiast JSON (mniej bajtów i RAM), implementacja: nano-pb.
  • Broker na krawędzi (edge) – Eclipse Kura / Azure IoT Edge z przepisywaniem tematów (topic mapping).
  • Ujednolicenie uwierzytelniania: OAuth 2.0 / JWT + TLS mutual (X.509) – trend w przemysłowym IoT.

Krótkie podsumowanie

Zaprezentowany kod stanowi w praktyce pełny szkielet projektu IoT: Wi-Fi → TLS → MQTT → JSON. Używa aktualnych bibliotek 2024 r., uwzględnia LWT, reconnect, payload JSON, a także wskazuje, jak podnieść bezpieczeństwo (TLS, certyfikaty) i wydajność (AsyncMqttClient). Dalsze rozszerzenia obejmują MQTT v5, aktualizacje OTA, Protobuf oraz integrację z edge-computing. W razie szczegółowych pytań (np. połączenie z konkretną chmurą AWS/GCP), zapraszam do dyskusji.

Oceń odpowiedź:

Zadaj dodatkowe pytanie Sztucznej Inteligencji

Czekaj (1min)...
Zastrzeżenie: Odpowiedzi udzielone przez sztuczną inteligencję (model językowy) mogą być niedokładne i wprowadzające w błąd. Elektroda nie ponosi odpowiedzialności za dokładność, rzetelność ani kompletność prezentowanych informacji. Wszystkie odpowiedzi powinny być zweryfikowane przez użytkownika.