ESP32-C3实现非易失变量(Arduino IDE )

devtools/2024/10/17 15:40:29/

1效果

网页输入数据,串口打印数据。掉电后数据还在

2源码

#include <WiFi.h> // 包含WiFi库,用于处理WiFi连接
#include <WebServer.h> // 包含WebServer库,用于创建Web服务器
#include <Preferences.h> // 包含Preferences库,用于在非易失性存储中保存键值对// 定义接入点名称
const char* ssid = "ESP32C3";
WebServer server(80); // 创建Web服务器实例,监听80端口Preferences preferences; // 创建Preferences实例,用于存储数据// 处理根目录请求的函数
void handleRoot() {String html = "<html><body>" // 构建HTML响应"<form action=\"/save\" method=\"POST\">" // 表单提交到/save路由"Enter data: <input type=\"text\" name=\"data\">" // 输入框,用户可以输入数据"<input type=\"submit\" value=\"Save\">" // 提交按钮"</form></body></html>";server.send(200, "text/html", html); // 发送HTTP响应,状态码200表示成功,内容类型为text/html
}// 处理保存数据的函数
void handleSave() {if (server.hasArg("data")) { // 检查是否有名为"data"的参数String data = server.arg("data"); // 获取名为"data"的参数值// 将数据保存到Preferencespreferences.putString("myDataKey", data); // 使用"myDataKey"作为键保存数据server.send(200, "text/plain", "Data saved!"); // 发送成功保存的响应} else {server.send(400, "text/plain", "Bad Request"); // 如果没有"data"参数,发送400错误响应}
}// 初始化函数
void setup() {Serial.begin(115200); // 初始化串口通信,波特率为115200WiFi.softAP(ssid); // 创建一个名为ssid的接入点server.begin(); // 启动Web服务器// 初始化Preferences,创建或打开名为"storage"的命名空间,不允许在文件系统中创建新文件preferences.begin("storage", false);// 设置Web服务器路由server.on("/", handleRoot); // 当访问根目录时,调用handleRoot函数server.on("/save", HTTP_POST, handleSave); // 当通过POST方法访问/save时,调用handleSave函数
}// 主循环函数
void loop() {server.handleClient(); // 处理客户端请求// 读取Preferences中的数据并通过串口输出String data = preferences.getString("myDataKey", "No data saved"); // 读取键为"myDataKey"的数据,如果不存在则返回"No data saved"Serial.println("Data from Preferences: " + data); // 输出数据到串口delay(1000); // 等待1000毫秒(1秒),每秒输出一次
}

3重点解释区

3-1

<Preferences.h> 是 Arduino ESP32 环境中的一个库,用于在 ESP32 的非易失性存储器(NVS)上保存数据。这个库是 Arduino EEPROM 库的替代品,特别适用于存储多个小值,而不是几个大值。如果需要存储大量数据,可以考虑使用文件系统库,如 LitteFS5。

基本功能和使用方法

  1. 数据存储方式Preferences 库在 NVS 中以“命名空间(namespace)”的形式存储数据,每个命名空间包含一系列的“键值对(key-value pairs)”。键名(key)是数据项的名称,值(value)是该项数据的具体值。命名空间和键名都是字符串,且长度不超过15个字符。多个命名空间是允许的,且每个命名空间内的键名必须是唯一的5。

  2. 支持的数据类型Preferences 直接支持多种数据类型,包括布尔型、字符型、整型、长整型、浮点型、双精度型和字符串等5。

  3. 基本操作:使用 Preferences 库的基本步骤包括创建或打开命名空间、存储和检索数据、删除键值对、确定键值对的数据类型等。存储数据时,需要先打开命名空间,然后使用键名存储数据,最后关闭命名空间。检索数据时,同样需要先打开命名空间,然后使用键名获取数据,最后关闭命名空间5。

  4. #include <Preferences.h>void setup() {Serial.begin(115200);Serial.println();delay(2000);Preferences prefs; // 声明Preferences对象prefs.begin("mynamespace"); // 打开命名空间mynamespaceuint32_t count = prefs.getUInt("count", 0); // 获取当前命名空间中的键名为"count"的值count++; // 累加计数Serial.printf("这是系统第 %u 次启动\n", count);prefs.putUInt("count", count); // 将数据保存到当前命名空间的"count"键中prefs.end(); // 关闭当前命名空间
    }void loop() {// ...
    }
    

    布尔型(bool)

    存储布尔值:

    Preferences prefs;
    prefs.begin("mynamespace");
    prefs.putBool("myBool", true); // 存储布尔值 true
    prefs.end();
    

    获取布尔值:

    Preferences prefs;
    prefs.begin("mynamespace");
    bool myBool = prefs.getBool("myBool", false); // 获取布尔值,如果不存在则返回默认值 false
    prefs.end();
    

    字符型(int8_t)

    存储字符型值:

    Preferences prefs;
    prefs.begin("mynamespace");
    prefs.putChar("myChar", 'A'); // 存储字符 'A'
    prefs.end();
    

    获取字符型值:

    Preferences prefs;
    prefs.begin("mynamespace");
    char myChar = prefs.getChar("myChar", 'Z'); // 获取字符,如果不存在则返回默认值 'Z'
    prefs.end();
    

    整型(int32_t)

    存储整型值:

    Preferences prefs;
    prefs.begin("mynamespace");
    prefs.putInt("myInt", 123); // 存储整型值 123
    prefs.end();
    

    获取整型值:

    Preferences prefs;
    prefs.begin("mynamespace");
    int32_t myInt = prefs.getInt("myInt", -1); // 获取整型值,如果不存在则返回默认值 -1
    prefs.end();
    

    长整型(int32_t)

    存储长整型值(在 Preferences 库中,长整型和整型使用相同的数据类型和存储方法):

    Preferences prefs;
    prefs.begin("mynamespace");
    prefs.putLong("myLong", 1234567890); // 存储长整型值 1234567890
    prefs.end();
    

    获取长整型值:

    Preferences prefs;
    prefs.begin("mynamespace");
    int32_t myLong = prefs.getLong("myLong", -1); // 获取长整型值,如果不存在则返回默认值 -1
    prefs.end();
    

    浮点型(float)

    存储浮点型值:

    Preferences prefs;
    prefs.begin("mynamespace");
    prefs.putFloat("myFloat", 3.14f); // 存储浮点型值 3.14
    prefs.end();
    

    获取浮点型值:

    Preferences prefs;
    prefs.begin("mynamespace");
    float myFloat = prefs.getFloat("myFloat", 0.0f); // 获取浮点型值,如果不存在则返回默认值 0.0
    prefs.end();
    

    双精度型(double)

    存储双精度型值:

    Preferences prefs;
    prefs.begin("mynamespace");
    prefs.putDouble("myDouble", 3.14159265358979323846); // 存储双精度型值
    prefs.end();
    

    获取双精度型值:

    Preferences prefs;
    prefs.begin("mynamespace");
    double myDouble = prefs.getDouble("myDouble", 0.0); // 获取双精度型值,如果不存在则返回默认值 0.0
    prefs.end();
    

    字符串(const char*)

    存储字符串:

    Preferences prefs;
    prefs.begin("mynamespace");
    prefs.putString("myString", "Hello World"); // 存储字符串 "Hello World"
    prefs.end();
    

    获取字符串:

    Preferences prefs;
    prefs.begin("mynamespace");
    String myString = prefs.getString("myString", "Default"); // 获取字符串,如果不存在则返回默认值 "Default"
    prefs.end();
    

    请注意,字符串可以存储为 Arduino String 对象或 C-string(以空字符结尾的字符数组)。在存储和检索字符串时,确保使用正确的方法。如果使用 C-string,请确保字符串长度不超过 NVS 分区允许的最大长度。

何时调用 prefs.end();(运行后将清理此对象,数据还在就是不可用重新上电后可以看到数据但在运行到它是再次读取数据时读不到)

  1. 在完成所有数据操作后调用:在完成对 NVS 的所有读取和写入操作后,应该调用 prefs.end();。这通常是在一系列 put...()(用于写入数据)或 get...()(用于读取数据)方法调用之后。

  2. 在适当的作用域结束处调用:通常在函数或作用域结束前调用 prefs.end();,以确保资源得到及时释放。

prefs.end(); 的作用

  • 确保数据写入:调用 prefs.end(); 确保所有挂起的写入操作都已完成,并且数据已经安全地存储在 NVS 中。

  • 释放资源:这个方法会关闭 Preferences 实例与 NVS 的连接,并释放与之相关的内存和其他资源。

  • 防止数据损坏:如果不调用 prefs.end();,可能会导致数据未完全写入或损坏,特别是在断电或程序崩溃的情况下。

示例

Preferences prefs;void setup() {// 开始 Preferences 实例,指定命名空间prefs.begin("mynamespace", false); // false 表示不覆盖现有数据// 存储一些数据prefs.putInt("myInt", 123);prefs.putFloat("myFloat", 456.78);// 结束 Preferences 实例prefs.end();
}void loop() {// 其他代码...
}

http://www.ppmy.cn/devtools/126493.html

相关文章

uni-app写的微信小程序如何体积太大如何处理

方法一&#xff1a;对主包进行分包处理&#xff0c;将使用url: /pages/components/equipment/equipment跳转页面的全部拆分为分包&#xff0c;如url: /pagesS/components/equipment/equipment 在pages.json中添加 "subPackages": [{ "root"…

TensorFlow 的核心概念

TensorFlow 是一个开源的机器学习框架&#xff0c;由 Google 开发和维护。它提供了一个强大的工具集&#xff0c;用于构建和训练各种机器学习模型。 TensorFlow 的核心概念是计算图&#xff08;Computational Graph&#xff09;。计算图由节点&#xff08;Nodes&#xff09;和…

开发与部署项目依赖管理之旅:Docker和venv区别

Docker与venv的区别 Docker和虚拟环境&#xff08;venv&#xff09;都是用于管理依赖关系和隔离环境的工具&#xff0c;但它们服务的目的和特点有所不同。下面是它们的详细比较。 虚拟环境&#xff08;venv&#xff09; 目的&#xff1a; 特定于Python&#xff1a;venv专为…

客户端、PC端、移动端集成发票真伪验真API接口返回值说明

客户端、pc端、移动端集成翔云发票查验接口&#xff0c;在现如今财务管理喝税务合规越来越严的背景下&#xff0c;集成发票真伪验真接口有助于提升财务工作效率&#xff0c;防止税务风险&#xff0c;简化发票管理流程&#xff0c;提升发票管理与报销效率&#xff0c;合规管理税…

JavaScript高级——ES6基础入门

前言 ES6&#xff08;ECMAScript 6&#xff09;&#xff0c;也被称为ES2015&#xff0c;是JavaScript的第六个版本.它于2015年发布&#xff0c;并在现代JavaScript开发中扮演了重要的角色. 学习方法: 看千遍&#xff0c;不如自己动手写一遍 遇到问题不要怕&#xff0c;微笑着…

5分钟上线你的简历

可以直接看视频&#xff1a;bilibilihttps://www.bilibili.com/video/BV1Af2fYhE7T/?share_sourcecopy_web&vd_sourceb8022571ef78f8f53b223aa5d1f31096 1.十块钱注册一个域名 2. 登录github去fork代码&#xff0c;地址&#xff1a;简历前端模版 3.用github登录vercel …

2024-NewStarCTF-WEEK2

Web 你能在一秒内打出八句英文吗 逻辑就是获取页面上的8句英文&#xff0c;打开浏览器自动提交&#xff0c;让GPT写了个脚本&#xff0c;得到flag from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import …

maven的pom文件解读

<?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM/4.0.0 http://ma…