🗂️ صفحهی وب از فایل SPIFFS روی ESP32
تا اینجا صفحههای وب را داخل کد C++ مینوشتیم. برای یک صفحهی کوچک اشکالی ندارد، ولی وقتی صفحه بزرگتر و رنگیتر شود، کد شلوغ و ویرایشش سخت میشود. ESP32 چند مگابایت حافظهی فلش دارد که میتوانیم مثل یک فلشمموری کوچک از آن استفاده کنیم. به سیستم فایل این حافظه SPIFFS میگویند. در این قسمت از آموزش ESP32، فایلهای index.html و style.css را در SPIFFS میگذاریم و برد آنها را سرو میکند؛ همه را هم در شبیهساز ESP32 فارسی، مثل تجربهای که در ووکوی داری، اجرا میکنیم.
چه میسازیم؟
یک صفحهی وب با رنگ و استایل جدا، که شمارندهی بازدید هم دارد. خود برنامه بار اول فایلها را در حافظه میسازد، پس به هیچ ابزار آپلود جداگانهای نیاز نداریم. فایلها بعد از ریست هم سر جایشان میمانند.
قطعهها
- فقط یک برد ESP32. سیمکشی لازم نیست.
کد کامل
#include <WiFi.h>
#include <SPIFFS.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
AsyncWebServer server(80);
int visits = 0;
const char starter_html[] PROGMEM = R"rawliteral(<!DOCTYPE html><html><head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="/style.css"></head>
<body><h2>Page from SPIFFS</h2>
<p>This file lives in the ESP32 flash memory.</p>
<p>Visits: <b id="n">?</b></p>
<script>
fetch('/visits').then(function (r) { return r.text(); })
.then(function (t) { document.getElementById('n').innerText = t; });
</script></body></html>
)rawliteral";
const char starter_css[] PROGMEM =
"body{font-family:sans-serif;text-align:center;background:#eef6ff}"
"h2{color:#1565c0}";
void writeFile(const char *path, const char *text) {
File f = SPIFFS.open(path, FILE_WRITE);
if (!f) {
Serial.println("cannot write file");
return;
}
f.print(text);
f.close();
}
void setup() {
Serial.begin(115200);
if (!SPIFFS.begin(true)) { // true = format the first time
Serial.println("SPIFFS failed!");
return;
}
if (!SPIFFS.exists("/index.html")) writeFile("/index.html", starter_html);
if (!SPIFFS.exists("/style.css")) writeFile("/style.css", starter_css);
WiFi.begin("Wokwi-GUEST", ""); // simulator network, no password
while (WiFi.status() != WL_CONNECTED) delay(200);
Serial.println(WiFi.localIP());
server.on("/visits", HTTP_GET, [](AsyncWebServerRequest *request) {
visits++;
request->send(200, "text/plain", String(visits));
});
// Every other address is a file in SPIFFS; "/" means index.html.
server.serveStatic("/", SPIFFS, "/").setDefaultFile("index.html");
server.begin();
}
void loop() {
}
توضیح بخشهای مهم
SPIFFS.begin(true)سیستم فایل را راه میاندازد.trueیعنی اگر حافظه هنوز قالببندی نشده، این کار را بکن. بار اول ممکن است چند ثانیه طول بکشد.SPIFFS.exists("/index.html")میپرسد فایل هست یا نه. فقط اگر نبود، آن را میسازیم؛ پس اگر بعداً فایل را عوض کنی، برنامه رویش را نمینویسد.- در
writeFile،FILE_WRITEفایل را برای نوشتن باز میکند (اگر بود، از نو).f.close()را هیچوقت فراموش نکن؛ تا بسته نشود، ممکن است داده کامل ذخیره نشود. server.serveStatic("/", SPIFFS, "/")جادوی اصلی است: هر آدرسی که مرورگر بخواهد، اگر فایلی با همان اسم در SPIFFS باشد، همان را میفرستد.setDefaultFileمیگوید آدرس خالی یعنیindex.html.- مسیر
/visitsرا قبل ازserveStaticتعریف کردهایم تا سرور اول آن را پیدا کند. loopخالی است، چون ESPAsyncWebServer کارش را در پسزمینه انجام میدهد.
data پروژه میگذارند و با ابزار آپلود فایلسیستم در Arduino IDE روی برد میفرستند. روش این مقاله (ساختن فایل از داخل کد) هم روی برد واقعی کار میکند و هم در شبیهساز. هستههای جدید ESP32 سیستم فایل LittleFS را هم دارند که با تغییر اسم SPIFFS به LittleFS تقریباً همینطور کار میکند.امتحانش کن
این پروژه آماده است: صفحهی وب از فایل SPIFFS روی ESP32. شبیهساز SPIFFS را شبیهسازی میکند و صفحه را در مرورگر مجازی خودش باز میکند. کاربرد دیگر SPIFFS، نگه داشتن تنظیمات است که در فایل تنظیمات روی حافظهی ESP32 و درس «ذخیرهی فایل روی حافظهی ESP32» میبینی. خواندن مثالها رایگان است و اجرای ESP32 با اشتراک Plus.
اشکالهای رایج
- «SPIFFS failed!»: روی برد واقعی، طرح پارتیشن انتخابشده در Arduino IDE بخش SPIFFS ندارد. یک Partition Scheme با SPIFFS انتخاب کن.
- صفحه بدون رنگ نمایش داده میشود: آدرس
/style.cssدر HTML با اسم فایل در SPIFFS یکی نیست. اسم فایلها به حروف بزرگ و کوچک حساساند. - تغییر HTML داخل کد اثری ندارد: فایل قدیمی از اجرای قبل در حافظه مانده و چون
existsدرست است، دوباره نوشته نمیشود. یک بارSPIFFS.remove("/index.html")را صدا بزن. - شمارنده همیشه ۱ است:
/visitsرا بعد ازserveStaticتعریف کردهای.
صفحهی SPIFFS را میشود با دادهی زنده ترکیب کرد: نمودار زنده با EventSource. برای دیدن همهی پروژههای وایفای سری به وایفای و اینترنت اشیا و صفحهی ESP32 بزن.
صفحهی SPIFFS را در تینکرکد فارسی باز کن 🗂️