2

SD カードにファイルのリストを作成しようとしていますが、これは 1 回で十分簡単に​​実行できますが、プログラムを複数回実行すると、リストが短くなるか、プログラムがファイルがまったくないと表示されます。

これをできるだけ簡単にするために、arduino SD ライブラリに付属の SD サンプルを使用し、セットアップ部分 (通常は 1 回実行される) をループ部分に入れています。これが私が持っているものです。

#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

終わり!

任意のキーを押してから入力して、リストを実行します

終わり!

任意のキーを押してから入力して、リストを実行します

終わり!

任意のキーを押してから入力して、リストを実行します

終わり!

任意のキーを押してから入力して、リストを実行します

/////////////////////////////////////////////// /////////////////////////////////

ご覧のとおり、どんどん短くなり、完全に停止します。

誰にも理由はありますか?

ポインターをいじって、ファイルを閉じて再度開いてみましたが、何も思いつきませんでした。

どんなアイデアでも大歓迎です。

4

2 に答える 2

3

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");
}

次に、ディレクトリ ウォークで開いているファイルを閉じます。

void printDirectory(File dir, int numTabs) {

  while(true) {
    File entry = dir.openNextFile();
    ...
    entry.close();
  }
  return;
}

最後に、loop() でブロックしないことを検討してください。loop() の外部で他のことが発生する可能性があり、キーを押すまでの待機時間に応じて、それらは無期限にブロックされます。より典型的なコード パターンは、ユーザー入力をブロックして待機するのではなく、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;
}
于 2013-06-07T06:53:18.450 に答える