• Уважаемые посетители сайта esp8266.ru!
    Мы отказались от размещения рекламы на страницах форума для большего комфорта пользователей.
    Вы можете оказать посильную поддержку администрации форума. Данные средства пойдут на оплату услуг облачных провайдеров для сайта esp8266.ru
  • Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

esp8266webserver+SPIFFS передача переменной в HTML

uVolt

New member
Всех с наступившим! В связи с новогодними мероприятиями не могу собраться в кучу. Прошу сведущих помочь с вопросом. Я весьма далёк от высокоуровневого программирования и поэтому ни как не могу понять как передать переменную в HTML файл. Код собрал как конструктор из примеров. Проверил, работает. Но при нажатии на кнопку переходит на ссылку в соответствии с кнопкой /on или /off и выводит соответствующий текст на страничке. А мне надо чтоб не было перехода а оставалась эта-же страничка но менялось значение переменной %STATE% на страничке.
В скетче использовал FTP и файловую систему SPIFFS.
Код:
#include <ESP8266WiFi.h> 
#include <ESP8266WebServer.h>
#include <FS.h> 
#include <ESP8266FtpServer.h>
#include <ESP8266HTTPUpdateServer.h>

const char* OTAUSER = "";
const char* OTAPASSWORD = "";
const char* OTAPATH = "/update";  
const byte relay = 2;
const char* user = "user";
const char* ssid = "Keenetic-3384"; 
const char* password = "12345678";

ESP8266HTTPUpdateServer httpUpdater;
ESP8266WebServer HTTP(80);

FtpServer ftpSrv; 
 
void setup() {
  pinMode(relay, OUTPUT);  
  Serial.begin(115200); 

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);

  Serial.print(" ssid: ");
  Serial.print(ssid);
  Serial.print(" password: ");
  Serial.print(password);
 
 
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
 
  SPIFFS.begin();
  httpUpdater.setup(&HTTP,  OTAPATH ,  OTAUSER ,   OTAPASSWORD);
  HTTP.begin();
  ftpSrv.begin(user,password);

  Serial.print("\nMy IP to connect via Web-Browser or FTP: ");  
  Serial.println(WiFi.localIP()); 
  Serial.println("\n");
 
  // Обработка HTTP-запросов
  HTTP.on("/on", []() {
    HTTP.send(200, "text/plain", on_());
  });
  HTTP.on("/off", []() {
    HTTP.send(200, "text/plain", off_());
  });
  HTTP.onNotFound([]() {
    if (!handleFileRead(HTTP.uri()))
      HTTP.send(404, "text/plain", "Not Found");
  });
}
 
void loop() {
  HTTP.handleClient(); 
  ftpSrv.handleFTP(); 
}
 

String on_() {
  String STATE;
    STATE = "on";
  digitalWrite(relay, 0); 
  Serial.println("\r\n");
  Serial.println(STATE);
  return "on";
}
 
String off_() {
  String STATE;
    STATE = "off";
  digitalWrite(relay, 1);
  Serial.println("\r\n");
  Serial.println(STATE);
  return "off"; 
}
 
bool handleFileRead(String path) { 
  if (path.endsWith("/")) path += "index.html"; 

  String contentType = getContentType(path);
  if (SPIFFS.exists(path)) {
    File file = SPIFFS.open(path, "r");
    size_t sent = HTTP.streamFile(file, contentType); 
    file.close();
    return true; 
  }
  return false; 
}
 
String getContentType(String filename) { 
  if (filename.endsWith(".html")) return "text/html";
  else if (filename.endsWith(".css")) return "text/css";
  else if (filename.endsWith(".js")) return "application/javascript";
  else if (filename.endsWith(".png")) return "image/png";
  else if (filename.endsWith(".jpg")) return "image/jpeg"; 
  else if (filename.endsWith(".gif")) return "image/gif";
  else if (filename.endsWith(".ico")) return "image/x-icon";  
  return "text/plain"; 
}
Код:
<!DOCTYPE html>
<html>
  <head>
    <title>ESP WEB SERVER</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" type="text/css" href="style.css">
    <link rel="icon" type="image/png" href="favicon.png">
    <link rel="stylesheet" href="/stile.css">
  </head>
  <body>
    <div class="topnav">
      <h1>ESP WEB SERVER</h1>
    </div>
    <div class="content">
      <div class="card-grid">
        <div class="card">
          <p class="card-title"><i class="fas fa-lightbulb"></i> GPIO 2</p>
          <p>
            <a href="on"><button class="button-on">ON</button></a>
            <a href="off"><button class="button-off">OFF</button></a>
          </p>
          <p class="state">State: %STATE%</p>
          <p><a href="/update">Update</a></p>
        </div>
      </div>
    </div>
  </body>
</html>
Код:
html {
  font-family: Arial, Helvetica, sans-serif;
  display: inline-block;
  text-align: center;
}

h1 {
  font-size: 1.8rem;
  color: white;
}

p {
  font-size: 1.4rem;
}

.topnav {
  overflow: hidden;
  background-color: #0A1128;
}

body { 
  margin: 0;
}

.content {
  padding: 5%;
}

.card-grid {
  max-width: 800px;
  margin: 0 auto;
  display: grid;
  grid-gap: 2rem;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
}

.card {
  background-color: white;
  box-shadow: 2px 2px 12px 1px rgba(140,140,140,.5);
}

.card-title {
  font-size: 1.2rem;
  font-weight: bold;
  color: #034078
}

input[type=submit] {
  border: none;
  color: #FEFCFB;
  background-color: #034078;
  padding: 15px 15px;
  text-align: center;
  text-decoration: none;
  display: inline-block;
  font-size: 16px;
  width: 100px;
  margin-right: 10px;
  border-radius: 4px;
  transition-duration: 0.4s;
  }

input[type=submit]:hover {
  background-color: #1282A2;
}

input[type=text], input[type=number], select {
  width: 50%;
  padding: 12px 20px;
  margin: 18px;
  display: inline-block;
  border: 1px solid #ccc;
  border-radius: 4px;
  box-sizing: border-box;
}

label {
  font-size: 1.2rem;
}
.value{
  font-size: 1.2rem;
  color: #1282A2; 
}
.state {
  font-size: 1.2rem;
  color: #1282A2;
}
button {
  border: none;
  color: #FEFCFB;
  padding: 15px 32px;
  text-align: center;
  font-size: 16px;
  width: 100px;
  border-radius: 4px;
  transition-duration: 0.4s;
}
.button-on {
  background-color: #034078;
}
.button-on:hover {
  background-color: #1282A2;
}
.button-off {
  background-color: #858585;
}
.button-off:hover {
  background-color: #252524;
}
 

Vovka

Member
А мне надо чтоб не было перехода а оставалась эта-же страничка но менялось значение переменной %STATE% на страничке.
Тут поможет javascript + XMLHttpRequest. Можно конечно и WebSocket, но это немного сложнее. Начните с XMLHttpRequest
 

uVolt

New member
Тут поможет javascript + XMLHttpRequest. Можно конечно и WebSocket, но это немного сложнее. Начните с XMLHttpRequest
Спасибо большое. Действительно javascript + XMLHttpRequest получилось реализовать. Получилось довольно лаконично, и вполне логично. Вот рабочий пример, правда пока без SPIFFS. Позже доработаю.
Код:
#include <ESP8266WiFi.h>
#include <FS.h>                                                         // Библиотека для работы с файловой системой
#include <ESP8266FtpServer.h>                                           // Библиотека для работы с SPIFFS по FTP
#include <ESP8266HTTPUpdateServer.h>
#include <ESP8266WebServer.h>
#include "index.h"
#define LED D0

const char* OTAUSER = "";
const char* OTAPASSWORD = "";
const char* OTAPATH = "/update";                                       // Путь, который будем дописывать после ip адреса в браузере.
const byte relay = 2;                                                  // Пин подключения сигнального контакта реле
const char* user = "user";
const char* ssid = "Keenetic-3384";                                             // Название генерируемой точки доступа
const char* password = "12345678";

ESP8266HTTPUpdateServer httpUpdater;
ESP8266WebServer server(80);                                           // Определяем объект и порт сервера для работы с HTTP
FtpServer ftpSrv;                                                      // Определяем объект для работы с модулем по FTP (для отладки HTML)

void handleRoot()
{
 String s = webpage;
 server.send(200, "text/html", s);
}
void led_control()
{
 String state = "OFF";
 String act_state = server.arg("state");
 if(act_state == "1")
 {
  digitalWrite(relay,HIGH); //LED ON (включение светодиода)
  state = "ON";
 }
 else
 {
  digitalWrite(relay,LOW); //LED OFF (выключение светодиода)
  state = "OFF";
 }
 
 server.send(200, "text/plane", state);
}
void setup(void)
{
  Serial.begin(115200);
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  Serial.println("");
  pinMode(relay,OUTPUT);
 
  while (WiFi.status() != WL_CONNECTED)
  {
    Serial.print("Connecting...");
  }
  httpUpdater.setup(&server,  OTAPATH ,  OTAUSER ,   OTAPASSWORD);
  server.begin();                                                         // Инициализируем Web-сервер
  ftpSrv.begin(user,password);                                            // Поднимаем FTP-сервер для удобства отладки работы HTML (логин, пароль)

  Serial.println("");
  Serial.print("Connected to ");
  Serial.println(ssid);
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
 
  server.on("/", handleRoot);
  server.on("/led_set", led_control);
}
void loop(void)
{
  server.handleClient();
  ftpSrv.handleFTP();                                                 // Обработчик FTP-соединений
}
Код:
const char webpage[] PROGMEM = R"=====(
<!DOCTYPE html>
<html>
<style type="text/css">
.button {
  background-color: #4CAF50; /* Green */
  border: none;
  color: white;
  padding: 15px 32px;
  text-align: center;
  text-decoration: none;
  display: inline-block;
  font-size: 16px;
}
</style>
<body style="background-color: #f9e79f ">
<center>
<div>
<h1>AJAX BASED ESP8266 WEBSERVER</h1>
  <button class="button" onclick="send(1)">LED ON</button>
  <button class="button" onclick="send(0)">LED OFF</button><BR>
</div>
 <br>
<div><h2>
  LED State: <span id="state">NA</span>
</h2>
</div>
          <p><a href="/update">Update</a></p>
<script>
function send(led_sts)
{
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      document.getElementById("state").innerHTML = this.responseText;
    }
  };
  xhttp.open("GET", "led_set?state="+led_sts, true);
  xhttp.send();
}
setInterval(function()
{
  getData();
}, 2000);
</script>
</center>
</body>
</html>
)=====";
 
Сверху Снизу