ESP32使用SdFat库向SDVolume Cache写入浮点数及字符串的问题
解决方案
你当前的代码采用固定4字节步长写入,仅适用于长度固定的单字符内容,写入浮点数或String这类长度可变的内容时,需要改为动态偏移量记录写入位置,修改后的代码及说明如下:
可用示例代码
#include <SdFat.h> SdFat sd; // 替换为你硬件对应的SD卡CS引脚 const uint8_t SD_CS_PIN = 5; void writeVarToSdCache() { // 此处省略SD卡初始化逻辑,请确保SD卡已成功挂载后再执行以下操作 uint32_t writeSectorNum = 0; // 替换为你实际要写入的SD扇区号 // 若需要覆盖整个扇区无需保留原有内容,可替换为uint8_t* pCache = sd.vol()->cacheClear(); uint8_t* pCache = sd.vol()->cacheRead(writeSectorNum); if (!pCache) { // 缓存获取失败时的错误处理逻辑,比如串口打印报错 return; } // 初始化缓存区为空格,可根据你的需求调整 memset(pCache, ' ', 512); // 用动态偏移量代替固定步长,记录当前写入位置 uint16_t curOffset = 0; int writeByteNum; // ------------------- 写入浮点数示例 ------------------- float targetFloat = 19.876; char floatBuf[16]; // dtostrf参数:目标浮点数、最小输出宽度、小数保留位数、存储缓冲区 dtostrf(targetFloat, 1, 3, floatBuf); // 按你的格式拼接内容,snprintf会自动避免缓存溢出 writeByteNum = snprintf((char*)pCache + curOffset, 512 - curOffset, "r,%s\n", floatBuf); if (writeByteNum > 0) { curOffset += writeByteNum; } // ------------------- 写入String示例 ------------------- String targetStr = "sensor_data_001"; writeByteNum = snprintf((char*)pCache + curOffset, 512 - curOffset, "r,%s\n", targetStr.c_str()); if (writeByteNum > 0) { curOffset += writeByteNum; } // 如果需要循环写入多条数据,可把上面的写入逻辑放到循环中,增加判断curOffset < 512 - 20即可(预留单条数据最大长度) // 标记缓存为脏,告知SdFat该缓存内容需要写入SD卡 sd.vol()->cacheSetDirty(); // 若需要立即写入无需延迟落盘,可额外调用以下方法 // sd.vol()->cacheWrite(writeSectorNum); }
注意事项
- 如果对性能要求不高,浮点数转字符串也可以直接用
String(targetFloat).c_str(),无需额外声明char缓冲区,写法更简洁。 - 不要省略
cacheSetDirty()调用,否则你修改的缓存内容不会同步到SD卡的物理存储上。 - 如果你不知道需要写入的扇区号,说明你的使用场景可能不需要直接操作Volume Cache,直接用SdFat提供的File类写文件即可,底层会自动处理缓存逻辑。
内容的提问来源于stack exchange,提问作者user11092642
相关产品推荐
相关产品推荐

