ESP32 Arduino 框架中 Preferences 类的使用指导:函数讲解与实战示例

Arduino开发ESP32使用Preferences不能正常保存数据的解决方法 使用Preferences库中的各种方法都没有能成功保存数。怀疑是存储很多数据之后,nvs分区可能就满了,使用Preferences库中prefs.clear();函数清除数据有没有效果。 阅读详情

1. 引言:为什么需要 Preferences?

在 ESP32 开发中,我们经常需要存储一些配置参数、设备状态或用户数据,这些数据需要在设备断电重启后依然能够保留。虽然可以使用文件系统(如 SPIFFS、LittleFS)或 EEPROM 模拟库,但 ESP32 Arduino 核心库内置的 Preferences 类提供了一种更简单、高效且可靠的非易失性存储(NVS)解决方案。

Preferences 库封装了 ESP32 的非易失性存储(NVS)功能,具有以下优势:

  • 键值对存储:使用简单的键(字符串)来存取数据,无需管理复杂的文件路径。
  • 数据类型丰富:支持整型、浮点型、字符串、二进制数据等多种类型。
  • 命名空间隔离:不同功能模块的数据可以存放在不同的命名空间下,避免键名冲突。
  • 原子操作与磨损均衡:底层 NVS 机制保证了数据写入的原子性,并具有磨损均衡特性,延长 Flash 寿命。
  • 使用简便:无需手动初始化文件系统,API 直观易用。

2. 基本使用流程与头文件

使用 Preferences 前,需要包含相应的头文件并创建对象。

#include <Preferences.h>

Preferences preferences;

基本操作遵循“打开 -> 读写 -> 关闭”的流程,关闭操作会将数据真正提交到 Flash。

3. 核心函数详解

3.1 初始化与命名空间管理

  • begin(const char* name, bool readOnly=false, const char* partition_label=NULL)
    • 功能:打开一个命名空间。如果命名空间不存在,则创建它。
    • 参数:
      • name:命名空间名称,用于数据隔离。
      • readOnly:是否为只读模式打开。默认为 false(读写模式)。
      • partition_label:指定使用的 NVS 分区标签,通常为 NULL 使用默认的 “nvs” 分区。
    • 返回值:成功打开返回 true,失败返回 false。
  • end()
    • 功能:关闭当前命名空间,确保所有更改写入 Flash。这是一个重要的步骤,不应省略。

3.2 数据写入函数(Put)

用于存储数据。函数名通常以 put 开头。

  • putChar(const char* key, int8_t value):存储 8 位有符号整数。
  • putUChar(const char* key, uint8_t value):存储 8 位无符号整数。
  • putShort(const char* key, int16_t value):存储 16 位有符号整数。
  • putUShort(const char* key, uint16_t value):存储 16 位无符号整数。
  • putInt(const char* key, int32_t value):存储 32 位有符号整数。
  • putUInt(const char* key, uint32_t value):存储 32 位无符号整数。
  • putLong(const char* key, int32_t value):存储 32 位长整型(与 putInt 相同)。
  • putULong(const char* key, uint32_t value):存储 32 位无符号长整型(与 putUInt 相同)。
  • putLong64(const char* key, int64_t value):存储 64 位有符号整数。
  • putULong64(const char* key, uint64_t value):存储 64 位无符号整数。
  • putFloat(const char* key, float_t value):存储单精度浮点数。
  • putDouble(const char* key, double_t value):存储双精度浮点数。
  • putBool(const char* key, bool value):存储布尔值。
  • putString(const char* key, const String& value):存储字符串(String 对象)。
  • putString(const char* key, const char* value):存储字符串(C 风格字符串)。
  • putBytes(const char* key, const void* value, size_t len):存储任意二进制数据。

3.3 数据读取函数(Get)

用于读取数据。如果键不存在,则返回指定的默认值。

  • getChar(const char* key, int8_t defaultValue=0)
  • getUChar(const char* key, uint8_t defaultValue=0)
  • getShort(const char* key, int16_t defaultValue=0)
  • getUShort(const char* key, uint16_t defaultValue=0)
  • getInt(const char* key, int32_t defaultValue=0)
  • getUInt(const char* key, uint32_t defaultValue=0)
  • getLong(const char* key, int32_t defaultValue=0)
  • getULong(const char* key, uint32_t defaultValue=0)
  • getLong64(const char* key, int64_t defaultValue=0)
  • getULong64(const char* key, uint64_t defaultValue=0)
  • getFloat(const char* key, float_t defaultValue=NAN)
  • getDouble(const char* key, double_t defaultValue=NAN)
  • getBool(const char* key, bool defaultValue=false)
  • String getString(const char* key, const String& defaultValue=String(""))
  • size_t getBytes(const char* key, void* buf, size_t maxLen):读取二进制数据到缓冲区,返回实际读取的字节数。

3.4 其他实用函数

  • remove(const char* key):删除指定键及其值。
  • clear():清除当前命名空间下的所有键值对。
  • freeEntries():获取当前命名空间下剩余的可用条目数(键值对数量)。
  • isKey(const char* key):检查指定键是否存在。

4. 综合使用示例

下面是一个完整的示例,演示如何存储 WiFi 配置、设备启动次数和一段自定义二进制数据。

#include <Preferences.h>

Preferences prefs;

void setup() {
  Serial.begin(115200);
  delay(1000);

  // 1. 打开(或创建)名为 "my_app" 的命名空间
  if (!prefs.begin("my_app")) {
    Serial.println("Failed to open preferences namespace");
    return;
  }

  // 2. 读写数据
  // 读取启动次数,如果不存在则默认为0,然后加1并写回
  uint32_t bootCount = prefs.getUInt("boot_count", 0);
  bootCount++;
  prefs.putUInt("boot_count", bootCount);
  Serial.printf("Device boot count: %u\n", bootCount);

  // 存储 WiFi SSID 和密码
  prefs.putString("wifi_ssid", "MyHomeWiFi");
  prefs.putString("wifi_pass", "SecurePassword123");

  // 读取 WiFi 配置(如果之前存储过)
  String ssid = prefs.getString("wifi_ssid", "");
  String pass = prefs.getString("wifi_pass", "");
  if (ssid.length() > 0) {
    Serial.printf("Stored WiFi SSID: %s\n", ssid.c_str());
    // 注意:实际项目中不应在日志中打印密码
  }

  // 存储和读取浮点数(例如传感器校准值)
  float calibrationFactor = 1.025;
  prefs.putFloat("cal_factor", calibrationFactor);
  float readCal = prefs.getFloat("cal_factor", 1.0);
  Serial.printf("Calibration factor: %.3f\n", readCal);

  // 存储和读取二进制数据(例如一个简单的结构体)
  struct MyData {
    uint8_t id;
    uint16_t value;
  } dataToStore = {0xAB, 1234};
  prefs.putBytes("my_struct", &dataToStore, sizeof(dataToStore));

  MyData dataRead;
  size_t len = prefs.getBytes("my_struct", &dataRead, sizeof(dataRead));
  if (len == sizeof(MyData)) {
    Serial.printf("Read binary data: ID=0x%02X, Value=%u\n", dataRead.id, dataRead.value);
  }

  // 3. 关闭命名空间,提交更改
  prefs.end();
  Serial.println("Preferences saved successfully.");
}

void loop() {
  // 主循环无需操作 Preferences
  delay(10000);
}

5. 高级技巧与注意事项

5.1 命名空间规划

为不同的功能模块使用不同的命名空间,例如 "wifi_config"、"device_settings"、"user_data"。这可以提高代码的可维护性,并允许单独清除某个模块的数据。

5.2 错误处理

始终检查 begin() 的返回值。写入失败可能由于 NVS 分区已满或 Flash 损坏。

5.3 数据更新策略

频繁更新同一个键可能会加速 Flash 磨损。对于频繁变化的数据(如传感器实时值),应考虑在 RAM 中缓存,定期或仅在必要时写入 Preferences。

5.4 字符串长度限制

单个键值对的总大小(键名长度 + 数据长度)存在限制(通常约为 1984 字节)。过长的字符串应分段存储或考虑使用文件系统。

5.5 与文件系统的选择

使用 Preferences 当:存储键值对形式的配置、状态标志、计数器等小型结构化数据。
使用 SPIFFS/LittleFS 当:需要存储大文件、日志、网页资源或非结构化的长文本。

6. 常见问题排查(FAQ)

  • Q:数据写入后,重启读取不到?
    A:确保每次修改后都调用了 end() 或 close()(Preferences 类中 end() 即关闭)。
  • Q:begin() 失败返回 false?
    A:检查 NVS 分区是否在分区表中被正确配置,或 Flash 存储空间是否已满。
  • Q:可以存储数组吗?
    A:可以,使用 putBytes 和 getBytes 来存储和读取整个数组。
  • Q:如何清空所有数据?
    A:在 Arduino IDE 的“工具”菜单中,选择“擦除 Flash”选项。在代码中,可以对特定命名空间使用 clear()。

7. 总结

Preferences 库是 ESP32 Arduino 开发中管理非易失性数据的利器。它通过简单的键值对 API 和内置的磨损均衡机制,让数据持久化变得安全便捷。掌握其核心函数和最佳实践,可以有效地存储设备配置、运行状态和用户设置,提升项目的可靠性。

建议在实际项目中,结合具体需求规划命名空间和键名,并养成良好的“打开-关闭”习惯,确保数据完整性。

护网日志分析基础 简要介绍日志分析,给出日志分析的步骤和思路。要求根据日志中的字符串特征,识别攻击者的攻击工具;根据日志中的行为特征,确定攻击者可能的攻击手段等。总结归纳护网中常见的中间件Tomcat、Apache、Weblogic、Nginx、Apache、IIS、MySQL、SQL Server、Oracle的日志路径和日志配置文件路径等。 阅读详情

相关推荐

山东大学FPGA课程实验一 加法器设计

电子设计自动化与FPGA设计,实验一 加法器设计

2503_91283667的博客 869

Arduino方式开发ESP32笔记:使用Preferences保存数据

本文大部分参考使用Arduino开发ESP32(18):使用Preferences保存数据 引出 在其他单片机上我们可以使用单片机自带Flash来保存一些数据,在ESP32上也可以这样,在ESP32的Flash上存在一个叫做nvs的分区,使用Arduino方式来开发的话,可以直接使用Preferences库来操作它。 大小 Arduino core for the ESP32中默认分区( Partition Scheme: “Default 4MB with spiffs (1.2MB APP /1.5MB

qlexcel的专栏 4435

Oracle11g安装教程、配置实例、监听、客户端程序详解_Windows篇

Oracle11g安装教程、配置实例、监听、客户端程序详解_Windows篇 文章目录Oracle11g安装教程、配置实例、监听、客户端程序详解_Windows篇前言一、数据库的安装前准备,前提是没有安装过!!!二、仅安装数据库软件(数据库运行环境)三、添加数据库实例四、设置监听程序,让数据库可以通过网络访问五、为目标数据库设置网名总结 前言 如果需要安装包:联系我看到会给你链接,因为现在官网已经不提供10g,11g的安装包了,在网盘保存望悉知(回复不会很及时,下班看到会回复敬请谅解)。 提示:以下

zhx__的博客 5630

使用Arduino开发ESP32(18):使用Preferences保存数据

文章目录目的基础说明使用演示API罗列总结 目的 对于传统的单片机来说我们如果要固化保存小批量的数据的话通常会使用EEPROM,在Arduino core for the ESP32中也有相关的功能。不过对于ESP32来说官方还提供了一种叫做 Preferences 的功能,这个功能也可以用来固化保存数据,并且使用上比EEPROM更加方便。这篇文章将对此做个使用说明。 基础说明 ESP32官方在Flash上建立了一个叫做nvs的分区,而Preferences功能就是建立在该分区上的。Arduino core

Naisu的各种笔记 1万+

别再为采样窗口发愁了!手把手教你用STM32实现三电阻分扇区电流采样(附代码避坑)

本文详细介绍了STM32平台下三电阻分扇区电流采样的实现方法,重点解决采样窗口选择不当和扇区切换逻辑问题。通过PWM定时器与ADC协同工作的底层机制分析,提供可移植的代码示例和实战经验,帮助工程师在电机矢量控制(FOC)系统中实现高精度相电流采样。

weixin_42531516的博客 165

Linux系统下奥比中光Astra Pro相机SDK部署与避坑指南

本文详细指导了在Linux系统下部署奥比中光Astra Pro深度相机SDK的全过程,涵盖系统准备、SDK安装、设备权限配置及常见问题排查。重点解析了USB设备规则配置这一关键步骤,并提供了Python与C++项目的集成方法,旨在帮助开发者快速完成相机配置,避免常见陷阱。

weixin_28455801的博客 298

Arduino入门教程

Arduino入门教程

ordersyhack 9165

让 AI 变聪明的 20 条指令:如何让大模型回答得更精准、更专业、更实事求是

让 AI 变聪明,本质上不是写几句神奇咒语,而是把你的任务表达得更清楚,把事实标准设得更严格,把输出格式规定得更明确,把不确定性管理得更认真,把历史对话利用得更充分。大模型的强项是语言生成、信息组织、模式归纳和方案扩展;弱项是事实核验、实时更新、责任判断和对模糊意图的准确猜测。好的指令,就是在用人的判断弥补模型的弱点,让模型把强项发挥在正确的地方。

Sumarua的博客 1477

Arduino-ESP32 Preferences库使用详解

在ESP32开发中,数据持久化存储是一个常见需求。Arduino-ESP32项目提供的Preferences库是一个专为ESP32设计的非易失性存储解决方案,它替代了传统的Arduino EEPROM库,提供了更强大、更可靠的数据存储功能。 Preferences库利用ESP32芯片内置的NVS(Non-Volatile Storage)存储机制,能够在设备重启或断电后保留数据。与EEPROM相...

gitblog_00052的博客 633

用树莓派Pico低成本更新USB-C PD控制器固件实战指南

固件更新是嵌入式系统开发与维护中的核心环节,它直接决定了硬件设备的功能、性能与兼容性。其原理通常是通过特定的通信接口(如SWD、JTAG、UART或USB)与设备内部的Bootloader建立连接,将新的程序代码安全写入非易失性存储器。在USB Power Delivery(PD)和Type-C生态中,固件更新技术尤为重要,它能修复协议握手Bug、适配新设备并提升供电策略的灵活性。本文聚焦于一个典型的工程实践场景:如何利用广泛普及且成本极低的树莓派Pico开发板,作为USB-C协议到I²C协议的转换桥,实现

weixin_27869497的博客 455

Simulink仿真模块-Signal Generator

Signal Generator:生成各种波形 所在的位置库为:Simulink / Sources 模型为: 说明 Signal Generator模块可以产生四种不同波形: 正弦波 方波 锯齿波 随机 可以使用 hertz 或 rad/sec 为单位表示信号参数。双击模型可以选择需要生成的波形,如图所示: 使用默认参数值,可以获得下列波形之一: 波形 波形输出 正弦波 ...

jk_101的博客 2652

【保姆级超详细还免费】Arduino-ESP32 Preferences库使用详解

Arduino-ESP32 Preferences库使用详解 【免费下载链接】arduino-esp32 Arduino core for the ESP32 项目地址: https://gitcode.com/GitHub_Tr...

gitblog_00432的博客 885

论文必备 - YOLOv12热力图可视化,支持指定模型,指定显示层,设置置信度,以及10种可视化实现方式

本文带来的是YOLOv12热力图可视化功能,支持,以及。我们经常看到一些论文里绘制了不同的热力图,一方面能够直观的感受其模型的有效性,另一方面也丰富了论文内容。特别是在使用了注意力模块的网络中,热力图就可以验证注意力机制是否真正聚焦到了预期的重要特征上,以便对模型的有效性和合理性进行评估。例如这篇文章中展示的,就很能够表达作者改进后的模型相比之前模型的优越性。

Limiiiing的博客 1705

Arduino-ESP32 Preferences库:键值对数据存储

在嵌入式系统开发中,非易失性存储(Non-Volatile Storage,NVS)是保存配置数据、设备状态和用户设置的关键技术。Arduino-ESP32的Preferences库提供了一个简单易用的键值对(Key-Value)存储接口,让开发者能够轻松地在ESP32的闪存中存储和检索各种数据类型。 Preferences库基于ESP-IDF的NVS(Non-Volatile Storage)...

gitblog_00218的博客 1006

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

快速上手 Arduino-ESP32:用 Arduino 语法完整开发 ESP32 指南

Arduino-ESP32 是乐鑫官方的 Arduino 核心,把 ESP32 系列芯片的驱动、编译和烧录都打包成了 Arduino 开发板包。装好之后,GPIO、PWM、串口、WiFi、蓝牙这些功能都能用熟悉的 Arduino 库调用,不用直接接触 ESP-IDF。适合刚接触 ESP32 的初学者、想快速验证物联网创意的硬件爱好者,以及希望把 Arduino 经验平移到双核 Wi-Fi 芯片上的

gitblog_00769的博客 734

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

ESP32终极开发指南:5分钟快速上手Arduino物联网项目

还在为物联网开发的高门槛而烦恼吗?想快速构建智能家居、工业控制或可穿戴设备,却苦于硬件选型和复杂配置?今天,我将为你介绍一个革命性的解决方案——Arduino-ESP32开发框架。这个开源项目为ESP32系列芯片提供了完整的Arduino兼容支持,让你能在熟悉的开发环境中轻松驾驭强大的ESP32硬件,快速实现物联网创意! ## 为什么你需要Arduino-ESP32? 在物联网开发领域,开发者

gitblog_00280的博客 946

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

Arduino ESP32 完整上手实战:四关通关,从拆箱到联网一次走完

arduino-esp32 是乐鑫官方维护的 Arduino 开发板支持包(Arduino core for the ESP32 family of SoCs),它让 ESP32、ESP32-S3、ESP32-C3 等全家族芯片都能用熟悉的 Arduino 语法编程,是零基础物联网爱好者最值得优先学习的入门路径。这篇实战教程把完整上手过程拆成四个关卡,每关都有明确通关标准,跟着走一遍,你就能完成开

gitblog_01041的博客 693

三步搞定物联网开发:Arduino-ESP32快速上手指南

你是否曾想过,用一块小小的开发板就能打造智能家居、环境监测、甚至工业控制设备?今天,我将为你介绍一个让物联网开发变得像搭积木一样简单的神奇工具——**Arduino-ESP32**。这不仅仅是一个开发框架,更是连接现实世界与数字世界的桥梁,让你在短短几小时内就能创造出功能强大的智能设备。 想象一下,你正在为家里的植物设计一个自动浇水系统,或者想制作一个能远程监控室内温湿度的智能传感器。传统的嵌入

gitblog_01008的博客 750

ESP32 开发环境搭建全流程:Arduino IDE 配好 arduino-esp32 就能跑

[arduino-esp32](https://link.gitcode.com/i/7a79c9db8f0dc1963c6cba5a671ef18a) 是乐鑫为 ESP32 系列芯片提供的 Arduino 官方核心,配好它之后,一块 ESP32 开发板就能在 Arduino IDE 里完成编译、烧录和串口调试,WiFi、蓝牙、传感器、屏幕这些外设生态也全部可以直接调用。这篇教程面向刚接触 [ES

gitblog_00320的博客 1092

Arduino ESP32-C3 入门初探

STM32的涨价依然没有停止的趋势,使得很多小型设备不得不考虑其他的MCU方案, 随着乐鑫ESP-C3和ESP-S2的发布量产,价格上有很大的优势,如果能够学会ESP32,使用ESP32作为MCU也是一个方向, 同时也能熟悉下RISC-V 架构的处理器,毕竟在新起的IOT领域RISC-V架构也有很大的竞争力的。 正好买了几款ESP32-C3的小开发板(是安信可的,因为乐鑫原厂的贵好几倍……),找了个时间捣鼓一了下,随便找了一块开发板长这样。 本着以快速跑起来的原则,没有使用ESP-IDF(但是后面肯定是

不浮夸,不将就,认真对待学知识的我们 1万+

3小时玩转ESP32:Arduino生态下的智能硬件开发终极指南

还在为复杂的嵌入式开发环境头疼吗?想要用简单的Arduino语法开发强大的ESP32项目却不知从何开始?今天,我要带你走进Arduino-ESP32的世界,这是一套让ESP32系列芯片在Arduino生态中焕发新生的开发框架。无论你是物联网新手还是经验丰富的开发者,都能在这里找到适合自己的开发路径。 **Arduino-ESP32**是Espressif官方支持的Arduino核心,它为ESP3

gitblog_01022的博客 950

arduino-esp32 完整指南:30 分钟跑通首次烧录,4 类上传报错一次排查干净

Arduino IDE 刚装好,开发板管理器里也选好了型号,点击上传,进度条却在 5% 处卡死,控制台弹出一行红字:`Failed to connect to ESP32: No serial data was received`。重启、重装驱动、甚至开始怀疑板子坏了——多数人第一次用 arduino-esp32 核心时,都卡在这一步。先别急着怀疑板子,这类报错九成是下载模式或串口没对上。这篇指南

gitblog_00685的博客 1015

Arduino ESP32 核心库:15 分钟完成 ESP32 开发环境搭建与串口验证

Arduino ESP32 核心库(本仓库)把 Espressif ESP32 系列芯片接入 Arduino 生态:用熟悉的 `setup/loop` 就能写 WiFi、蓝牙、传感器程序。按本文三个检查点操作,约 15 分钟即可编译并上传第一个验证程序。 ## 三问自检:ESP32 开发环境的前置条件 动手前先确认三件事,任何一问答"否",先按替代方案处理再往下走。 **1. 操作系统是 6

gitblog_00993的博客 768

ESP32物联网开发:如何用Arduino框架快速构建专业级解决方案?

还在为ESP32底层开发的复杂性而苦恼?面对ESP-IDF的陡峭学习曲线和繁琐配置,是否渴望一种更高效、更易用的开发方式?Arduino-ESP32项目正是为解决这一痛点而生——它为ESP32系列芯片提供了完整的Arduino兼容支持,让你在熟悉的开发环境中轻松驾驭强大的ESP32硬件。这个开源项目将ESP32的强大性能与Arduino的易用性完美结合,为物联网开发者提供了从原型到产品的完整解决方

gitblog_00374的博客 631

Arduino-ESP32:用Arduino生态解锁ESP32物联网开发的完整解决方案

物联网开发面临硬件复杂、环境配置繁琐和生态系统碎片化的挑战。传统ESP32开发需要深入理解底层寄存器操作,而Arduino生态又缺乏对ESP32高级功能的完整支持。Arduino-ESP32项目完美解决了这一矛盾,为ESP32系列芯片提供了完整的Arduino兼容支持,让开发者能在熟悉的Arduino环境中轻松驾驭强大的ESP32硬件,将开发效率提升3倍以上。 ## 硬件抽象层:统一的外设管理架

gitblog_00434的博客 337

ESP32 Arduino终极指南:快速构建智能物联网设备的完整教程

还在为物联网项目开发而烦恼吗?想用简单的Arduino语法控制强大的ESP32芯片吗?今天我要为你介绍一个改变游戏规则的开源项目——Arduino-ESP32!这个项目让ESP32系列芯片(包括ESP32、ESP32-C3、ESP32-S3等)完美融入Arduino生态系统,让你用熟悉的Arduino编程方式,轻松构建智能家居、工业传感器、可穿戴设备等各种物联网应用。 ## 为什么你需要关注Ar

gitblog_00578的博客 952
上一篇: C语言组播的使用
下一篇: QT_Creater开发常见错误解决办法
西装没钱买
博客等级 码龄4年 620粉丝 52原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值