首页 文章

Arduino Ethernet-SD屏蔽,列出SD卡上所有文件名现有文件

提问于
浏览
0

我有:Arduino MEGA 2560;以太网SD屏蔽http://www.amazon.com/dp/B0022TWQ22/?tag=stackoverfl08-20; SD卡2GB FAT .

SD包含400个文件,名称为00000000; 0000001; 0000002; ... 00000098; 0000099; 0000100; ... 00000398; 00000399 .

我需要构造String var,它将包含由“;”分隔的所有文件名像这样:sdata =“0000001; 0000002; 0000003 ... 00000398; 00000399;”;

码:

#include <SdFat.h>
#include <SPI.h>


const uint16_t chipSelect = SS;
char cnamefile[9];
String sdata="";
SdFat sd;
SdFile file;

void setup() {


  Serial.begin(9600);
  Serial.println("hi");
  sdata="";
  if (!sd.begin(chipSelect, SPI_HALF_SPEED)) sd.initErrorHalt();
    Serial.println("List files");
    while (file.openNext(sd.vwd(), O_READ)) {
      file.getFilename(cnamefile);
      file.close();
      sdata = sdata + String(cnamefile) + ";";

    }
  Serial.print(sdata);
}

void loop() { 
}

听COM端口我看到:

hi
List files
00000005;00000006;00000007;00000008;00000009;00000010;00000011;00000012;00000013;00000014;00000015;00000016;00000017;00000018;00000019;00000020;00000021;00000022;00000023;00000024;00000025;00000026;00000027;00000028;00000029;00000030;00000031;00000032;00000033;00000034;00000035;00000036;00000037;00000038;00000039;00000040;00000041;00000042;00000043;00000044;00000045;00000046;00000047;00000048;00000049;00000050;00000051;00000052;00000053;00000054;00000055;00000056;00000057;00000058;00000059;00000060;00000061;00000062;00000063;00000064;00000065;00000066;00000067;00000068;00000069;00000070;00000071;00000072;00000073;00000074;00000075;00000076;00000077;00000078;

如何解决这个问题并将所有文件名放在一个变量中?

信息:400名和400“;”它的3600字节 . 当我尝试读取任何文件并将其所有内容(超过3600字节)放入“String sdata”时,它正常工作 . 仅限列表问题 . 请帮我解决这个问题 .

1 回答

  • 1

    这似乎是您的程序失败的正确位置 . 这条无辜的线是你的问题:

    sdata = sdata + String(cnamefile) + ";";
    

    像这样的字符串连接将在短时间内使用sdata的2倍内存 . 这是您应该如何查看该行中的操作顺序

    // compiler has done this for you:
    String temp1234 = sdata + String();
    
    // note that at this moment, memory usage is now 2x sdata
    
    String temp1235 = temp1234 + ";";
    
    // now you can have 3x the memory used
    
    // assignment to variable
    sdata = temp1235;
    
    // now can delete temporary variable
    // compiler will do this
    //temp1234.delete()
    //temp1235.delete()
    

    您正在尝试创建最大3k字节的字符串,但总RAM只有8k,因此无法执行上述操作 .

    这表明了有关Strings的几点意见 . 上面的连接在一行上,不一定比这两行更好:

    sdata = sdata + String(cnamefile);
    sdata = sdata  + ";";
    

    在第二种形式中,确保中间结果只有一个临时变量 .

    这导致了下一个提示 . 你应该在想我将如何逃避临时变量 . 这就是为什么我们有=运算符 . 你最好的机会是这样连接:

    sdata += String(cnamefile);
    sdata += ";";
    

    如果String类上有=运算符,编译器将使用它 . 该运算符可能能够使用更有效的内存连接方式 . 例如,如果String预先分配了一些额外的内存,那么它可以将新字符放入现有缓冲区 .

    通常,这是关于约束内存空间中字符串的一种很好的学习方法,因为您必须了解在大型CPU环境中经常被忽略的一些编译器内部和操作员详细信息 .

    鉴于您建议的大小,如果您更改为预构建String缓冲区并使用文件名填充它的方法,您可能只能适应RAM . 换句话说:不要在微控制器上使用String .

相关问题