如何用Arduino读取SD卡中的最后一行?
Arduino读取SD卡文件最后一行的实现方案
你目前的代码能读取第一行,但要读取最后一行,核心思路是要么逐行记录直到文件末尾(适合小文件),要么从文件末尾倒推定位最后一行的起始位置(适合大文件,效率更高)。先指出你现有代码里的问题:if((cr == '\n') && ("LAST LINE?"))逻辑无效,字符串常量在条件判断里永远为真,且没有判断文件是否读到末尾。
方法一:逐行遍历记录(简单易读,适合小文件)
从头读到尾,每次读取一行并覆盖之前的记录,最后保留的内容就是最后一行。
#include <SD.h> #include <SPI.h> File SD_File; const int pinCS = 10; // 根据实际文件行长度调整缓冲区大小 char lastLine[128]; char tempLine[128]; void setup() { Serial.begin(9600); // 初始化SD卡并做异常判断 if (!SD.begin(pinCS)) { Serial.println("SD卡初始化失败"); return; } // 写入测试内容(可选,用于验证功能) SD_File = SD.open("test.txt", FILE_WRITE); if (SD_File) { SD_File.println("第一行内容"); SD_File.println("第二行内容"); SD_File.println("最后一行内容"); SD_File.close(); } else { Serial.println("打开文件写入失败"); } // 打开文件读取最后一行 SD_File = SD.open("test.txt"); if (SD_File) { // 初始化缓冲区为空 lastLine[0] = '\0'; // 逐行读取文件内容 while (SD_File.readBytesUntil('\n', tempLine, sizeof(tempLine)-1)) { // 用当前行覆盖上一行,最终保留最后一行 strcpy(lastLine, tempLine); // 去除Windows格式换行的'\r'字符 int len = strlen(lastLine); if (len > 0 && lastLine[len-1] == '\r') { lastLine[len-1] = '\0'; } } SD_File.close(); // 输出结果 Serial.println("文件最后一行内容:"); Serial.println(lastLine); } else { Serial.println("打开文件读取失败"); } } void loop() { // 无需循环操作 }
方法二:从文件末尾倒推定位(高效,适合大文件)
利用SD卡文件的size()和seek()方法,从文件末尾往前找第一个换行符,定位到最后一行的起始位置后再读取,避免遍历整个大文件。
#include <SD.h> #include <SPI.h> File SD_File; const int pinCS = 10; char lastLine[128]; void setup() { Serial.begin(9600); if (!SD.begin(pinCS)) { Serial.println("SD卡初始化失败"); return; } // 写入测试内容(可选) SD_File = SD.open("test.txt", FILE_WRITE); if (SD_File) { SD_File.println("测试行1"); SD_File.println("测试行2"); SD_File.println("最终行"); SD_File.close(); } else { Serial.println("写入文件失败"); } SD_File = SD.open("test.txt"); if (SD_File) { unsigned long fileSize = SD_File.size(); if (fileSize == 0) { Serial.println("文件为空"); SD_File.close(); return; } // 从文件末尾往前查找换行符 unsigned long pos = fileSize - 1; while (pos > 0) { SD_File.seek(pos); char c = SD_File.read(); // 找到换行符则停止,pos+1即为最后一行起始位置 if (c == '\n') { break; } pos--; } // 处理文件只有一行的情况 if (pos == 0) { SD_File.seek(0); } else { SD_File.seek(pos + 1); } // 读取最后一行内容并处理换行符 SD_File.readBytesUntil('\n', lastLine, sizeof(lastLine)-1); int len = strlen(lastLine); if (len > 0 && lastLine[len-1] == '\r') { lastLine[len-1] = '\0'; } SD_File.close(); Serial.println("文件最后一行内容:"); Serial.println(lastLine); } else { Serial.println("打开文件失败"); } } void loop() { }
注意事项
- 缓冲区(
lastLine、tempLine)的大小要根据实际文件的最大行长度调整,避免内容溢出。 - 不同系统换行符格式不同:Windows是
\r\n,Linux/Arduino是\n,代码中加入了去除\r的逻辑保证内容整洁。 - SD卡初始化阶段加入异常判断,避免卡未插入时程序崩溃。
内容的提问来源于stack exchange,提问作者arsha hadian
相关产品推荐
相关产品推荐

