Проблема со считыванием с SD карты

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

  1. fixedip

    fixedip Гик

    Всем добрый день
    Есть у меня одна проблема со считыванием с SD карты имен файлов, считывается только 5 раз потом перестает считывать.
    Код (Text):

    void SDReadDir () {// функция чтения кол-ва и имён рецептов
      for (byte i = 0; i < 50; i++ ) {
        NameDir[i] = "";
      }

      SumDir = 0;//кол-во рецептов
      ErroSD ();
      File root = SD.open("/BEER");

      while (true) {
        File entry =  root.openNextFile();
        if (! entry || SumDir == 50) {
          // no more files
          //root1.rewindDirectory();
          break;
        }

        NameDir[SumDir] = entry.name();// записываем в массив имя файла
        SumDir ++;
        entry.close();


      }

    }
     
     
  2. rkit

    rkit Гуру

    Это кто вас так учил работать со строками? Быстро читать учебник.

    А освобождать память кто будет?

    А с чего вы решили, что тут строка выделяется в куче?
     
  3. fixedip

    fixedip Гик

    Спасибо за ответ.....точно сказать не могу откуда это взято....просто модифицирован под мои нужды....
     
    Последнее редактирование: 21 сен 2017
  4. fixedip

    fixedip Гик

    Опыта работы со строками ..минимален....направьте на путь истинный, что за учебник ?
     
  5. DIYMan

    DIYMan Guest

    Любой учебник по С/С++, вбить волшебные слова в гугле, читать, смотреть обучалки на ютюбе - и всё придёт ;)
     
  6. fixedip

    fixedip Гик

    Спасибо.
    Я понял в чем у меня проблема : переполняется память локальных переменных.
     
  7. fixedip

    fixedip Гик

    Поправьте меня если я ошибаюсь в своих размышлениях.
    Массив String (хотя он объявлен как глобальный) создается в стеке и при его заполнении или повторной записи, он не перезаписывается, а продолжает расти пока не заполнит стек. после чего наезжает на кучу и перезаписывает данные в ней?
     
  8. rkit

    rkit Гуру

    Библиотека SD вообще не работает со String
     
  9. DIYMan

    DIYMan Guest

    Где бы ни был объявлен объект типа String - память под внутренний буфер выделяется на куче. При этом эта память будет занятой до тех пор, пока живёт объект типа String: если он объявлен локально - то до выхода из области видимости, если глобально - всю жисть.

    При этом, однажды выделенный буфер за время жизни объекта может только УВЕЛИЧИВАТЬСЯ, т.е.:

    Код (C++):
    String s; // объект класса

    s = "123"; // на куче занято 4 байта
    s = "1"; // на куче занято 4 байта
    s = "12345"; // на куче занято 6 байт
    s = ""; // на куче занято 6 байт
    Исходники класса String есть в поставке Arduino IDE, можете ознакомиться ;)
     
  10. DIYMan

    DIYMan Guest

    По коду - не вижу почему-то root.close(), как минимум.
     
  11. fixedip

    fixedip Гик

    root.close(); увеличило кол-во отражений на результат то же
     
  12. DIYMan

    DIYMan Guest

    Приведите, пожалуйста, ПОЛНЫЙ код скетча.
     
  13. fixedip

    fixedip Гик

    Весь скеч очень большой 182 К
    В этой функции считываем кол-во SumDir и имена файлов из заданной папки.
    После чего друга функция выводит на экран эти данные, при обновлении экрана снова считываем данные с карты памяти (так-как они могли изменится).
     
  14. DIYMan

    DIYMan Guest

    Ок. Как объявлена NameDir?
     
  15. fixedip

    fixedip Гик

    Код (Text):
    String NameDir[30] = "";//буфер хренеия имен рецептов считанных с SD карты
     
  16. fixedip

    fixedip Гик

    Функция вывода на экран
    Код (Text):

    void ReceptScreen (byte col1, byte col2) {// Функция отображения рецептов с карты памяти col1 - первая колонка (кратна 5),col2 - вторая колонка (кратна 5)
      myGLCD.setFont(BigRusFont);

      myGLCD.setColor(139, 69, 19);
      myGLCD.setBackColor(139, 69, 19);
      myGLCD.fillRoundRect(5, 65, 475, 225);
      myGLCD.setColor(VGA_WHITE);
      for (byte i = 0 ; i < 5; i++) {
        myGLCD.printNumI(i, 5, 75 + (i * 32));
        {
          myGLCD.print(NameDir[i + col1], 37, 75 + (i * 32));
        }
      }
      for (byte i = 0 ; i < 5; i++) {
        myGLCD.printNumI(i + 5, 250, 75 + (i * 32));
        {
          myGLCD.print(NameDir[i + col2], 282, 75 + (i * 32));
        }
      }
     
     
  17. DIYMan

    DIYMan Guest

    И далее:
    Код (C++):
    for (byte i = 0; i < 50; i++ ) {
        NameDir[i] = "";
      }
    Ничего странного не замечаете, не? С кол-вом элементов массива всё норм? У вас их 30, а в цикле вы тыркаетесь куда-то в Урюпинск, т.к. условие остановки цикла - i < 50. У вас 20 итераций убивают к хренам память.
     
  18. fixedip

    fixedip Гик

    Извиняюсь за не точность, это я уменьшил максимальное кол-во считанных имён. .. позже, так что в первой функции их то же 20
     
  19. DIYMan

    DIYMan Guest

    Не, так мы каши не сварим - у вас непонятно что непонятно где: я вам указываю на ошибку, оказывается, её нет. Либо вы приводите полный АКТУАЛЬНЫЙ код касательно работы с SD (и ОБЪЯВЛЕНИЯ переменных, и работа с ними), либо - мы никуда не продвинемся.
     
  20. fixedip

    fixedip Гик

    SDReadDir-->вывод первой страницы на экран--->кол-во страниц--- обработка кнопок и потом все с начала по выходу кнопки Esc
    Код (C++):
    byte SumDir = 0;//для хранения кол-во рецептов
    Код (C++):
    String NameDir[30] = "";//буфер хренеия имен рецептов считанных с SD карты
    Код (C++):
    void SDReadDir () {// функция чтения кол-ва и имен рецептов

      char *cls = 0;
      for (byte i = 0; i < 30; i++ ) {
        {
          NameDir[i] = *cls;
        }
      }

      SumDir = 0;
      ErroSD ();
      File root = SD.open("/BEER");

      while (true) {
        File entry = root.openNextFile();
        //File entry =  SD.open("/BEER").openNextFile();
        if (! entry || SumDir == 30) {
          // no more files
          //root1.rewindDirectory();
               entry.close();
                root.close();
          break;
        }

        NameDir[SumDir] = entry.name();
        SumDir ++;
        entry.close();
      }

    }
    Код (C++):
    void ReceptScreen (byte col1, byte col2) {// Функция отображения рецептов с карты памяти col1 - первая колонка (кратна 5),col2 - вторая колонка (кратна 5)
      myGLCD.setFont(BigRusFont);

      myGLCD.setColor(139, 69, 19);
      myGLCD.setBackColor(139, 69, 19);
      myGLCD.fillRoundRect(5, 65, 475, 225);
      myGLCD.setColor(VGA_WHITE);
      for (byte i = 0 ; i < 5; i++) {
        myGLCD.printNumI(i, 5, 75 + (i * 32));
        {
          myGLCD.print(NameDir[i + col1], 37, 75 + (i * 32));
        }
      }
      for (byte i = 0 ; i < 5; i++) {
        myGLCD.printNumI(i + 5, 250, 75 + (i * 32));
        {
          myGLCD.print(NameDir[i + col2], 282, 75 + (i * 32));
        }
      }
    }
    Код (C++):
    void Touch5 () { // обработка кнопок меню sd карты
      ColchStr ();
      byte screenstep = 1;
      myGLCD.setColor(VGA_WHITE);
      myGLCD.setBackColor(139, 69, 19);
      myGLCD.printNumI(screenstep, 216, 226);
      myGLCD.printNumI(ScreenDir, 248, 226);
      myGLCD.print("/", 232, 226);
      while (true)
      {
        MainMenu (pauseBeerScreen1);
        NameBeer = "/BEER/";
        char customKey = customKeypad.getKey();

        if (customKey) {

          if (customKey == 'E') {
            pos = 4;
            Screen0 ();// переход в следущие меню
          }
          if (customKey == 'R') {
            screenstep++;
            if (screenstep > ScreenDir) screenstep = 1;
          }
          if (customKey == 'L') {
            screenstep--;
            if (screenstep < 1) screenstep = ScreenDir;
          }
          myGLCD.setColor(VGA_WHITE);
          myGLCD.setBackColor(139, 69, 19);
          myGLCD.printNumI(screenstep, 216, 226);
          myGLCD.printNumI(ScreenDir, 248, 226);
          myGLCD.print("/", 232, 226);
          if (customKey == '0') {
            switch (screenstep) {
              case 1:
                NameBeer += NameDir[0];
                DonwdAndDel ();
              case 2:
                NameBeer += NameDir[10];
                DonwdAndDel ();
              case 3:
                NameBeer += NameDir[20];
                DonwdAndDel ();
              case 4:
                NameBeer += NameDir[30];
                DonwdAndDel ();
              case 5:
                NameBeer += NameDir[40];
                DonwdAndDel ();
            }
          }
          if (customKey == '1') {
            switch (screenstep) {
              case 1:
                NameBeer += NameDir[1];
                DonwdAndDel ();
              case 2:
                NameBeer += NameDir[11];
                DonwdAndDel ();
              case 3:
                NameBeer += NameDir[21];
                DonwdAndDel ();
              case 4:
                NameBeer += NameDir[31];
                DonwdAndDel ();
              case 5:
                NameBeer += NameDir[41];
                DonwdAndDel ();
            }
          }
          if (customKey == '2') {
            switch (screenstep) {
              case 1:
                NameBeer += NameDir[2];
                DonwdAndDel ();
              case 2:
                NameBeer += NameDir[12];
                DonwdAndDel ();
              case 3:
                NameBeer += NameDir[22];
                DonwdAndDel ();
              case 4:
                NameBeer += NameDir[32];
                DonwdAndDel ();
              case 5:
                NameBeer += NameDir[42];
                DonwdAndDel ();
            }
          }
          if (customKey == '3') {
            switch (screenstep) {
              case 1:
                NameBeer += NameDir[3];
                DonwdAndDel ();
              case 2:
                NameBeer += NameDir[13];
                DonwdAndDel ();
              case 3:
                NameBeer += NameDir[23];
                DonwdAndDel ();
              case 4:
                NameBeer += NameDir[33];
                DonwdAndDel ();
              case 5:
                NameBeer += NameDir[43];
                DonwdAndDel ();
            }
          }
          if (customKey == '4') {
            switch (screenstep) {
              case 1:
                NameBeer += NameDir[4];
                DonwdAndDel ();
              case 2:
                NameBeer += NameDir[14];
                DonwdAndDel ();
              case 3:
                NameBeer += NameDir[24];
                DonwdAndDel ();
              case 4:
                NameBeer += NameDir[34];
                DonwdAndDel ();
              case 5:
                NameBeer += NameDir[44];
                DonwdAndDel ();
            }
          }
          if (customKey == '5') {
            switch (screenstep) {
              case 1:
                NameBeer += NameDir[5];
                DonwdAndDel ();
              case 2:
                NameBeer += NameDir[15];
                DonwdAndDel ();
              case 3:
                NameBeer += NameDir[25];
                DonwdAndDel ();
              case 4:
                NameBeer += NameDir[35];
                DonwdAndDel ();
              case 5:
                NameBeer += NameDir[45];
                DonwdAndDel ();
            }
          }
          if (customKey == '6') {
            switch (screenstep) {
              case 1:
                NameBeer += NameDir[6];
                DonwdAndDel ();
              case 2:
                NameBeer += NameDir[16];
                DonwdAndDel ();
              case 3:
                NameBeer += NameDir[26];
                DonwdAndDel ();
              case 4:
                NameBeer += NameDir[36];
                DonwdAndDel ();
              case 5:
                NameBeer += NameDir[46];
                DonwdAndDel ();
            }
          }
          if (customKey == '7') {
            switch (screenstep) {
              case 1:
                NameBeer += NameDir[7];
                DonwdAndDel ();
              case 2:
                NameBeer += NameDir[17];
                DonwdAndDel ();
              case 3:
                NameBeer += NameDir[27];
                DonwdAndDel ();
              case 4:
                NameBeer += NameDir[37];
                DonwdAndDel ();
              case 5:
                NameBeer += NameDir[47];
                DonwdAndDel ();
            }
          }
          if (customKey == '8') {
            switch (screenstep) {
              case 1:
                NameBeer += NameDir[8];
                DonwdAndDel ();
              case 2:
                NameBeer += NameDir[18];
                DonwdAndDel ();
              case 3:
                NameBeer += NameDir[28];
                DonwdAndDel ();
              case 4:
                NameBeer += NameDir[38];
                DonwdAndDel ();
              case 5:
                NameBeer += NameDir[48];
                DonwdAndDel ();
            }
          }
          if (customKey == '9') {
            switch (screenstep) {
              case 1:
                NameBeer += NameDir[9];
                DonwdAndDel ();
              case 2:
                NameBeer += NameDir[19];
                DonwdAndDel ();
              case 3:
                NameBeer += NameDir[29];
                DonwdAndDel ();
              case 4:
                NameBeer += NameDir[39];
                DonwdAndDel ();
              case 5:
                NameBeer += NameDir[49];
                DonwdAndDel ();
            }
          }
          switch (screenstep) {
            case 1:
              ReceptScreen (0, 5);
              break;
            case 2:
              ReceptScreen (10, 15);
              break;
            case 3:
              ReceptScreen (20, 25);
              break;
            case 4:
              ReceptScreen (30, 35);
              break;
            case 5:
              ReceptScreen (40, 45);
              break;
            case 6:
              ReceptScreen (50, 55);
              break;
          }
        }
      }
    }
    Код (C++):
    void ColchStr () { // функция расчета кол-ва страниц рецептов
      //SDReadDir ();
      if (SumDir < 10)ScreenDir = 1;
      if (SumDir > 10)ScreenDir = 2;
      if (SumDir > 20)ScreenDir = 3;
      if (SumDir > 30)ScreenDir = 4;
      if (SumDir > 40)ScreenDir = 5;
      if (SumDir > 50)ScreenDir = 6;
    }
    Код (C++):
    void DonwdAndDel () {//функция изменения, загрузки, удаления  рецепта
      myGLCD.setColor(139, 69, 19);
      myGLCD.setBackColor(139, 69, 19);
      myGLCD.fillRoundRect(5, 65, 475, 241);
      myGLCD.setColor(VGA_WHITE);
      myGLCD.print(NameBeer, CENTER, 100);
      myGLCD.print("F1-""\x86\x85""MEH""\x86""T""\x92", 30, 140);
      myGLCD.print("F2-""\x8A\x82""A""\x88\x86""T""\x92", 260, 140);
      myGLCD.print("*-""\x85""A""\x81""P""\x8A\x85\x86""T""\x92", 260, 180);
      myGLCD.print("#-""\x89""POCMOTPET""\x92", 30, 180);
      myGLCD.setBackColor(VGA_WHITE);
      myGLCD.setColor(VGA_BLACK);
      myGLCD.print("                                                                                                                         ", CENTER, 300);
      myGLCD.print("Esc - OTMEHA", CENTER, 300);
      while (true) {
        char customKey = customKeypad.getKey();
        if (customKey) {
          if (customKey == 'Z') {
            SD.remove(NameBeer);
            SDReadDir ();
            Screen5 ();
          }
          if (customKey == 'P') {
       
            Redakt = false;
            BeerStep = 1;
            SDReadBeer ();
          }
          if (customKey == '*') {
            Redakt = true;
            SDReadBeer ();
          }
          if (customKey == 'E') {
            Redakt = true;
            Screen5 ();
          }
          if (customKey == '#') {
            Redakt = false;
            SDReadBeer ();
          }
        }
      }

    }
     
     
    Последнее редактирование: 26 сен 2017