ESP32 Aszinkron webszerver

Gyakran szükség lehet arra, hogy grafikus felületen kommunikáljunk az ESP32 mikrokontrolleren futó alkalmazásunkkal. Akár konfiguráció módosítása, vagy szenzor értékek megjelenítése, stb. Kézenfekvő megoldás a webböngésző használata, hisz szinte mindíg kéznél van az okostelefonunk. Ehez nyújt segítséget az aszinkron webszerver. Ebben cikkben példákkal szeretném bemutatni az ESPAsyncWebServer könyvtár alkalmazását ESP32 modulon.

Tartalom:

  Bevezetés az ESPAsyncWebServer könyvtár használatába

  Űrlap adatok küldése POST metodus használatával

  Webhely jelszóval védett beállítások oldallal

Bevezetés az ESPAsyncWebServer könyvtár használatába

Az aszinkron webszerver használatához telepíteni kell az ESPAsyncWebServer könyvtárat.  Az AsyncTCP könyvtár az ESPAsyncWebServer függőségeként kell telepíteni A könyvtárak elérhetőek az alábbi linkekre kattintva.

ESPAsyncWebServer könyvtár letöltése

AsyncTCP könyvtár letöltése

Csomagoljuk ki a letöltött fájlokat, töröljük a fájl végéhez hozzáfűzött „-master” szótagot, majd másoljuk át az „…/Arduino/libraries/” mappába.

Ezután indítsuk el/-újra az Arduino IDE-t.

A kódunk elején importáljuk a WiFi.h könyvtárat, valamint a korábban letöltött a fenti két könyvtárat is.

#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>

Ezek után két változót deklarálunk a WiFi hálózat hitelesítő adatainak számára.

const char* ssid = "wifi_ssid";
const char* password = "szupertitkos_jelszavad";

Készítsünk egy példányt az AsyncWebServer objektumból, adjuk meg a portot, ahol a szerver figyelni fog. A 80-as port az alapértelmezett HTTP-port.

AsyncWebServer server(80);

A setup() függvényben elindítjuk a soros kapcsolatot.

Serial.begin(115200);

Kapcsolódunk a Wifi hálózathoz majd kinyomtatjuk az ESP32 IP címét a soros monitorra..

WiFi.begin(ssid, password);

Serial.print("Kapcsolodas a wifi halozathoz.");
while (WiFi.status() != WL_CONNECTED
{
  delay(500);
  Serial.print(".");
}
Serial.println();
Serial.println("Csatlakozva!");
Serial.print("Ip cim: ");
Serial.println(WiFi.localIP());

Az aszinkron webszerver egyszerre több kapcsolatot tud kezelni. Minden kapcsolódó ügyfél egy  AsyncWebServerRequest objektumhoz van társítva. Az ESPAsyncWebServer egy háttérfolyamatként fut.

A server.on() metódus hívásával az első paraméterben beállítjuk az útvonalat, ahol a szerver figyeli a bejövő HTTP kéréseket, a második argumentum tartalmazza a HTTP kérések típusát, esetünkben GET metódust használunk, és végül a harmadik paraméterben megadunk egy funkciót, amely akkor fog végrehajtódni, amikor egy kérés érkezik a megadott útvonalon.

Az AsyncWebServerRequest send metódusa segítségével megadhatjuk a HTTP-választ. A következő példában egy egyszerű karakterláncot küldünk, itt a send három paraméterrel rendelkezik. Az első paraméter a 200 HTTP válaszkód, a második paraméter a küldés módja, esetünkben „text/plain”, a hamadik argumentum a küldendő karakterlánc, a „Hello AsyncWebServer”.

Ezek után indítsuk el a szervert a server.begin() függvény meghívásával.

server.on("/hello_server", HTTP_GET, [](AsyncWebServerRequest *request)
{
  request->send(200, "text/plain", "Hello AsyncWebServer!");
});
 
server.begin();

A loop() függvénybe most nem kerül semmi, mivel az AsyncWebServer használatához nem kell klienskezelő függvényt meghívni.

Lássuk a teljes kódot:

#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>

const char* ssid = "wifi_ssid";
const char* password = "szupertitkos_jelszavad";

AsyncWebServer server(80);

void setup()
{
  Serial.begin(115200);
 
  WiFi.begin(ssid, password);

  Serial.print("Kapcsolodas a wifi halozathoz.");
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }
  Serial.println();
  Serial.println("Csatlakozva!");
  Serial.print("Ip cim: ");
  Serial.println(WiFi.localIP());
 
  server.on("/hello_server", HTTP_GET, [](AsyncWebServerRequest *request)
  {
    request->send(200, "text/plain", "Hello AsyncWebServer!");
  });
 
  server.begin();
}
void loop(){}

Az ArduinoIDE segítségével töltsük fel a fenti kódot az ESP32-re. Ha ez megvan nyissuk meg a kedvenc webböngészőnket és az ArduinoIDE soros monitorból kimásolt IP címet kiegészítve a server.on függvényben megadott elérési úttal, írjuk be a böngésző címsorába. Például így.

http://192.168.1.20/hello_server

Az eredmény látható a böngésző ablakában.

Űrlap adatok küldése POST metodus használatával

A következő példában egy szövegbeviteli mezőből továbbítunk adatot POST metódus használatával, majd megjelenítjük a beírt szöveget.

#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>

AsyncWebServer server(80);

const char* ssid = "wifi_ssid";
const char* password = "szupertitkos_jelszavad";

const char* PARAM_MESSAGE = "message";
String postMessage = "";

const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML>
<html>
  <head>
    <title>ESP32 Aszinkron webszerver</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <script>
      function submitData() 
      {
        setTimeout(function(){
          document.location.reload(false); 
        }, 1000);   
      }
    </script>  
  </head>
  <body>
    <center>
      <h2>ESP32 Aszinkron webszerver</h2>

      <div style="height:50px"></div>

      <p>HTTP POST üzenet: %POST_MESSAGE%</p>
      
      <form action="/post" method="POST" target="self_page">
        <input type="text" name="message">
        <br><br>
        <input type="submit" value="Küldés..." onclick="submitData()">
      </form>
    </center>
    <iframe style="display:none" name="self_page"></iframe>
  </body>
</html> )rawliteral";

void notFound(AsyncWebServerRequest *request) 
{
  request->send(404, "text/plain", "A keresett oldal nem talalhato");
}

String processor(const String& var)
{
  if(var == "POST_MESSAGE")
  {
    return postMessage;
  }
  return String();
}

void setup()
{
  Serial.begin(115200);
 
  WiFi.begin(ssid, password);

  Serial.print("Kapcsolodas a wifi halozathoz.");
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }
  Serial.println();
  Serial.println("Csatlakozva!");
  Serial.print("Ip cim: ");
  Serial.println(WiFi.localIP());

  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request)
  {
    request->send_P(200, "text/html", index_html, processor);
  });

  server.on("/post", HTTP_POST, [](AsyncWebServerRequest *request)
  {
    if(request->hasParam(PARAM_MESSAGE, true))
    {
      postMessage = request->getParam(PARAM_MESSAGE, true)->value();
    }
    request->send(200);
  });

  server.onNotFound(notFound);

  server.begin();
}

void loop() {}

A html kód az „index_html[]” konstans karaktertömbbe kerül. A „PROGMEM” kulcsszó egy változó módosító, azt mondja a fordítónak, hogy mentse a változó tartalmát a flash memóriába.

const char index_html[] PROGMEM = R"rawliteral(....)rawliteral";

Az „R” azt jelenti, hogy mindent, ami a határolók között van, kezeljen nyers karakterláncként. Tehát minden úgy van ahogy le van írva a „rawliteral( és …. )rawliteral” között. A példában a „rawliteral” határolót használjuk, de ez helyett bármit szabadon választhatunk.

Ha valamit elgépeltünk a böngésző címsorában akkor a”notFound()” függvény kezeli le a hibát. Elküldi a 404 HTML válaszkódot és megjeleníti a megadott tartalmat, jelen esetben ez „text/plain” típusú szöveg „A keresett oldal nem talalhato”.

void notFound(AsyncWebServerRequest *request) 
{
  request->send(404, "text/plain", "A keresett oldal nem talalhato");
}

A html kódban elhelyeztünk egy helyőrzőt. A helyőrzőket % szimbólumok határolják, a példánkban ez a (%POST_MESSAGE%). Amikor a weboldal betöltődik a „processor()” függvény lefut és ahol megtalálja a kódban a helyőrzőt lecseréli az helyére illő Stringre.

Ebben a példában egy bekezdés tartalmát módosítjuk, átadjuk a „postMessage” globális változó értékét a %POST_MESSAGE% helyőrzőnek.

String postMessage = "";

<html>...
  <p>HTTP POST üzenet: %POST_MESSAGE%</p>
...</html>

String processor(const String& var)
{
  if(var == "POST_MESSAGE")
  {
    return postMessage;
  }
  return String();
}

A kódunkban az első server.on() függvény a kezdőlap megjelenítését szolgálja ki. Az első paraméter, az elérési út csak a „/” karaktert tartalmazza, így az ESP32 IP cimére érkező kéréseket figyeli.

A send_P() függvény válaszként elküldi a 200 HTTP válaszkódot, meghatározza a tartalom típusát, ezesetben „text/html”. A harmadik paraméterben meg kell adni a megjelenítendő html kód helyét, a példánkban az index_html tömbben tárolt karakterlánc. Mivel a html kódban elhelyeztünk egy helyőrzőt, meg kell határozni a feldolgozó függvényt ami ezt kezeli, ez a negyedik paraméterben megadott processor() függvény.

server.on("/", HTTP_GET, [](AsyncWebServerRequest *request)
{
  request->send_P(200, "text/html", index_html, processor);
});

A példakódban a második server.on() függvény a „/post” elérési útvonalat figyeli és a HTTP_POST kéréseket fogadja. A függvényen belül megvizsgáljuk, hogy az adott paraméter tartalmaz-e adatot. Ha igen kivonjuk a paraméter tartalmát további feldolgozásra.

Jelen esetben ez a „PARAM_MESSAGE ” a „message” névvel megjelölt szövegbeviteli mező tartalmát hordozza, ennek az értékét adjuk át a „postMessage” globális változónak. Végül 200-as HTTP válaszkódot küld.

const char* PARAM_MESSAGE = "message";
String postMessage = "";

</html>...
  <input type="text" name="message">
...</html>

server.on("/post", HTTP_POST, [](AsyncWebServerRequest *request)
{
  if(request->hasParam(PARAM_MESSAGE, true))
  {
    postMessage = request->getParam(PARAM_MESSAGE, true)->value();
  }
  request->send(200);
});

A server.onNotFound(notFound) függvény figyeli azokat a kéréseket, amelyek nem létező oldalakra irányulnak, ehez a „notFound()” függvényt adjuk paraméterként, ami ezeket a hibákat lekezeli.

server.onNotFound(notFound);

Végül elindítjuk az AsyncWebServer-t a „server.begin();” függvény hívásával.

server.begin();

Töltsük fel a kódot az ESP32-re, majd nézzük meg a kimenetet a webböngészőben.

ESP32 aszinkron webszerver - form adat küldés POST metódussal
ESP32 aszinkron webszerver – form adat küldés POST metódussal

Shelly Pro 4PM

Shelly Pro 4PM

Shelly Pro 4PM

Professzionális Wi-Fi relé 4 érintkezővel otthoni automatizáláshoz, Támogatott az Amazon Alexa, Google Home aszisztensek és az MQTT.

Hirdetés

Webhely jelszóval védett beállítások oldallal

A harmadik példában egy főoldalból és egy beállítások oldalból álló webhelyet készítünk.

Az első indításkor az ESP32 megpróbál csatlakozni a wifi hálózathoz, de nem rendelkezik a wifi csatlakozáshoz szükséges azonosítókkal. 15 másodperc sikertelen próbálkozás után automatikusan átáll AP módba. Ebben az esetben csatlakozni kell az ESP32 wifi hozzáférési ponthoz.

A csatlakozáshoz szükséges alapértelmezett azonosítók:
  SSID: Esp_AP
  Jelszó: 12345678

Fontos! A Jelszónak legalább 8 karakternek kell lennie, különben nem veszi figyelembe a szerver.

Ha sikeresen csatlakoztunk az ESP32 hozzáférési ponthoz, nyissuk meg a webböngészőben a ‘192.168.7.22‘ IP címet.

A főoldalon a címsor alatt egy szöveges mező megjeleníti a led állapotát, amelyet az alatta elhelyezett nyomógombbal tudunk ki illetve bekapcsolni. A led az ESP32 GPIO2 lábához csatlakozik.

Lejjebb találunk még egy gombot, erre kattintva eljuthatunk a beállítások oldalra.

ESP32 aszinkron webszerver kezdőlap
ESP32 aszinkron webszerver kezdőlap

A beállítások oldal jelszóval védett, az belépéshez szükséges azonosítók:
  alapértelmezett felhasználónév: admin
  alapértelmezett jelszó: admin.

ESP32 aszinkron webszerver bejelentkezés
ESP32 aszinkron webszerver bejelentkezés

A beállítások oldalon találunk két űrlapot. Az első űrlapon beállíthatjuk/ módosíthatjuk a wifi kapcsolódáshoz és a hozzáférési ponthoz (AP) szükséges bejelentkezési azonosítókat. A mentés gombra kattintva az adatok eltárolódnak egy nem felejtő memóriaterületre, az SPIFFS-re (SPI Flash File Storage).

Ezután az ESP32 újraindul.

ESP32 aszinkron webszerver hálózati beállítások
ESP32 aszinkron webszerver hálózati beállítások

A második űrlapon módosíthatjuk a beállitások oldal belépési azonosítóit. Ezek az azonosítók is egy nem felejtő memóriába kerülnek. A mentést követően az ESP32 nem indul újra.

ESP32 aszinkron webszerver belépési azonosítók módosítása
ESP32 aszinkron webszerver belépési azonosítók módosítása

A két űrlap alatt találunk még két gombot, nem hiszem hogy magyarázatra szorul.

ESP32 aszinkron webszerver gombok
ESP32 aszinkron webszerver gombok

Ez a példakód jó kiindulási alap lehet olyan projektekhez ahol szükség van a beállítások módosítására.

#include <WiFi.h>
#include <ESPAsyncWebServer.h>
#include <AsyncTCP.h>
#include <Hash.h>
#include "FS.h"
#include "SPIFFS.h"
#define FORMAT_SPIFFS_IF_FAILED true
const char ledPin = 2;
String httpUsername = "admin";
String httpPassword = "admin";
String _AP_ssid = "Esp_AP";
String _AP_password = "12345678";
IPAddress local_IP(192,168,7,22);
IPAddress gateway(192,168,7,1);
IPAddress subnet(255,255,255,0);
AsyncWebServer server(80);
bool wifiIsConnected = false;
String ledValue ="false";
String ledState ="A LED kikapcsolva!";
const char* param_ledvalue = "ledvalue";
const char* param_ap_ssid = "inputApSsid";
const char* param_ap_password = "inputApPassword";
const char* param_wifi_ssid = "inputWifiSsid";
const char* param_wifi_password = "inputWifiPassword";
const char* param_httpUsername = "inputHttpUsername";
const char* param_httpPassword = "inputHttpPassword";
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML>
<html>
<head>
<title>Kezdőlap</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script>
function submitData() 
{
setTimeout(function(){
document.location.reload(false); 
}, 1000);   
}
</script>
</head>
<body>
<center>
<h2>ESP32 aszinkron webszerver</h2>
<div style="height:50px"></div>
<p>%LED_STATE%</p>
<form action="/ledSwitch" target="self_page">
<input type="hidden" name="ledvalue" value="%LED_VALUE%">
<input type="submit" value="LED" onclick="submitData()">
</form>
<br><br>
<button onclick="window.location.href='/settings';">Beállítások</button>
<iframe style="display:none" name="self_page"></iframe>
</center>
</body>
</html> )rawliteral";
const char settings_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML>
<html>
<head>
<title>Beállítások</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script>
function submitData() 
{
setTimeout(function(){
document.location.reload(false); 
}, 1000);   
}
function logoutButton() 
{
var xmlHttpRequest = new XMLHttpRequest();
xmlHttpRequest.open("GET", "/logout", true);
xmlHttpRequest.send();
setTimeout(function() {
window.open("/","/"); 
}, 1000);
}
</script>
</head>
<body>
<center>
<h2>Beállítások</h2>
<div style="height:50px"></div>
<fieldset style="width:300px">
<legend>Hálózati beállítások:</legend>
<br><br>
<form action="/network" target="self_page">
AP SSID:<br>
<input type="text" value='%inputApSsid%' name="inputApSsid" size="20">
<br><br>
AP Jelszó:<br>
<input type="text" value='%inputApPassword%' name="inputApPassword" size="20">
<br>( Legalább 8 karakter! )
<br><br>
Wifi SSID:<br>
<input type="text" value='%inputWifiSsid%' name="inputWifiSsid" size="20">
<br><br>
Wifi Jelszó:<br>
<input type="text" value='%inputWifiPassword%' name="inputWifiPassword" size="20">
<br><br>
<input type="submit" value="Mentés" onclick="submitData()">
</form>
<br><br>
</fieldset>
<div style="height:20px"></div>
<fieldset style="width:300px">
<legend>Bejelentkezési adatok:</legend>
<br><br>
<form action="/http_login_set" target="self_page">
Felhasználónév:<br>
<input type="text" value='%inputHttpUsername%'  name="inputHttpUsername" size="20">
<br><br>
Jelszó:<br>
<input type="text" value='%inputHttpPassword%'  name="inputHttpPassword" size="20">
<br><br><br>
<input type="submit" value="Mentés" onclick="submitData()">
</form>
<br><br>
</fieldset>
<div style="height:20px"></div>
<fieldset style="width:300px">
<legend>Kezdőlapra</legend>
<br><br>
<button onclick="window.location.href='/';">Kezdőlap</button>
<br><br>
</fieldset>
<div style="height:20px"></div>
<fieldset style="width:300px">
<legend>Kijelentkezés</legend>
<br><br>
<button onclick="logoutButton()">Kijelentkezés</button>
<br><br>
</fieldset>
<div style="height:50px;"></div>
<iframe style="display:none" name="self_page"></iframe>
</center>
</body>
</html> )rawliteral";
String inputValueAdapter(const String& inputValueSet)
{
if(inputValueSet == "LED_STATE")
{
return ledState;
}
if(inputValueSet == "LED_VALUE")
{
return ledValue;
}
if(inputValueSet == "inputApSsid")
{
return readFile(SPIFFS, "/apSsid.txt");
}
if(inputValueSet == "inputApPassword")
{
return readFile(SPIFFS, "/apPassword.txt");
}
if(inputValueSet == "inputWifiSsid")
{
return readFile(SPIFFS, "/wifiSsid.txt");
}
if(inputValueSet == "inputWifiPassword")
{
return readFile(SPIFFS, "/wifiPassword.txt");
}
if(inputValueSet == "inputHttpUsername")
{
return readFile(SPIFFS, "/httpUsername.txt");
}
if(inputValueSet == "inputHttpPassword")
{
return readFile(SPIFFS, "/httpPassword.txt");
}
return String();
}
void setupAsyncServer()
{
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request)
{
request->send_P(200, "text/html", index_html, inputValueAdapter);
});
server.on("/ledSwitch", HTTP_GET, [](AsyncWebServerRequest *request)
{
ledValue = request->getParam(param_ledvalue)->value();
if(ledValue == "true")
{
ledValue = "false";
digitalWrite(ledPin, LOW);
ledState ="A LED kikapcsolva!";
}
else if(ledValue == "false")
{
ledValue = "true";
digitalWrite(ledPin, HIGH);
ledState ="A LED bekapcsolva!";
}
request->send(200, "text/text", ledValue);
});
server.on("/settings", HTTP_GET, [](AsyncWebServerRequest *request)
{
String temp_httpUsername = readFile(SPIFFS, "/httpUsername.txt");
if(temp_httpUsername == "")
{
temp_httpUsername = httpUsername;
}
const char* http_username = temp_httpUsername.c_str();
String temp_httpPassword = readFile(SPIFFS, "/httpPassword.txt");
if(temp_httpPassword == "")
{
temp_httpPassword = httpPassword;
}
const char* http_password = temp_httpPassword.c_str();
if(!request->authenticate(http_username, http_password))
{
return request->requestAuthentication();
}
request->send_P(200, "text/html", settings_html, inputValueAdapter);
});
server.on("/network", HTTP_GET, [](AsyncWebServerRequest *request)
{
String temp_httpUsername = readFile(SPIFFS, "/httpUsername.txt");
if(temp_httpUsername == "")
{
temp_httpUsername = httpUsername;
}
const char* http_username = temp_httpUsername.c_str();
String temp_httpPassword = readFile(SPIFFS, "/httpPassword.txt");
if(temp_httpPassword == "")
{
temp_httpPassword = httpPassword;
}
const char* http_password = temp_httpPassword.c_str();
if(!request->authenticate(http_username, http_password))
{
return request->requestAuthentication();
}
String inputMessage;
if (request->hasParam(param_ap_ssid)) 
{
inputMessage = request->getParam(param_ap_ssid)->value();
writeFile(SPIFFS, "/apSsid.txt", inputMessage.c_str());
}
if (request->hasParam(param_ap_password))
{
inputMessage = request->getParam(param_ap_password)->value();
writeFile(SPIFFS, "/apPassword.txt", inputMessage.c_str());
}
if (request->hasParam(param_wifi_ssid)) 
{
inputMessage = request->getParam(param_wifi_ssid)->value();
writeFile(SPIFFS, "/wifiSsid.txt", inputMessage.c_str());
}     
if (request->hasParam(param_wifi_password)) 
{
inputMessage = request->getParam(param_wifi_password)->value();
writeFile(SPIFFS, "/wifiPassword.txt", inputMessage.c_str());
}
request->send(200, "text/text", inputMessage);
Serial.println("ESP Restart...");
ESP.restart();
});
server.on("/http_login_set", HTTP_GET, [](AsyncWebServerRequest *request)
{
String temp_httpUsername = readFile(SPIFFS, "/httpUsername.txt");
if(temp_httpUsername == "")
{
temp_httpUsername = httpUsername;
}
const char* http_username = temp_httpUsername.c_str();
String temp_httpPassword = readFile(SPIFFS, "/httpPassword.txt");
if(temp_httpPassword == "")
{
temp_httpPassword = httpPassword;
}
const char* http_password = temp_httpPassword.c_str();
if(!request->authenticate(http_username, http_password))
{
return request->requestAuthentication();
}
String inputMessage;                                
if (request->hasParam(param_httpUsername))
{
inputMessage = request->getParam(param_httpUsername)->value();
writeFile(SPIFFS, "/httpUsername.txt", inputMessage.c_str());
}
if (request->hasParam(param_httpPassword))
{
inputMessage = request->getParam(param_httpPassword)->value();
writeFile(SPIFFS, "/httpPassword.txt", inputMessage.c_str());
}
request->send(200, "text/text", inputMessage);
});
server.on("/logout", HTTP_GET, [](AsyncWebServerRequest *request)
{
request->send(401);
});
server.onNotFound(notFound);
server.begin();
}
void notFound(AsyncWebServerRequest *request) 
{
request->send(404, "text/plain", "A keresett oldal nem talalhato");
}
String readFile(fs::FS &fs, const char * path)
{
String fileContent = "";
File file = fs.open(path, "r");
if(!file || file.isDirectory())
{
return fileContent;
}
while(file.available())
{
fileContent+=String((char)file.read());
}
file.close();
return fileContent;
}
void writeFile(fs::FS &fs, const char * path, const char * message)
{
File file = fs.open(path, "w");
if(!file)
{
return;
}
file.print(message);
file.close();
}
void setup_ap()
{
String temp_pass = readFile(SPIFFS, "/apPassword.txt");
if(temp_pass == "")
{
temp_pass = _AP_password;
}
String temp_ssid = readFile(SPIFFS, "/apSsid.txt");
if(temp_ssid == "")
{
temp_ssid = _AP_ssid;
}
const char* AP_ssid = temp_ssid.c_str();
const char* AP_password = temp_pass.c_str();
WiFi.softAPConfig(local_IP, gateway, subnet);
WiFi.softAP(AP_ssid, AP_password);
IPAddress Ap_Ip = WiFi.softAPIP();
Serial.print("Access Point IP cime: ");
Serial.println(Ap_Ip);
Serial.println();
}
void setup_wifi() 
{
String temp_pass = readFile(SPIFFS, "/wifiPassword.txt");
char passbuff[temp_pass.length() + 1];
temp_pass.toCharArray(passbuff, temp_pass.length() + 1);
const char* password = passbuff;
String temp_ssid = readFile(SPIFFS, "/wifiSsid.txt");
char ssidbuff[temp_ssid.length() + 1];
temp_ssid.toCharArray(ssidbuff, temp_ssid.length() + 1);
const char* ssid = ssidbuff;
WiFi.begin(ssid, password);
Serial.print("Csatlakozas a wifi halozathoz.");
int i = 0;
while (true) 
{
if(WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
i++;
if(i > 30)
{
wifiIsConnected = false;
Serial.println();
Serial.println("Nem lehet csatlakozni a wifi halozathoz.");
break;
}
}
else
{
wifiIsConnected = true;
Serial.println();
Serial.println("Csatlakozva!");
Serial.print("Ip cim: ");
Serial.println(WiFi.localIP());
Serial.println();
break;
}
}
}
void setup()
{
pinMode(ledPin, OUTPUT);
Serial.begin(115200);
SPIFFS.begin();
WiFi.mode(WIFI_STA);
setup_wifi();
if(!wifiIsConnected)
{
WiFi.mode(WIFI_AP);
setup_ap();    
}
setupAsyncServer();
}
void loop(){}
Shelly Plug S

Shelly Plug S

A legkisebb WiFi-csatlakozóval bárhonnan vezérelhető számos háztartási és irodai eszköz.

Hirdetés

Shelly 1 PM WiFi kapcsoló

Shelly 1 PM WiFi kapcsoló

A háztartási és irodai eszközök vezérelhetők a legkisebb WiFi-kapcsolású kapcsolókapcsolóval. Az áramfogyasztást is mérhetjük vele.

Shelly 1 wifi relé

Shelly 1 wifi relé

A Shelly ESP8266-on alapszik, egyszerűen egy aljzat vagy egy kapcsoló mögé telepíthetnek, ez nagyon megkönnyíti az intelligens otthon utólagos kiépítését.