Чтение массива с sd карты

Тема в разделе "Arduino & Shields", создана пользователем vvr, 16 май 2014.

  1. vvr

    vvr Инженерище

    Решил создать отдельную тему. Благодаря помощи форумчан с записью-чтением переменной с sd карты разобрался. Теперь нужно освоить запись -чтение массива.
    Записываю показания двух потенциометров
    Код (Text):
     String dataString = String(val) + "  ,  " + String(val1);
    File dataFile = SD.open("log.txt", FILE_WRITE);
        if (dataFile)
        {
          dataFile.println(dataString);
          dataFile.close();
          Serial.println(dataString);
        }
    Читаю с первого байта
    Код (Text):
     File dataFile = SD.open("log.txt", FILE_READ);
      if (dataFile)
      {
        Serial.println("log.txt:");
        while (dataFile.available())
        {
          Serial.write(dataFile.read());
        }
        dataFile.close();
      }
    Всё нормально, в сериале пишет то, что записали.
    По аналогии с предыдущей темой читаю с последнего файла
    Код (Text):
    File dataFile = SD.open("log.txt", FILE_READ);
      unsigned long i;
      if (dataFile)
      {
        Serial.println("log.txt:");
        i = dataFile.size() - 1;
        while(i>0)
        {
          dataFile.seek(i--);
          Serial.write(dataFile.read());
        }
        dataFile.close();
      }
    В сериале пишет с последнего файла , но только строка в обратной последовательности.
    [​IMG]
    Как в этом случае развернуть строку?
    И сразу второй вопрос - как извлекать переменную ?
     
  2. Mitrandir

    Mitrandir Гуру

    Зачем это извращение с хранением данных в строках. Храните в двоичном виде. меньше геморроя.
     
  3. vvr

    vvr Инженерище

    Как это, я с этим не сталкивался. Почитаю конечно. Если можно ссылку на пример.
     
  4. Mitrandir

    Mitrandir Гуру

    я сегодня добрый) напишу сейчас пример
     
  5. Mitrandir

    Mitrandir Гуру

    Как-то так, надеюсь не ошибся. проверить не могу, нет карты

    Код (Text):
    #include <SD.h>


    //Пишет пару значений в конец фаила
    void dumpToFile (File* f, byte v1, byte v2)
    {
      //отмотаемся а конец фаила
      uint32_t fsize = f->size();
      f->seek(fsize);
      // напишем 2 байта
      f->write(v1);
      f->write(v2);
    }

    //читает сдедующуюю пару значений

    bool readNextPair(File* f, byte* v1,byte* v2)
    {
      int res; // буффер
      if((res = f->read())!= -1) // читаем в буффер
      {
        *v1 = (byte)res; // нам удалось, записываем буффер по первому адресу
      }
      else
      {
        return false;  // что-то пошло не так, выходим
      }
      //аналогично вторую запись
      if((res = f->read())!= -1)
      {
        *v2 = (byte)res;
      }
      else
      {
          return false;
      }
      return true;
    }

    //читает предыдущую запись в фаиле
    bool readPrevPair(File* f, byte* v1, byte*v2)
    {
      // проверим, есть ли предыдущая пара значений
      uint32_t pos = f->position();
      if(pos <2) return false;
      //сдвигаемся на два байта
      pos -= 2;
      f->seek(pos);
      //читаем два байта вперед используя гоотвую функцию
      if(!readNextPair(f,v1,v2))
      {
        f->seek(f->size()); //отмотаемся в конец фаила
        return false;// не смогли прочитать
      }
      //функция чтения отмотала указатель позиции на два байта вперед. вернем наместо
      f->seek(pos);
      return false;
       
    }
    void dumpToSerial(byte b1,byte b2)
    {
      Serial.print("b1=");
      Serial.print(b1);
      Serial.print("\tb2=");
      Serial.print(b2");
      Serial.println();
    }

    //Пример использования
    void setup(){
    //инициализацию пропущу


    File f = SD.open("log.dat",FILE_WRITE);
    //Запишем 5 пар байт для примера
    dumpToFile(&f,1,2);
    dumpToFile(&f,100,250);
    dumpToFile(&f,41,12);
    dumpToFile(&f,10,2);
    dumpToFile(&f,13,20);

    //Читаем вперед
    byte v1,v2;
    //отмотаемся назад
    f.seek(0);
    readNextPair(&f,&v1,&v2);
    dumpToSerial(v1,v2);
    readNextPair(&f,&v1,&v2);
    dumpToSerial(v1,v2);
    readNextPair(&f,&v1,&v2);
    dumpToSerial(v1,v2);
    readNextPair(&f,&v1,&v2);
    dumpToSerial(v1,v2);
    readNextPair(&f,&v1,&v2);
    dumpToSerial(v1,v2);

    //Написав 5 пар в сериал, мы переместили указатель в конец, мотаться никуда не надо
    //читаем назад
    readPrevPair(&f,&v1,&v2);
    dumpToSerial(v1,v2);
    readPrevPair(&f,&v1,&v2);
    dumpToSerial(v1,v2);
    readPrevPair(&f,&v1,&v2);
    dumpToSerial(v1,v2);
    readPrevPair(&f,&v1,&v2);
    dumpToSerial(v1,v2);
    readPrevPair(&f,&v1,&v2);
    dumpToSerial(v1,v2);

    f.close();


    }
    void loop(){}
     
    vvr нравится это.
  6. Megakoteyka

    Megakoteyka Оракул Модератор

    Код (Text):
    readPrevPair(&f,&v1,&v2);
    dumpToSerial(v1,v2);
    readPrevPair(&f,&v1,&v2);
    dumpToSerial(v1,v2);
    readPrevPair(&f,&v1,&v2);
    dumpToSerial(v1,v2);
    readPrevPair(&f,&v1,&v2);
    dumpToSerial(v1,v2);
    readPrevPair(&f,&v1,&v2);
    dumpToSerial(v1,v2);
    А циклы нам на что? ;)
    Код (Text):
    for(int i = 0; i < 5; i++)
    {
      readPrevPair(&f,&v1,&v2);
      dumpToSerial(v1,v2);
    }
     
    vvr нравится это.
  7. Mitrandir

    Mitrandir Гуру

    лень)
     
  8. vvr

    vvr Инженерище

    Ругается
    at java.util.regex.Pattern$GroupHead.match(Pattern.java:4168)
    at java.util.regex.Pattern$Loop.match(Pattern.java:4295)
    at java.util.regex.Pattern$GroupTail.match(Pattern.java:4227)
    at java.util.regex.Pattern$BranchConn.match(Pattern.java:4078)
     
  9. Mitrandir

    Mitrandir Гуру

    убери все комментарии на русском
    ему русский не по душе
     
  10. Mitrandir

    Mitrandir Гуру

    тут я случайно кавычку написал, торже убрать

    а может из-за кавычки таким образом ругается, с неё начни
     
  11. vvr

    vvr Инженерище

    Убрал кавычки - скомпилировался код. При записи пишет в сериал от 0 до 63. Читать не хочет.
     
  12. vvr

    vvr Инженерище

    Код (Text):
    {
        File f = SD.open("log.dat",FILE_READ);
        Serial.println("log.txt:");
        f.seek(0);
        readNextPair(&f, &val, &val1);
        dumpToSerial(val, val1);
        f.close();
      }

     
      {
        File f = SD.open("log.dat",FILE_READ);
        Serial.println("log.txt:");
        readPrevPair(&f, &val, &val1);
        dumpToSerial(val, val1);
        f.close();
      }
    Читаю в loop() . В обеих случаях показывает последние записанные значения. Пытаюсь ввести цикл for или while - сразу тормоз
     
  13. Mitrandir

    Mitrandir Гуру

    Чтобы читать назад надо сиком в конец встать
     
  14. vvr

    vvr Инженерище

    Так и вперёд читает только последнее значение. A как перевести теперь из двоичного вида в int?
     
  15. Megakoteyka

    Megakoteyka Оракул Модератор

    Что Вы подразумеваете под двоичным видом?
    Если пишите и читаете байтами, а не текстом, то ничего переводить не нужно.
     
  16. Mitrandir

    Mitrandir Гуру

    как это не нужно?
    ну прогчитал два байта, надо еще и в int склеить
     
  17. Megakoteyka

    Megakoteyka Оракул Модератор

    Просто переводить в int и склеивать слово из старшего и младшего байта - разные вещи.
    Вопрос сформулирован не очень корректно.
    Клеить просто: int x = (hiByte << 8) | lowByte;
     
  18. vvr

    vvr Инженерище

    Записываю две переменные на карту как посоветовал Mitrandir. В сериале пишет значения от 0 до 63.
    Читаю что с первого байта, что с последнего - в сериале пишет log.txt и только два последних записанных значения, и опять от 0 до 63.
    Моих знаний пока не хватает понять, в этом примере что должно записывать вместо числа например 255.
    И получается что читается только последняя записанная строка.
    После того, как помогут разобраться (надеюсь) с этим, возникнет второй вопрос, как обе прочитанные переменные перевести в int. Как я понимаю, сейчас не пишутся младший и старший байты
     
  19. Megakoteyka

    Megakoteyka Оракул Модератор

    int x = (hiByte << 8) | lowByte;
     
  20. vvr

    vvr Инженерище

    //Пишет пару значений в конец файла
    void dumpToFile (File* f, byte v1, byte v2)
    {
    //отмотаемся а конец файла
    uint32_t fsize = f->size();
    f->seek(fsize);
    // напишем 2 байта
    f->write(v1);
    f->write(v2);
    }

    Что здесь записывается?
    v1 и v2 - данные с потенциометра (0-255).
    Пишет 0 - 63