ESP8266——入门:文件系统(三)

文件系统

编写的程序都是上传到板子的闪存系统中。通常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表示不使用闪存文件系统)

image-20200722173903855

程序较小时,1Mb足以,编译上传,提示格式化并且写入成功

image-20200722175019582

读取

#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() {
}

编译写入后,串口读取结果

image-20200722175506682

添加

先找到文件,进行读取,获取文件对象后,在末尾进行添加

#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() {
}

编辑上传后,通过串口查看结果

image-20200722180108263

读取文件夹内容

首先获取文件夹对象,然后通过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() {
}

编译上传后,结果如下

image-20200722181221111

删除

找到指定文件名的文件后,进行删除

#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

image-20200722181508411

通过上例的读取文件夹内容即可发现文件已经不存在,如下图,notes2.txt已经不存在

image-20200722181855352

应用

上传其他类型文件到开发板

向Arduino添加插件(在太极创客的网站上下的),并将下载的插件解压缩到项目文件夹的tools文件夹下,重启Arduino即可。

此时在工具栏即可看到下图选项

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-At7jLjoZ-1595423352711)(…/…/…/Software/Typora/upload/image-20200722183305495.png)]

打开某项目时候,可以选择上图中的选项进行上传,上传的是项目文件的同目录下的data文件夹中内容。根据文件夹中内容进行选择大小,如下图

image-20200722183535998

将代码上传后,输入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(服务器错误)
    }    
  }
}
  • 0
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值