在物联网设备开发中,数据存储是至关重要的一环。你是否遇到过这些问题:
Arduino-ESP32提供了多种文件系统解决方案,本文将深入解析SPIFFS、LittleFS和SD卡三种主流存储方案,帮助你做出最佳选择。
SPIFFS(SPI Flash File System)是专为SPI NOR flash设计的嵌入式文件系统:
特性 | 说明 | 适用场景 |
---|---|---|
轻量级 | 代码体积小,内存占用低 | 资源受限设备 |
磨损均衡 | 基本均衡算法 | 中等写入频率 |
掉电保护 | 有限保护机制 | 非关键数据存储 |
目录支持 | 有限目录功能 | 简单文件结构 |
#include "FS.h"
#include "SPIFFS.h"
#define FORMAT_SPIFFS_IF_FAILED true
void setup() {
Serial.begin(115200);
// 初始化SPIFFS
if(!SPIFFS.begin(FORMAT_SPIFFS_IF_FAILED)){
Serial.println("SPIFFS挂载失败");
return;
}
// 获取文件系统信息
Serial.printf("总空间: %d bytes\n", SPIFFS.totalBytes());
Serial.printf("已用空间: %d bytes\n", SPIFFS.usedBytes());
// 文件操作示例
writeFile(SPIFFS, "/config.txt", "device_id=12345");
readFile(SPIFFS, "/config.txt");
}
// 写入文件函数
void writeFile(fs::FS &fs, const char *path, const char *message) {
File file = fs.open(path, FILE_WRITE);
if(file.print(message)) {
Serial.println("文件写入成功");
}
file.close();
}
// 读取文件函数
void readFile(fs::FS &fs, const char *path) {
File file = fs.open(path);
while(file.available()) {
Serial.write(file.read());
}
file.close();
}
通过实际测试,SPIFFS在不同操作下的性能表现:
操作类型 | 文件大小 | 耗时(ms) | 备注 |
---|---|---|---|
顺序写入 | 1KB | 15 | 小文件快速写入 |
随机读取 | 1KB | 2 | 读取速度优秀 |
目录遍历 | 100文件 | 120 | 文件较多时较慢 |
LittleFS是ESP32推荐的现代文件系统,相比SPIFFS有显著。
#include <LittleFS.h>
void setup() {
Serial.begin(115200);
// LittleFS初始化
if(!LittleFS.begin(true)){
Serial.println("LittleFS挂载失败");
return;
}
// 创建多级目录
createDirRecursive("/system/config/network");
// 原子写入操作
atomicWrite("/system/config/network/wifi.txt", "ssid=MyWiFi\npassword=123456");
// 文件系统信息
printFSInfo();
}
// 递归创建目录
void createDirRecursive(const char *path) {
char *pathCopy = strdup(path);
char *ptr = strchr(pathCopy, '/');
while(ptr != NULL) {
*ptr = '\0';
if(!LittleFS.exists(pathCopy)) {
LittleFS.mkdir(pathCopy);
}
*ptr = '/';
ptr = strchr(ptr + 1, '/');
}
free(pathCopy);
}
// 原子写入(避免数据损坏)
void atomicWrite(const char *path, const char *content) {
String tempPath = String(path) + ".tmp";
File tempFile = LittleFS.open(tempPath.c_str(), FILE_WRITE);
tempFile.print(content);
tempFile.close();
// 原子重命名
LittleFS.rename(tempPath.c_str(), path);
}
// 使用缓冲区优化大文件操作
void optimizedFileCopy(const char *src, const char *dst) {
const size_t bufferSize = 4096; // 4KB缓冲区
uint8_t buffer[bufferSize];
File source = LittleFS.open(src, FILE_READ);
File destination = LittleFS.open(dst, FILE_WRITE);
while(source.available()) {
size_t bytesRead = source.read(buffer, bufferSize);
destination.write(buffer, bytesRead);
}
source.close();
destination.close();
}
// 批量文件操作
void batchFileOperations() {
// 使用事务性操作提高性能
LittleFS.beginTransaction();
for(int i = 0; i < 100; i++) {
String filename = "/data/sensor_" + String(i) + ".txt";
writeFile(LittleFS, filename.c_str(), "sensor data");
}
LittleFS.endTransaction();
}
SD卡通过SPI接口连接ESP32,典型接线方式:
ESP32引脚 | SD卡引脚 | 功能 |
---|---|---|
GPIO14 | CLK | 时钟 |
GPIO15 | MISO | 主入从出 |
GPIO2 | MOSI | 主出从入 |
GPIO13 | CS | 片选 |
#include "SD.h"
#include "SPI.h"
#define SD_CS 13
void setup() {
Serial.begin(115200);
// SD卡初始化
if(!SD.begin(SD_CS)){
Serial.println("SD卡挂载失败");
return;
}
uint8_t cardType = SD.cardType();
if(cardType == CARD_NONE){
Serial.println("未检测到SD卡");
return;
}
Serial.print("SD卡类型: ");
switch(cardType){
case CARD_MMC: Serial.println("MMC"); break;
case CARD_SD: Serial.println("SDSC"); break;
case CARD_SDHC: Serial.println("SDHC"); break;
default: Serial.println("未知"); break;
}
// 获取容量信息
uint64_t cardSize = SD.cardSize() / (1024 * 1024);
Serial.printf("SD卡大小: %lluMB\n", cardSize);
}
// 大数据文件处理
void processLargeData() {
File dataFile = SD.open("/sensor_data.csv", FILE_APPEND);
// 写入CSV格式数据
dataFile.print("timestamp,temperature,humidity\n");
for(int i = 0; i < 1000; i++) {
dataFile.printf("%lu,%.2f,%.2f\n",
millis(),
random(200, 300) / 10.0,
random(300, 800) / 10.0);
}
dataFile.close();
}
特性 | SPIFFS | LittleFS | SD卡 |
---|---|---|---|
最大容量 | 4-16MB | 4-16MB | 32GB+ |
写入速度 | 中等 | 快 | 取决于卡速 |
读取速度 | 快 | 很快 | 快 |
目录性能 | 差 | 优秀 | 优秀 |
磨损均衡 | 基本 | 优秀 | 优秀 |
掉电保护 | 有限 | 优秀 | 优秀 |
适用场景 | 配置存储 | 频繁读写 | 大数据存储 |
class DeviceConfig {
private:
const char* configPath = "/config/device.json";
public:
bool saveConfig(const String& jsonConfig) {
if(!LittleFS.begin(true)) return false;
// 确保配置目录存在
if(!LittleFS.exists("/config")) {
LittleFS.mkdir("/config");
}
// 原子写入配置
atomicWrite(configPath, jsonConfig.c_str());
LittleFS.end();
return true;
}
String loadConfig() {
if(!LittleFS.begin(false)) return "";
if(LittleFS.exists(configPath)) {
File configFile = LittleFS.open(configPath, FILE_READ);
String content = configFile.readString();
configFile.close();
LittleFS.end();
return content;
}
LittleFS.end();
return "";
}
};
class DataLogger {
private:
fs::FS* filesystem;
const char* logBasePath = "/logs";
public:
DataLogger(fs::FS& fs) : filesystem(&fs) {}
bool logSensorData(const String& sensorName, float value) {
String dateStr = getDateString();
String filePath = String(logBasePath) + "/" + dateStr + "/" + sensorName + ".csv";
// 创建日期目录
String datePath = String(logBasePath) + "/" + dateStr;
if(!filesystem->exists(datePath.c_str())) {
filesystem->mkdir(datePath.c_str());
}
// 写入数据
File logFile = filesystem->open(filePath.c_str(), FILE_APPEND);
if(logFile) {
logFile.printf("%lu,%.2f\n", millis(), value);
logFile.close();
return true;
}
return false;
}
};
挂载失败
写入速度慢
数据损坏
来源:https://blog.csdn.net/gitblog_00074/article/details/151563479
四位数码管是一种常见的LED显示器件,主要用于显示数字信息。
ESP32-P4-WIFI6-DEV-KIT是一款微雪(Waveshare)设计的基于 ESP32-P4 的多媒体开发板,并集成 ESP32-C6,支持 Wi-Fi 6 和 BLE 5 无线连接。它提供丰富的人机交互接口,包括 MIPI-CSI (集成图像信号处理器 ISP)、MIPI-DSI、SPI、I2S、I2C、LED PWM、MCPWM、RMT、ADC、UART 和 TWAI 等。
ESP-Hosted 解决方案提供了将 ESP 板用作 Wi-Fi 和 Bluetooth/BLE 连接的通信处理器的方法。
ESP-Hosted 提供了一种将ESP芯片和模组用作通信协处理器的解决方案,该解决方案为主机微处理器或微控制器提供无线连接,使主机能够与其他设备通信。简单来说为网卡方案。
Arduino+ESP32上使用TFT_eSPI库快速点亮这个屏幕,驱动芯片ST7789
本文给出了一个ESP32与SPI 接口TFT显示屏接线的详细说明,供大家参考。
本文讲解如何在Micropython环境下使用ESP32的ESPNow功能进行数据传输。
ESP-Dongle 是一款基于 ESP32-S3 芯片开发的多功能 USB Device 解决方案。它不仅外形小巧,功能齐全,更集成了无线 U 盘、SD 卡读取以及 USB 无线网卡等多项功能。
ESP32 系列芯片可以利用 CSI 数据实现动作检测和存在检测。无论是自动调节灯光、风扇,还是节能控制,CSI 技术为智能家居带来了新的可能性。随着 CSI 技术的发展,未来的智能家居将能够更精确地感知和响应我们的行为,实现更高效、更人性化的控制。
ESP32-FreeRTOS项目提供了丰富的示例,帮助开发者快速掌握ESP32的硬件功能和FreeRTOS实时操作系统。
本节我们在迭代二的基础上使用四位数码管和OLED显示屏显示相关交互信息。