ESP8266文件系统的使用

最近有做一个小项目,一些系统设定需要保存,开机后依旧是上次设置的值,之前使用eeprom来储存,但有些esp8266在写值会重启,能力有限,至今没有找到原因在哪里,所以当时改了储存设定的方式,改用文件系统来做,以下为记录

1、文件也就两种方式要么读要么写,故有以下两个函数,分别实现读参与写参,如有需要可以直接移植取用,

2、需要调用的一些函数如下,可另放一个.ino

/***********************************************************************************
   函数:/WIFIConfig.conf文件中读取设置数据并连接WIFI
***********************************************************************************/
void read_setting()
{
    DBG_433("读取config设定");
    String str = str_read_or_show("/json/setConfig.json", true); // 读取文件内容

    String on_hour = analysis_json(str, "on_hour");                       // 解析on_hour
    String on_minute = analysis_json(str, "on_minute");                   // 解析on_minute
    String off_hour = analysis_json(str, "off_hour");                     // 解析on_hour
    String off_minute = analysis_json(str, "off_minute");                 // 解析on_minute
    String first_open = analysis_json(str, "first_open");                 // 解析first_open
    String dingshikaiguan = analysis_json(str, "dingshikaiguan");         // 解析dingshikaiguan
    String chixugongqi_change = analysis_json(str, "chixugongqi_change"); // 解析chixugongqi_change
    String oled_fx = analysis_json(str, "oled_fx");                       // 解析oled_fx

    set_time.on_hour = strtoul(on_hour.c_str(), NULL, 10);
    set_time.on_minute = strtoul(on_minute.c_str(), NULL, 10);
    set_time.off_hour = strtoul(off_hour.c_str(), NULL, 10);
    set_time.off_minute = strtoul(off_minute.c_str(), NULL, 10);
    set_time.first_open = strtoul(first_open.c_str(), NULL, 10);
    set_time.dingshikaiguan = strtoul(dingshikaiguan.c_str(), NULL, 10);
    set_time.chixugongqi_change = strtoul(chixugongqi_change.c_str(), NULL, 10);
    set_time.oled_fx = strtoul(oled_fx.c_str(), NULL, 10);

    Serial.printf("是否第一次开机:%d 开机时间 %d:%d /关机时间 %d:%d   定时开关:%d    供气模式: %d  屏幕方向 %d\n", set_time.first_open, set_time.os_hour, set_time.os_minute, set_time.on_hour, set_time.on_minute, set_time.off_hour, set_time.off_minute, set_time.dingshikaiguan, set_time.chixugongqi_change, set_time.oled_fx);
}
/**********************************************************************************
   函数:
 *********************************************************************************/
void write_setting()
{
    DBG_433("更新设定");

    String rec_on_hour = String("") + set_time.on_hour;
    String rec_on_minute = String("") + set_time.on_minute;
    String rec_off_hour = String("") + set_time.off_hour;
    String rec_off_minute = String("") + set_time.off_minute;
    String rec_first_open = String("") + set_time.first_open;
    String rec_dingshikaiguan = String("") + set_time.dingshikaiguan;
    String rec_chixugongqi_change = String("") + set_time.chixugongqi_change;
    String rec_oled_fx = String("") + set_time.oled_fx;

    StaticJsonDocument<200> set_json; // 创建一个JSON对象,wifi_json

    set_json["on_hour"] = rec_on_hour;                       // 写入一个建和值
    set_json["on_minute"] = rec_on_minute;                   // 写入一个键和值
    set_json["off_hour"] = rec_off_hour;                     // 写入一个建和值
    set_json["off_minute"] = rec_off_minute;                 // 写入一个键和值
    set_json["first_open"] = rec_first_open;                 // 写入一个建和值
    set_json["dingshikaiguan"] = rec_dingshikaiguan;         // 写入一个键和值
    set_json["chixugongqi_change"] = rec_chixugongqi_change; // 写入一个建和值
    set_json["oled_fx"] = rec_oled_fx;                       // 写入一个键和值

    String set_json_str;                             // 定义一个字符串变量
    serializeJson(set_json, set_json_str);           // 生成JOSN的字符串
    str_write("/json/setConfig.json", set_json_str); // 字符串写入
}
#include <ArduinoJson.h>
#include "FS.h"
String file_name0 = "/json/config.json";           // 被读取的文件位置和名称
String file_name1 = "/json/mn88xxxconfig.json";    // 被读取的文件位置和名称
String file_name2 = "/json/mn88xxxconfigcal.json"; // 被读取的文件位置和名称
String file_name3 = "/json/mn78xxxconfigcal.json"; // 被读取的文件位置和名称

File fsUploadFile; // 建立文件对象用于闪存文件上传
/**************************************************************************************
   函数:字符串写入文件,文件如果存在,将被清零并新建,文件不存在,将新建该文件
   path:    文件的绝对路径
   str:     要写入的字符串
 *************************************************************************************/
void str_write(String path, String str)
{
    Serial.println("写入文件");
    File wf = SPIFFS.open(path, "w"); // 以写入模式打开文件
    if (!wf)
    {                                         // 如果无法打开文件
        Serial.println("打开文件写入时错误"); // 显示错误信息
        return;                               // 无法打开文件直接返回
    }
    wf.print(str);                    // 字符串写入文件
    wf.close();                       // 关闭文件
    File rf = SPIFFS.open(path, "r"); // 以读取模式打开文件
    Serial.print("FILE:");
    Serial.println(rf.readString()); // 读取文件
    rf.close();                      // 关闭文件
}


/**********************************************************************************
   函数:从文件path中读取字符串
   path:      文件的绝对路径
   return:    返回读取的字符串
 *********************************************************************************/
String str_read_or_show(String path, bool read_or_show)
{
    String str;
    Serial.println('\n');
    Serial.print("读取文件:");
    Serial.println(path);
    //  确认闪存中是否有file_name文件
    if (SPIFFS.exists(path))
    {
        Serial.print(path);
        Serial.println(" FOUND.");
    }
    else
    {
        Serial.print(path);
        Serial.print(" NOT FOUND.");
        return "false";
    }
    File configFile = SPIFFS.open(path, "r");
    if (!configFile)
    {
        Serial.println("Failed to open config file");
        return "";
    }
    if (read_or_show)
    {
        /*********************************************************************************/
        Serial.println("read from file:");
        str = configFile.readString();
        /*********************************************************************************/
    }
    else
    {
        while (configFile.available())
        {
            Serial.write(configFile.read());
        } // 这部分放str前边会导致出错
        // 读取文件内容并且通过串口监视器输出文件信息
        return "";
        /*********************************************************************************/
    }
    configFile.close();
    return str;
}
/***************************************************************************************
   函数:解析JSON字符串,从JSON字符串名称得到该值
   str:   JSON字符串
   Name:  JSON集合的名称
   return: 返回值的字符串
 ***************************************************************************************/
String analysis_json(String str, String Name)
{
    DynamicJsonDocument doc(str.length() * 2); // 定义一个JSON对象
    deserializeJson(doc, str);                 // 反序列数据
    String value = doc[Name].as<String>();     // 从Name中读取对应的值
    return value;
}

/***********************************************************************************
   函数:/WIFIConfig.conf文件中读取设置数据并连接WIFI
***********************************************************************************/
void wifi_connect()
{
    Serial.println();
    Serial.println("在conf文件中读取数据并连接WIFI");
    String str = str_read_or_show("/json/WIFIConfig.json", true); // 读取文件内容
    String wifiname = analysis_json(str, "wifiname");             // 解析WIFI名称
    String wifipassword = analysis_json(str, "wifipassword");     // 解析WIFI密码
    Serial.print("WiFi 名称: ");                                  // 显示wifi
    Serial.println(wifiname);                                     //
    Serial.print("WiFi 密码: ");                                  //
    Serial.println(wifipassword);                                 //


}
/**********************************************************************************
   函数:响应网站/setwifi目录的POST请求,收到请求后,运行get_WIFI_set_CALLback回调函数
   获取并格式化收到的POST数据
 *********************************************************************************/
void get_WIFI_set_CALLback()
{
    Serial.println("收到设置WIFI按钮");

    String rec_wifiname = "Xiaomi";
    String rec_wifipassword = "wifipassword";

    // 把SSID和password写成一个JSON格式
    StaticJsonDocument<200> wifi_json;                 // 创建一个JSON对象,wifi_json
    wifi_json["wifiname"] = rec_wifiname;              // 写入一个建和值
    wifi_json["wifipassword"] = rec_wifipassword;      // 写入一个键和值
    String wifi_json_str;                              // 定义一个字符串变量
    serializeJson(wifi_json, wifi_json_str);           // 生成JOSN的字符串
    str_write("/json/WIFIConfig.json", wifi_json_str); // 字符串写入
}


void seting_config_setup()
{
    Serial.println("Mounting FS...");
    spiffs_begin();
    read_sise();
    list_sp();
}

// 处理/LED-Control请求
void del_config()
{
    String file_cal = "/json/setConfig.json";
    // 从闪存中删除file_name文件
    if (SPIFFS.remove(file_cal))
    {

        Serial.print(file_cal);
        Serial.println(" remove sucess");
    }
    else
    {
        Serial.print(file_cal);
        Serial.println(" remove fail");
    }
}
/***********************************************************************************
   函数:
***********************************************************************************/
void spiffs_begin()
{
    if (SPIFFS.begin())
    { // 启动SPIFFS
        Serial.println("SPIFFS Started.");
    }
    else
    {
        Serial.println("SPIFFS Failed to Start.");
    }
}

void list_sp()
{
    Serial.println();
    String folder_all = "/"; // 被读取的文件夹
    spiffs_begin();
    // 显示目录中文件内容以及文件大小
    Dir dir = SPIFFS.openDir(folder_all); // 建立“目录”对象
    while (dir.next())
    {                                   // dir.next()用于检查目录中是否还有“下一个文件”
        Serial.println(dir.fileName()); // 输出文件名
    }
}

void read_data()
{
    str_read_or_show(file_name0, false);
    str_read_or_show(file_name1, false);
    str_read_or_show(file_name2, false);
    str_read_or_show(file_name3, false);
}
void read_sise()
{
    uint32_t realSize = ESP.getFlashChipRealSize();
    uint32_t ideSize = ESP.getFlashChipSize();
    FlashMode_t ideMode = ESP.getFlashChipMode();

    Serial.printf("Flash real id:   %08X\n", ESP.getFlashChipId());
    Serial.printf("Flash real size: %u\n\n", realSize);

    Serial.printf("Flash ide  size: %u\n", ideSize);
    Serial.printf("Flash ide speed: %u\n", ESP.getFlashChipSpeed());
    Serial.printf("Flash ide mode:  %s\n", (ideMode == FM_QIO ? "QIO" : ideMode == FM_QOUT ? "QOUT"
                                                                    : ideMode == FM_DIO    ? "DIO"
                                                                    : ideMode == FM_DOUT   ? "DOUT"
                                                                                           : "UNKNOWN"));

    if (ideSize != realSize)
    {
        Serial.println("Flash Chip configuration wrong!\n");
    }
    else
    {
        Serial.println("Flash Chip configuration ok.\n");
    }
}

猜你喜欢

转载自blog.csdn.net/yyandad/article/details/130303655