【问题标题】:how to recheck file in Arduino SD card如何重新检查 Arduino SD 卡中的文件
【发布时间】:2013-06-06 19:58:14
【问题描述】:

我正在尝试在我的 SD 卡上创建一个文件列表,这很容易做到一次,但是当我多次运行程序时,列表要么缩短,要么程序说根本没有文件。

为了使这尽可能简单,我使用了 arduino SD 库附带的 SD 示例,并将设置部分(通常会运行一次)放在循环部分中。 这就是我所拥有的。

#include <SD.h>

File root;

void setup()  
{
// Open serial communications and wait for port to open:
Serial.begin(9600);
 while (!Serial) {
  ; // wait for serial port to connect. Needed for Leonardo only
}


Serial.print("Initializing SD card...");
// On the Ethernet Shield, CS is pin 4. It's set as an output by default.
// Note that even if it's not used as the CS pin, the hardware SS pin 
// (10 on most Arduino boards, 53 on the Mega) must be left as an output 
// or the SD library functions will not work. 
  pinMode(10, OUTPUT);

if (!SD.begin(10)) {
  Serial.println("initialization failed!");
  return;
}
Serial.println("initialization done.");


}

void loop()
{
  Serial.println("hit any key then enter to run the list");
    while(!Serial.available())
    {;}
  Serial.read();
  root = SD.open("/");

  printDirectory(root, 0);

Serial.println("done!");

// nothing happens after setup finishes.
  }

 void printDirectory(File dir, int numTabs) {
    while(true) {

   File entry =  dir.openNextFile();
   if (! entry) {
     // no more files
     //Serial.println("**nomorefiles**");
     break;
     }
   for (uint8_t i=0; i<numTabs; i++) {
     Serial.print('\t');
      }
   Serial.print(entry.name());
   if (entry.isDirectory()) {
     Serial.println("/");
     printDirectory(entry, numTabs+1);
   } else {
     // files have sizes, directories do not
     Serial.print("\t\t");
     Serial.println(entry.size(), DEC);
   }
 }
}

但是运行后我得到了这个奇怪的输出

正在初始化 SD 卡...初始化完成。

按任意键然后回车运行列表

HFBVYRG.TXT 7

THBVFG.TXT 7

WAZXDSQ.TXT 7

QAZXSW.TXT 21

WSXZAQ.TXT 7

1478523.TXT 7

QWSDFRE.TXT 7

ZXCVBNM.TXT 7

MKOLIJY.TXT 7

完成!

按任意键然后回车运行列表

HFBVYRG.TXT 7

THBVFG.TXT 7

WAZXDSQ.TXT 7

QAZXSW.TXT 21

WSXZAQ.TXT 7

1478523.TXT 7

QWSDFRE.TXT 7

ZXCVBNM.TXT 7

MKOLIJY.TXT 7

完成!

按任意键然后回车运行列表

HFBVYRG.TXT 7

THBVFG.TXT 7

WAZXDSQ.TXT 7

QAZXSW.TXT 21

完成!

按任意键然后回车运行列表

完成!

按任意键然后回车运行列表

完成!

按任意键然后回车运行列表

完成!

按任意键然后回车运行列表

/////////////////////////////////////// /////////////////////////////////////////p>

你可以看到它越来越短,然后完全停止。

有人知道为什么吗?

我尝试过使用指针并关闭并重新打开文件,但我什么也没想到。

任何想法将不胜感激。

【问题讨论】:

    标签: pointers arduino sd-card


    【解决方案1】:

    不匹配的 open() 和 close() 不会带来任何好处。每次循环都打开根目录:

    root = SD.open("/");
    

    但从来没有

    root.close();
    

    首先,修复此错误,并在尝试打印列表之前检查打开根目录时是否成功:

    root = SD.open("/");
    if(root) {
      printDirectory(root, 0);
      Serial.println("done!");
      root.close();
    }
    else {
      Serial.println("failed to open directory");
    }
    

    二、关闭目录walk中打开的文件

    void printDirectory(File dir, int numTabs) {
    
      while(true) {
        File entry = dir.openNextFile();
        ...
        entry.close();
      }
      return;
    }
    

    最后,考虑不要在循环()中阻塞。其他事情可能发生在您的 loop() 之外,它们将被无限期地阻止,具体取决于您等待按键的时间。一个更典型的代码模式是在循环()中疯狂地旋转,而不是阻塞等待用户输入。例如:

    boolean bNeedPrompt = true;
    
    void loop() {
      // Show the prompt once, then mark as displayed so that text does not
      // continuously scroll on the screen
      if(bNeedPrompt) {
        Serial.println("hit any key then enter to run the list");
        bNeedPrompt = false;
      }
    
      if(Serial.available()) {
        Serial.read();
        // do action
        // set flag so that prompt will display again
        bNeedPrompt = true;
      }
    
      return;
    }
    

    【讨论】:

    • 我不能告诉你我有多开心哈哈哈!!!非常感谢,这几天一直困扰着我。我会好好看看你的代码,但我第一次在基本代码上做它工作得很好:) 最后一件事,但这只是为了一般知识你知道为什么它给出了两次列表然后只是搞砸了?如果你不知道我真的不介意再次感谢
    • 天哪!这也是解决我的问题的方法。谢谢!
    【解决方案2】:

    jdr5ca 的回答解决了您设置中的许多问题 - 如果不关闭文件,您将泄漏资源,这不会很好地结束。对于像 Arduino 这样的低内存设置来说尤其重要,它的原始芯片只有 2k RAM,因此在整个代码中都值得牢记。

    您剩下的问题的简短答案:它不会完全可预测,但内存不足可能是您的问题的原因。继续阅读以了解更多详情。

    我最近对 ​​SD 库有过一些类似的经历,但原因并不明显。我发现如果我系统上的可用内存低于大约 500 字节(总 RAM 的四分之一),那么 SD 库在尝试列出目录时就会开始表现得很奇怪。

    我看到了和你类似的东西,例如:

    1. 列出根目录下的条目并找到两个子目录
    2. 列出其中一个子目录中的条目,运行良好
    3. 列出根目录下的条目,现在我只找到一个子目录!我列出内容的那个已经消失了!
    4. 我仍然可以很好地列出子目录的内容,即。它还在!
    5. 重置 Arduino 并重新启动得到相同的结果,再次显示文件仍然存在于 SD 卡上

    我认为所有这一切都归结为 SD 库非常消耗内存(#include SD.h 立即使用了 500 个字节!),并且没有特别明显地处理低内存错误。

    所以,如果事情表现得很奇怪,那么:

    1. 检查您的内存使用情况(参见例如freeRam() 来自http://playground.arduino.cc/Code/AvailableMemory

    2. 尽可能减少内存使用量。大致顺序:

      • 删除不需要的库
      • 删除您不需要的任何硬编码字符串(例如,在调用 Serial.print() 时)
      • 对于硬编码字符串,您确实需要使它们尽可能短,并将它们存储在闪存中(例如Serial.print(F("String in flash"));)而不是 RAM
      • 目前您无法将格式字符串(例如 snprintf)粘贴到闪存中,因此请避免使用这些格式字符串,只需手动构建输出即可(这样比较耗时,但可以节省内存)
      • 确保您在任何地方都使用适当的变量类型(即适合您的目的的最小大小的类型) - 如果您有任何数组,则尤其重要,原因很明显!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-07-02
      • 2013-09-08
      • 2023-03-16
      • 2011-05-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多