ESP8266-NodeMCU (5) 闪存文件系统

        当ESP8266使用无线终端模式,作为一台微型服务器,如果想向用户展示网站信息,图片信息时,就需要使用到ESP8266的闪存文件系统(4M),可以将文件上传到开发板上,供用户访问

1 设置闪存文件系统

        Arduino:工具>>Flash Size>>选择对应的闪存文件大小

2 通过代码使用闪存文件系统

2 .1 向闪存文件系统写入信息

#include <FS.h>  // 引入FS(Flash Size)库
 
String file_name = "/text/notes.txt"; // 文件位置和名称(根目录/text下的notes.txt)
 
void setup() {
  Serial.begin(9600);
  
  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对象,w表示写入,r表示读取
  dataFile.println("Hello IOT World.");       // File.println()写入
  dataFile.close();                           // 完成文件写入后关闭文件
  Serial.println("Finished Writing data to SPIFFS");
}
 
void loop() {
}

2.2 读取闪存文件系统

#include <FS.h>
 
String file_name = "/text/notes.txt";   
 
void setup() {
  Serial.begin(9600);
  
  if(SPIFFS.begin()){
    Serial.println("SPIFFS Started.");
  } else {
    Serial.println("SPIFFS Failed to Start.");
  }
 
  if (SPIFFS.exists(file_name)){   // 判断闪存文件file_name是否存在
    Serial.print(file_name);
    Serial.println(" FOUND.");
  } else {
    Serial.print(file_name);
    Serial.print(" NOT FOUND.");
  }
 
  File dataFile = SPIFFS.open(file_name, "r"); 
 
  for(int i=0; i<dataFile.size(); i++){
    Serial.print((char)dataFile.read());   // File.read()读取,每次只能读取一个字符
  }
 
  dataFile.close();                           
}
 
void loop() {
}

3 通过ArduinoIDE插件使用闪存文件系统

3.1 下载Arduino-ESP8266闪存文件插件程序

(插件仅支持arduino1.0版本,不支持2.0以上版本)

        方式一:官网GitHub下载>>选择"ESP8266FS-0.5.0.zip"

        方式二:太极创客官网下载

        查看ArduinoIDE"项目文件夹地址":文件>>首选项项目文件夹地址

        在该地址下建立一个tools文件夹,将下载好的插件解压缩,得到的ESP8266FS文件夹移入tools下

        重启ArduinoIDE,在工具下看到"ESP8266 Sketch Data Upload"表示插件安装成功

3.2 插件使用

        点击"ESP8266 Sketch Data Upload",会向开发板上传与当前程序所在位置同目录的data文件夹

3.2.1 向闪存文件系统存入网页信息

#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <ESP8266WebServer.h>
#include <FS.h>  

ESP8266WiFiMulti wifiMulti;     

ESP8266WebServer esp8266_server(80);    

void setup() {
  Serial.begin(9600);         
  
  wifiMulti.addAP("WIFI1", "12345678"); 
  wifiMulti.addAP("WIFI2", "12345678");
  wifiMulti.addAP("WIFI3", "12345678"); 
  Serial.println("Connecting ...");                   
  
  int i = 0;  
  while (wifiMulti.run() != WL_CONNECTED) { 
    delay(1000);
    Serial.print(i++); Serial.print(' ');
  }
  
  Serial.println('\n');
  Serial.print("Connected to ");
  Serial.println(WiFi.SSID());             
  Serial.print("IP address:\t");
  Serial.println(WiFi.localIP());          

  if(SPIFFS.begin()){                       // 启动闪存文件系统
    Serial.println("SPIFFS Started.");
  } else {
    Serial.println("SPIFFS Failed to Start.");
  }
  
  esp8266_server.onNotFound(handleUserRequet);      
  esp8266_server.begin();                         
  Serial.println("HTTP server started");
}

void loop(void) {
  esp8266_server.handleClient();                
}

void handleUserRequet() {         
  String webAddress = esp8266_server.uri();       // 获取用户请求网址信息
  
  bool fileReadOK = handleFileRead(webAddress);  
  if (!fileReadOK){                                                 
    esp8266_server.send(404, "text/plain", "404 Not Found"); 
  }
}

bool handleFileRead(String path) {           
  if (path.endsWith("/")) {                   // 如果访问地址以"/"为结尾,则改为默认访问  /index.html
    path = "/index.html";                    
  } 
  
  String contentType = getContentType(path);  // 获取文件类型
  
  if (SPIFFS.exists(path)) {                     // 如果访问的文件可以在SPIFFS中找到
    File file = SPIFFS.open(path, "r");          // 则尝试打开该文件
    esp8266_server.streamFile(file, contentType);// esp8266_server.streamFile()将该文件返回给浏览器
    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";
}

        直接访问保存在开发板上的网页信息:

3.2.2 通过PWM控制LED灯亮度

        通过模拟信号控制LED的点亮程度,不再只是单纯地通过低高电平控制灯的亮灭(0亮1灭)

#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <ESP8266WebServer.h>
#include <FS.h>  
 
ESP8266WiFiMulti wifiMulti;         
 
ESP8266WebServer esp8266_server(80);

void setup(void){
  Serial.begin(9600);        
  Serial.println("");
  
  pinMode(LED_BUILTIN, OUTPUT); 

  wifiMulti.addAP("WIFI1", "12345678"); 
  wifiMulti.addAP("WIFI2", "12345678");
  wifiMulti.addAP("WIFI3", "12345678"); 
  Serial.println("Connecting ...");                     
  
  int i = 0;  
  while (wifiMulti.run() != WL_CONNECTED) {
    delay(1000);
    Serial.print(i++); Serial.print(' ');
  }
  
  Serial.println('\n');
  Serial.print("Connected to ");
  Serial.println(WiFi.SSID());            
  Serial.print("IP address:\t");
  Serial.println(WiFi.localIP());          

  if(SPIFFS.begin()){                       
    Serial.println("SPIFFS Started.");
  } else {
    Serial.println("SPIFFS Failed to Start.");
  }                      
                 
  esp8266_server.on("/LED-Control", handleLEDControl);   
  esp8266_server.onNotFound(handleUserRequest); 

  esp8266_server.begin();
  Serial.println("HTTP server started");
}
 
void loop(void){
  esp8266_server.handleClient();  //处理网络请求
}                                
                                                                         
void handleLEDControl(){
  String ledPwm = esp8266_server.arg("ledPwm"); //esp8266_server.arg("ledPwm"),获取ledPwm对应的值
  int ledPwmVal = ledPwm.toInt();

  analogWrite(LED_BUILTIN, ledPwmVal);  // anologWrite(pin,int)写入模拟信号(0~1023)

  String httpBody = "Led PWM: " + ledPwm + "<p><a href=\"/LED.html\"><-LED Page</a></p>";           
  esp8266_server.send(200, "text/html", httpBody);
}

void handleUserRequest() {         
  String reqResource = esp8266_server.uri();
  Serial.print("reqResource: ");
  Serial.println(reqResource);
  
  bool fileReadOK = handleFileRead(reqResource);
  if (!fileReadOK){                                                 
    esp8266_server.send(404, "text/plain", "404 Not Found"); 
  }
}

bool handleFileRead(String resource) {        
  if (resource.endsWith("/")) {                 
    resource = "/LED.html";                 
  } 
  String contentType = getContentType(resource); 
  if (SPIFFS.exists(resource)) {                    
    File file = SPIFFS.open(resource, "r");        
    esp8266_server.streamFile(file, contentType);
    file.close();                                
    return true;                                 
  }
  return 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";
}

4 通过网页使用闪存文件系统

#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <ESP8266WebServer.h>
#include <FS.h>  

ESP8266WiFiMulti wifiMulti;  
ESP8266WebServer esp8266_server(80);  

File fsUploadFile;            

void setup() {
  Serial.begin(9600);        
  Serial.println("");

  wifiMulti.addAP("WIFI1", "12345678");
  wifiMulti.addAP("WIFI1", "12345678"); 
  wifiMulti.addAP("WIFI1", "12345678"); 
  Serial.println("Connecting ...");   

  int i = 0;  
  while (wifiMulti.run() != WL_CONNECTED) {
    delay(1000);
    Serial.print(i++); Serial.print('.');
  }
  
  Serial.println('\n');
  Serial.print("Connected to ");
  Serial.println(WiFi.SSID());             
  Serial.print("IP address:\t");
  Serial.println(WiFi.localIP());         
          
  if(SPIFFS.begin()){                 
    Serial.println("SPIFFS Started.");
  } else {
    Serial.println("SPIFFS Failed to Start.");
  }
  
  esp8266_server.on("/upload.html",HTTP_POST,respondOK,handleFileUpload);
  esp8266_server.onNotFound(handleUserRequest);

  esp8266_server.begin();             
  Serial.println("HTTP server started");
}

void loop() {
  esp8266_server.handleClient();
}

void handleFileUpload(){  
  HTTPUpload& upload = esp8266_server.upload();
  if(upload.status == 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){         
    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(服务器错误)
    }    
  }
}

void respondOK(){
  esp8266_server.send(200);
}

// 处理用户浏览器的HTTP访问
void handleUserRequest(){      
  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";
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值