文件系统
编写的程序都是上传到板子的闪存系统中。通常ESP8266开发板的闪存大小为4Mb,其中闪存1Mb用于程序存储,剩余的3Mb用于存放系统文件和其他文件,用户可用的空间是小于3Mb的。
FS库
在使用时,执行SPIFFS.format()
进行格式化文件(对于旧板子来讲)
SPIFFS.begin()
用于启动SPIFFS
//建立文件对象
SPIFFS.open(file_name, "w");
//参数说明:
//第一个参数是被操作的文件名称
//第二个参数"w" 代表写入文件信息,“r”表示读取文件 “a”表示添加
写入
代码
#include <FS.h>
String file_name = "/notes.txt"; //被读取的文件位置和名称
void setup() {
Serial.begin(9600);
Serial.println("");
Serial.println("SPIFFS format start");
SPIFFS.format(); // 格式化SPIFFS
Serial.println("SPIFFS format finish");
if(SPIFFS.begin()){ // 启动SPIFFS
Serial.println("SPIFFS Started.");
} else {
Serial.println("SPIFFS Failed to Start.");
}
File dataFile = SPIFFS.open(file_name, "w");// 建立File对象用于向SPIFFS中的file对象(即/notes.txt)写入信息
dataFile.println("Hello IOT World."); // 向dataFile写入字符串信息
dataFile.close(); // 完成文件写入后关闭文件
Serial.println("Finished Writing data to SPIFFS");
}
void loop() {
}
设置
设置程序使用多大的闪存(none表示不使用闪存文件系统)
程序较小时,1Mb足以,编译上传,提示格式化并且写入成功
读取
#include <FS.h>
String file_name = "/notes.txt"; //被读取的文件位置和名称
void setup() {
Serial.begin(9600);
Serial.println("");
if(SPIFFS.begin()){ // 启动闪存文件系统
Serial.println("SPIFFS Started.");
} else {
Serial.println("SPIFFS Failed to Start.");
}
//确认闪存中是否有file_name文件
if (SPIFFS.exists(file_name)){
Serial.print(file_name);
Serial.println(" FOUND.");
} else {
Serial.print(file_name);
Serial.print(" NOT FOUND.");
}
//建立File对象用于从SPIFFS中读取文件
File dataFile = SPIFFS.open(file_name, "r");
//读取文件内容并且通过串口监视器输出文件信息
for(int i=0; i<dataFile.size(); i++){
Serial.print((char)dataFile.read()); //dataFile.read()每次只能读取一个字符,并进行char强转
}
//完成文件读取后关闭文件
dataFile.close();
}
void loop() {
}
编译写入后,串口读取结果
添加
先找到文件,进行读取,获取文件对象后,在末尾进行添加
#include <FS.h>
/*对闪存系统中文件进行修改添加*/
String file_name = "/notes.txt"; //被读取的文件位置和名称
void setup() {
Serial.begin(9600);
Serial.println("");
if(SPIFFS.begin()){ // 启动闪存文件系统
Serial.println("SPIFFS Started.");
} else {
Serial.println("SPIFFS Failed to Start.");
}
//确认闪存中是否有file_name文件
if (SPIFFS.exists(file_name)){
Serial.print(file_name);
Serial.println(" FOUND.");
File dataFile = SPIFFS.open(file_name, "a");// 建立File对象用于向SPIFFS中的file对象(即/notes.txt)写入信息
dataFile.println("This is New Message."); // 向dataFile添加字符串信息
dataFile.close(); // 完成文件操作后关闭文件
Serial.println("Finished Appending data to SPIFFS");
} else {
Serial.print(file_name);
Serial.print(" NOT FOUND.");
}
}
void loop() {
}
编辑上传后,通过串口查看结果
读取文件夹内容
首先获取文件夹对象,然后通过dir.next()
读取每一个文件,当读取完毕后会返回0
#include <FS.h>
String file_name = "/test/notes2.txt"; //被读取的文件位置和名称
String folder_name = "/test"; //被读取的文件夹
void setup() {
Serial.begin(9600);
Serial.println("");
if(SPIFFS.begin()){ // 启动闪存文件系统
Serial.println("SPIFFS Started.");
} else {
Serial.println("SPIFFS Failed to Start.");
}
File dataFile = SPIFFS.open(file_name, "w");// 建立File对象用于向SPIFFS中的file对象(即myFile.txt)写入信息
dataFile.println("Hello Composer."); // 向dataFile写入字符串信息
dataFile.close(); // 完成文件写入后关闭文件
Serial.println(F("Finished Writing data to SPIFFS"));
// 显示目录中文件内容以及文件大小
Dir dir = SPIFFS.openDir(folder_name); // 建立“目录”对象
while (dir.next()) { // dir.next()用于检查目录中是否还有“下一个文件”
Serial.println(dir.fileName()); // 输出文件名
}
}
void loop() {
}
编译上传后,结果如下
删除
找到指定文件名的文件后,进行删除
#include <FS.h>
String file_name = "/test/notes2.txt"; //被读取的文件位置和名称
void setup() {
Serial.begin(9600);
Serial.println("");
if(SPIFFS.begin()){ // 启动闪存文件系统
Serial.println("SPIFFS Started.");
} else {
Serial.println("SPIFFS Failed to Start.");
}
//从闪存中删除file_name文件
if (SPIFFS.remove(file_name)){
Serial.print(file_name);
Serial.println(" remove sucess");
} else {
Serial.print(file_name);
Serial.println(" remove fail");
}
}
void loop() {
}
编译上传后,显示结果,显示结果后,结果为fail,结果是正常,因为上传代码后,已经执行过一边,点击RST后,文件已经不存在,所以显示fail
通过上例的读取文件夹内容即可发现文件已经不存在,如下图,notes2.txt已经不存在
应用
上传其他类型文件到开发板
向Arduino添加插件(在太极创客的网站上下的),并将下载的插件解压缩到项目文件夹的tools文件夹下,重启Arduino即可。
此时在工具栏即可看到下图选项
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-At7jLjoZ-1595423352711)(…/…/…/Software/Typora/upload/image-20200722183305495.png)]
打开某项目时候,可以选择上图中的选项进行上传,上传的是项目文件的同目录下的data文件夹中内容。根据文件夹中内容进行选择大小,如下图
将代码上传后,输入ip地址即可访问页面
代码如下:
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <ESP8266WebServer.h>
#include <FS.h>
ESP8266WiFiMulti wifiMulti; // 建立ESP8266WiFiMulti对象
ESP8266WebServer esp8266_server(80); // 建立网络服务器对象,该对象用于响应HTTP请求。监听端口(80)
void setup() {
Serial.begin(9600); // 启动串口通讯
Serial.println("");
wifiMulti.addAP("MERCURY", "2020Yuan..."); // 将需要连接的一系列WiFi ID和密码输入这里
wifiMulti.addAP("ssid_from_AP_2", "your_password_for_AP_2"); // ESP8266-NodeMCU再启动后会扫描当前网络
wifiMulti.addAP("ssid_from_AP_3", "your_password_for_AP_3"); // 环境查找是否有这里列出的WiFi ID。如果有
Serial.println("Connecting ..."); // 则尝试使用此处存储的密码进行连接。
int i = 0;
while (wifiMulti.run() != WL_CONNECTED) { // 尝试进行wifi连接。
delay(1000);
Serial.print(i++); Serial.print(' ');
}
// WiFi连接成功后将通过串口监视器输出连接成功信息
Serial.println('\n');
Serial.print("Connected to ");
Serial.println(WiFi.SSID()); // 通过串口监视器输出连接的WiFi名称
Serial.print("IP address:\t");
Serial.println(WiFi.localIP()); // 通过串口监视器输出ESP8266-NodeMCU的IP
if(SPIFFS.begin()){ // 启动闪存文件系统
Serial.println("SPIFFS Started.");
} else {
Serial.println("SPIFFS Failed to Start.");
}
esp8266_server.onNotFound(handleUserRequet); // 告知系统如何处理用户请求(on和notfound结合)
esp8266_server.begin(); // 启动网站服务
Serial.println("HTTP server started");
}
void loop(void) {
esp8266_server.handleClient(); // 处理用户请求
}
// 处理用户浏览器的HTTP访问
void handleUserRequet() {
// 获取用户请求网址信息
String webAddress = esp8266_server.uri();
// 通过handleFileRead函数处处理用户访问
bool fileReadOK = handleFileRead(webAddress);
// 如果在SPIFFS无法找到用户访问的资源,则回复404 (Not Found)
if (!fileReadOK){
esp8266_server.send(404, "text/plain", "404 Not Found");
}
}
bool handleFileRead(String path) { //处理浏览器HTTP访问
if (path.endsWith("/")) { // 如果访问地址以"/"为结尾
path = "/index.html"; // 则将访问地址修改为/index.html便于SPIFFS访问
}
String contentType = getContentType(path); // 获取文件类型
if (SPIFFS.exists(path)) { // 如果访问的文件可以在SPIFFS中找到
File file = SPIFFS.open(path, "r"); // 则尝试打开该文件
esp8266_server.streamFile(file, contentType);// 并且将该文件返回给浏览器
file.close(); // 并且关闭文件
return true; // 返回true
}
return false; // 如果文件未找到,则返回false
}
// 获取文件类型
String getContentType(String filename){
if(filename.endsWith(".htm")) return "text/html";
else 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(".gif")) return "image/gif";
else if(filename.endsWith(".jpg")) return "image/jpeg";
else if(filename.endsWith(".ico")) return "image/x-icon";
else if(filename.endsWith(".xml")) return "text/xml";
else if(filename.endsWith(".pdf")) return "application/x-pdf";
else if(filename.endsWith(".zip")) return "application/x-zip";
else if(filename.endsWith(".gz")) return "application/x-gzip";
return "text/plain";
}
网页控制PWD引脚
主要操作函数:
void handleLEDControl(){
// 从浏览器发送的信息中获取PWM控制数值(字符串格式)
String ledPwm = esp8266_server.arg("ledPwm"); //获取请求的参数值
// 将字符串格式的PWM控制数值转换为整数
int ledPwmVal = ledPwm.toInt();
// 实施引脚PWM设置
analogWrite(LED_BUILTIN, ledPwmVal);
// 建立基本网页信息显示当前数值以及返回链接
String httpBody = "Led PWM: " + ledPwm + "<p><a href=\"/LED.html\"><-LED Page</a></p>";
esp8266_server.send(200, "text/html", httpBody);
}
网页图形化控制PWD引脚
主要操作函数
void handleADC(){
int a = analogRead(A0); //读取模拟引脚A0值
a = map(a,0,1023,0,100);
String adc = String(a);
Serial.println(adc);
esp8266_server.send(200, "text/plain",adc);
}
map函数:
x = map(t,fromMAX,fromMIN,toMIN,forMAX);
t,x为同类型变量,fromMAX,fromMIN为t本身上下界,toMIN,forMAX为根据范围比例变换后的上下界,并将结果存入x变量
网页上传文件
主要操作函数
esp8266_server.on("/upload.html", // 如果客户端通过upload页面
HTTP_POST, // 向服务器发送文件(请求方法POST)
respondOK, // 则回复状态码 200 给客户端
handleFileUpload);// 并且运行处理文件上传函数
void handleFileUpload(){
HTTPUpload& upload = esp8266_server.upload();
if(upload.status == UPLOAD_FILE_START){ // 如果上传状态为UPLOAD_FILE_START
String filename = upload.filename;
// 建立字符串变量用于存放上传文件名
if(!filename.startsWith("/")) filename = "/" + filename;
// 为上传文件名前加上"/"
Serial.println("File Name: " + filename);
// 通过串口监视器输出上传文件的名称
fsUploadFile = SPIFFS.open(filename, "w");
// 在SPIFFS中建立文件用于写入用户上传的文件数据
} else if(upload.status == UPLOAD_FILE_WRITE){
// 如果上传状态为UPLOAD_FILE_WRITE
if(fsUploadFile)
fsUploadFile.write(upload.buf, upload.currentSize);
// 向SPIFFS文件写入浏览器发来的文件数据
} else if(upload.status == UPLOAD_FILE_END){ // 如果上传状态为UPLOAD_FILE_END
if(fsUploadFile) { // 如果文件成功建立
fsUploadFile.close(); // 将文件关闭
Serial.println(" Size: "+ upload.totalSize); // 通过串口监视器输出文件大小
esp8266_server.sendHeader("Location","/success.html");
// 将浏览器跳转到/success.html(成功上传页面)
esp8266_server.send(303); // 发送相应代码303(重定向到新页面)
} else { // 如果文件未能成功建立
Serial.println("File upload failed"); // 通过串口监视器输出报错信息
esp8266_server.send(500, "text/plain", "500: couldn't create file");
// 向浏览器发送相应代码500(服务器错误)
}
}
}