ESP32CAM日志写入SD卡仅出现乱码问题排查求助
问题原因及修复方案
核心错误分析
日志文件出现乱码的直接原因是写入了指针地址而非字符串内容,同时存在SD卡重复挂载/卸载的低效操作:
错误的
fwrite参数&info传递的是指针变量自身的地址,而非字符串的起始地址,导致写入的是指针的内存值(如L@?这类乱码),正确写法应为直接使用info。sizeof(info)返回的是指针类型的大小(ESP32上为4字节),而非字符串的实际长度,需替换为strlen(info)获取字符串长度。
SD卡重复挂载/卸载
每次调用Log函数都重新初始化并卸载SD卡,不仅效率极低,还可能导致文件系统不稳定,应改为初始化时挂载一次,仅在设备 shutdown 时卸载。缺乏错误检查
未校验fopen和Open_Card的返回值,若SD卡或文件操作失败会引发未定义行为。
修复后的代码
1. 全局SD卡初始化(建议放在setup函数中)
#include <string.h> #include <sys/stat.h> #include <sys/unistd.h> sdmmc_card_t *g_card = NULL; // 全局存储SD卡指针 // 初始化SD卡(仅调用一次) void Init_SD_Card() { g_card = Open_Card(); if (g_card == NULL) { // 处理SD卡初始化失败逻辑 return; } } // 卸载SD卡(仅在关机时调用) void Deinit_SD_Card() { if (g_card != NULL) { esp_vfs_fat_sdcard_unmount(MOUNT_POINT, g_card); g_card = NULL; } }
2. 修复后的Log函数
void Log(const char *info){ if (g_card == NULL || info == NULL) { return; // SD卡未初始化或输入为空,直接返回 } FILE *f; const char *file_foo = MOUNT_POINT"/Log.txt"; // 打开文件,不存在则创建 f = fopen(file_foo, "a"); if (f == NULL) { // 处理文件打开失败逻辑 return; } // 写入字符串内容 fwrite(info, 1, strlen(info), f); fwrite("\n", 1, 1, f); // 可选:添加换行符,提升日志可读性 fclose(f); }
3. 调用示例
// 在setup中初始化SD卡 void setup() { Init_SD_Card(); // ...其他初始化逻辑 } // 在需要记录日志的地方调用 const char *string_err = esp_err_to_name(wifi_err); Log(string_err); Log("This is my ip:");
额外注意事项
- 确保包含
<string.h>头文件,否则strlen函数无法正常使用。 - 若日志需要包含时间戳,可添加
strftime等函数生成时间字符串后拼接写入。 - SD卡文件系统操作建议添加适当的延时或使用文件系统缓存,避免频繁写入导致SD卡寿命缩短。
内容的提问来源于stack exchange,提问作者lightshadown
相关产品推荐
相关产品推荐

