Skip to content

在 esp8266 上提供静态网站服务

发布日期:2023-10-31

基于 esp8266 芯片的 NodeMCU 开发板,最大的特点是带有 wifi 模块,是一块成本低廉的物联网开发板。

esp8266单片机


我以12.8元售价买到一块,具有 typeC 接口,支持 CH340 串口(cp2102串口尺寸更小,售价更贵),主要硬件参数包括 50K 的 RAM、512K 的 Flash。对比 arduino nano,售价几乎一致,esp8266体积更大但支持wifi。在开发版上提供静态网站服务有很多作用,比如提供智能家居的操作面板,用siri控制智能家居等等。

找到合适的文件上传方案

开发前提,我使用了 arduino IDE 2.0+,需要安装esp8266插件支持,跑通了例程。

为了上传html文件,我查阅了相关资料 Install ESP8266 Filesystem Uploader in Arduino IDE 发现,通常使用的一种上传方式是采用Serial Peripheral Interface Flash File System (SPIFFS)中文翻译为串行外设接口闪存文件系统,而这种方案已经废弃,相关的arduino IDE插件也无法在2.0版本中使用。

因此我将解决方案转到 LittleFS,一个更现代化的文件系统,为此我们需要对应的 arduino IDE 插件 1.8版本IDE的插件,2.0版本插件参见该项目的说明,作者也提供了,使用时需要结合两个插件的说明来使用。

使用插件上传文件到开发板

以下内容是对上述插件使用方式的整理,具体可以参考插件的说明文件。

安装插件,在 ~/.arduinoIDE/plugins/ 中放入github下载的 vsix 文件,其中 plugins 目录可能要手动创建。重启 IDE。

new 一个 sketch,在项目根目录下创建 data 目录,放入 index.html, index.css, 写入你喜欢的内容。之后按 [Ctrl] + [Shift] + [P], 选择 "Upload LittleFS to Pico/ESP8266"。如无意外的话,data目录内的所有文件将会上传到开发板的根目录,因此在开发板上不存在 data 目录。

启动异步服务器提供文件服务

服务器例程参考自esp8266-webserver-using-littlefs, 具体如下,有修改

使用例程直接编译,遇到没有的库,用 IDE 下载就好了,再次编译直至编译成功,上传程序。

c
/*
  Title:  ESP8266 Webserver - No Filesystem
  Description:  An ESP8266 webserver that uses LittleFS to load web content
  Author: donsky
  For:    www.donskytech.com
  Date:   September 14, 2022
*/

#include <Arduino.h>
#ifdef ESP32
#include <WiFi.h>
#include <AsyncTCP.h>
#elif defined(ESP8266)
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#endif
#include <ESPAsyncWebSrv.h>
#include <LittleFS.h>

/*
  用你家的wifi信息替换下面的中文文字,注意不要填 5G wifi,不支持的
*/
#ifndef STASSID
#define STASSID "这里写wifi名称"
#define STAPSK  "这里写wifi密码"
#endif

const char* ssid = STASSID;
const char* password = STAPSK;


// Webserver
AsyncWebServer server(80);

String PARAM_MESSAGE = "status";

const int LED_PIN = LED_BUILTIN;

void notFound(AsyncWebServerRequest *request)
{
  request->send(404, "text/plain", "Not found");
}

void toggleLED(String status)
{
  if (status == "ON")
    digitalWrite(LED_PIN, LOW);
  else
    digitalWrite(LED_PIN, HIGH);
}

void setup()
{

  Serial.begin(115200);
  Serial.println("Starting the LittleFS Webserver..");

  // Begin LittleFS
  if (!LittleFS.begin())
  {
    Serial.println("An Error has occurred while mounting LittleFS");
    return;
  }

  // Connect to WIFI
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  if (WiFi.waitForConnectResult() != WL_CONNECTED)
  {
    Serial.printf("WiFi Failed!\n");
    return;
  }

  Serial.print("IP Address: ");
  Serial.println(WiFi.localIP());

  // LED PIN
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, HIGH);

  // Route for root index.html
  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request)
            { request->send(LittleFS, "/index.html", "text/html"); });

  // Route for root index.css
  server.on("/test.css", HTTP_GET, [](AsyncWebServerRequest *request)
            { request->send(LittleFS, "/index.css", "text/css"); });

  // Route for root entireframework.min.css
  // server.on("/entireframework.min.css", HTTP_GET, [](AsyncWebServerRequest *request)
  //           { request->send(LittleFS, "/entireframework.min.css", "text/css"); });

  // Route for root index.js
  // server.on("/index.js", HTTP_GET, [](AsyncWebServerRequest *request)
  //           { request->send(LittleFS, "/index.js", "text/javascript"); });

  // Respond to toggle event
  server.on("/toggle", HTTP_GET, [](AsyncWebServerRequest *request)
            {
        String status;
        if (request->hasParam(PARAM_MESSAGE)) {
            status = request->getParam(PARAM_MESSAGE)->value();
            if(status == "ON"){
              toggleLED("ON");
            }else{
              toggleLED("OFF");
            }
        } else {
            status = "No message sent";
        }
        request->send(200, "text/plain", "Turning Built In LED : " + status); });

  server.onNotFound(notFound);

  server.begin();
}

void loop()
{
}

查看效果

上传成功后打开 IDE 的串行监视器,按一下开发板的复位键,可以看到输出了一个局域网ip地址,访问这个地址,就可以看到我们写的html文件了。

Power by vitepress