SD.exists

Тема в разделе "Arduino & Shields", создана пользователем Arduiner001, 26 окт 2017.

  1. Arduiner001

    Arduiner001 Гик

    Всем привет! Пишу я под ESP32, возможно какое-то значение это имеет. Проблема в том, что SD.exists всегда выдаёт false. Вот код:
    Код (C++):
    #include <SPI.h>
    #include <mySD.h> //Библиотека SD для ESP32

    bool SD_Exists(String file){
      char cfn[file.length() + 1];
      file.toCharArray(cfn, sizeof(cfn));
      Serial.println(cfn);
      return SD.exists(cfn);
    }

    void setup() {
      Serial.begin(115200);
      SD.begin(5, 23, 19, 18);
    }

    void loop() {
      Serial.println(SD_Exists("OS/3X128/system") ? "Exists" : "NO!");
      delay(500);
    }
    Вот результат:
    На карте памяти папка есть, карта подключена к ESP. Подскажите пожалуйста, в чём проблема
     
  2. b707

    b707 Гуру

    Подозреваю, что у вас ошибка в пути к файлу. Попробуйте для начала считать текущий католог.
     
  3. Arduiner001

    Arduiner001 Гик

    Код (C++):
    #include <SPI.h>
    #include <mySD.h>

    bool SD_Exists(String file){
      char cfn[file.length() + 1];
      file.toCharArray(cfn, sizeof(cfn));
      Serial.println(cfn);
      return SD.exists(cfn);
    }

    void setup() {
      Serial.begin(115200);
      if(SD.begin(5, 23, 19, 18)){ //Контакты, к которым подключена карта
        Serial.println("SD.begin() OK");
      }
    }

    void loop() {
      Serial.println(SD_Exists("") ? "Exists" : "NO!");
      Serial.println(SD_Exists("/") ? "Exists" : "NO!");
      delay(500);
    }
    Выдаёт
     
  4. Arduiner001

    Arduiner001 Гик

    Или так
     

    Вложения:

    • esp.png
      esp.png
      Размер файла:
      13,2 КБ
      Просмотров:
      503
  5. Arduiner001

    Arduiner001 Гик

    Пришёл к выводу, что всё, кроме exists() работает. Нашёл код в исходниках:
    Код (C++):
    boolean walkPath(char *filepath, SdFile& parentDir,
             boolean (*callback)(SdFile& parentDir,
                         char *filePathComponent,
                         boolean isLastComponent,
                         void *object),
             void *object = NULL) {
      /*
       
         When given a file path (and parent directory--normally root),
         this function traverses the directories in the path and at each
         level calls the supplied callback function while also providing
         the supplied object for context if required.

           e.g. given the path '/foo/bar/baz'
                the callback would be called at the equivalent of
            '/foo', '/foo/bar' and '/foo/bar/baz'.

         The implementation swaps between two different directory/file
         handles as it traverses the directories and does not use recursion
         in an attempt to use memory efficiently.

         If a callback wishes to stop the directory traversal it should
         return false--in this case the function will stop the traversal,
         tidy up and return false.

         If a directory path doesn't exist at some point this function will
         also return false and not subsequently call the callback.

         If a directory path specified is complete, valid and the callback
         did not indicate the traversal should be interrupted then this
         function will return true.

       */



      SdFile subfile1;
      SdFile subfile2;

      char buffer[PATH_COMPONENT_BUFFER_LEN];

      unsigned int offset = 0;

      SdFile *p_parent;
      SdFile *p_child;

      SdFile *p_tmp_sdfile;
     
      p_child = &subfile1;
     
      p_parent = &parentDir;

      while (true) {

        boolean moreComponents = getNextPathComponent(filepath, &offset, buffer);

        boolean shouldContinue = callback((*p_parent), buffer, !moreComponents, object);

        if (!shouldContinue) {
          // TODO: Don't repeat this code?
          // If it's one we've created then we
          // don't need the parent handle anymore.
          if (p_parent != &parentDir) {
            (*p_parent).close();
          }
          return false;
        }
       
        if (!moreComponents) {
          break;
        }
       
        boolean exists = (*p_child).open(*p_parent, buffer, O_RDONLY);

        // If it's one we've created then we
        // don't need the parent handle anymore.
        if (p_parent != &parentDir) {
          (*p_parent).close();
        }
       
        // Handle case when it doesn't exist and we can't continue...
        if (exists) {
          // We alternate between two file handles as we go down
          // the path.
          if (p_parent == &parentDir) {
            p_parent = &subfile2;
          }

          p_tmp_sdfile = p_parent;
          p_parent = p_child;
          p_child = p_tmp_sdfile;
        } else {
          return false;
        }
      }
     
      if (p_parent != &parentDir) {
        (*p_parent).close(); // TODO: Return/ handle different?
      }

      return true;
    }
    Может быть супер-гуру-профессионалы найдут ошибку?
     
  6. Arduiner001

    Arduiner001 Гик

    Я победил эту систему, написав функцию:
    Код (C++):
    bool SD_Exists(String file){
      char cfn[file.length() + 1];
      file.toCharArray(cfn, sizeof(cfn));
      Serial.println(cfn);
      File f = SD.open(cfn, FILE_READ);
      return f.available() > 0;
    }
    Причём, я думал, что это не будет работать для директорий, однако сработало. Я не знаю почему.
     
  7. DIYMan

    DIYMan Guest

    Вы наплодили утечек памяти, как минимум. Вашу функцию надо переписать как минимум так:
    Код (C++):
    bool SD_Exists(const String& file)
    {
      Serial.println(file);
      File f = SD.open(file.c_str(), FILE_READ);

        if(f)
        {
            bool b = f.available();
            f.close();
            return b;
        }
    return false;
    }
    И вообще - ваша мания везде, где не надо, юзать toCharArray - плохая привычка: у класса String есть метод c_str(), который выдаёт константный указатель на внутренний буфер, и если не надо этот буфер менять (как в вашем примере) - то лучше юзать именно этот метод.

    З.Ы. И да, по теме: exists - у меня работает, как надо, версия IDE 1.6.7
     
  8. Arduiner001

    Arduiner001 Гик

    У вас работает на платформе Arduino? Если да, то у меня ESP32
     
  9. DIYMan

    DIYMan Guest

    Да, на Arduino, за ESP32 не скажу, возможно, косяк библиотеки?