Интересное поведение SD шилда

Andrey12
Andrey12 аватар
Offline
Зарегистрирован: 26.12.2014

Есть SD шилд в нем карта 4gb, подключен к меге. Но возникла проблема записи на SD карту, можент кто поможет?

Приведу именно момент который не работает, а не весь скетч, потому как проще для тестирования и понимания.
Вот первый скетч он работает отлично

#include <SPI.h>
#include <SD.h>

//File dataFile;
const int chipSelect = 53;

int fileSize;
char buf[4];
char fName[13];

void setup()
{
  // put your setup code here, to run once:
  Serial.begin(115200);
  Serial.print("Initializing SD card...");
  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    return;
  }
  Serial.println("card initialized.");
}

void loop()
{
  // make a string for assembling the data to log:

  for (int i = 0; i < 1000; i++)
  {
    // небольшая задержка
    delay(1000);

    String dataString = "";
    // это взял из примера SD библиотеки чтоб было что писать в файл
    for (int analogPin = 0; analogPin < 3; analogPin++) {
      int sensor = analogRead(analogPin);
      dataString += String(sensor);
      if (analogPin < 2) {
        dataString += ",";
      }
    }

    // формируем полный путь и имя файла
    // дело в том что я у себя при достиженни нужного размера создаю новый файл
    sprintf(buf, "%04d", i);
    String tempName = "DATA" + String(buf) + ".CSV";
    Serial.print("Check open - ");
    Serial.print(tempName);
    Serial.println(" - ");
    tempName.toCharArray(fName, 13);
    Serial.println(fName);

    // если так все работает
    File dataFile = SD.open(fName, FILE_WRITE);


    // далее из примера к SD библиотеки
    if (dataFile) {
      dataFile.println(dataString);
      dataFile.close();
      // print to the serial port too:
      Serial.println(dataString);
    }
    // if the file isn't open, pop up an error:
    else {
      Serial.println("error opening datalog.txt");
    }
  }
}

Внимание на 55 строку. Если тип переменной объявляем в loop() все ок, все работает. Строка 04 закоментирована.

Но мне необходимо чтобы переменная dataFile была видна в разных функциях. Поэтому делаю так, опять же внимание на строку 04 и 55, разница только в них.

#include <SPI.h>
#include <SD.h>

File dataFile;
const int chipSelect = 53;

int fileSize;
char buf[4];
char fName[13];

void setup()
{
  // put your setup code here, to run once:
  Serial.begin(115200);
  Serial.print("Initializing SD card...");
  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    return;
  }
  Serial.println("card initialized.");
}

void loop()
{
  // make a string for assembling the data to log:

  for (int i = 0; i < 1000; i++)
  {
    // небольшая задержка
    delay(1000);

    String dataString = "";
    // это взял из примера SD библиотеки чтоб было что писать в файл
    for (int analogPin = 0; analogPin < 3; analogPin++) {
      int sensor = analogRead(analogPin);
      dataString += String(sensor);
      if (analogPin < 2) {
        dataString += ",";
      }
    }

    // формируем полный путь и имя файла
    // дело в том что я у себя при достиженни нужного размера создаю новый файл
    sprintf(buf, "%04d", i);
    String tempName = "DATA" + String(buf) + ".CSV";
    Serial.print("Check open - ");
    Serial.print(tempName);
    Serial.println(" - ");
    tempName.toCharArray(fName, 13);
    Serial.println(fName);

    // если так все работает
    dataFile = SD.open(fName, FILE_WRITE);


    // далее из примера к SD библиотеки
    if (dataFile) {
      dataFile.println(dataString);
      dataFile.close();
      // print to the serial port too:
      Serial.println(dataString);
    }
    // if the file isn't open, pop up an error:
    else {
      Serial.println("error opening datalog.txt");
    }
  }
}

 

А в этом случае такая картина, получается ардуино перезагружается при попытке открыть файл.

Что делать, куда бежать, не пойму. Может кто сталкивался?

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

Мдааа. А вы интересовались размером памяти ардуино? Или считаете что она безразмерная и туда можно файло 4 гига прочитать?

Andrey12
Andrey12 аватар
Offline
Зарегистрирован: 26.12.2014

Puhlyaviy пишет:
Мдааа. А вы интересовались размером памяти ардуино? Или считаете что она безразмерная и туда можно файло 4 гига прочитать?

Конечно интересоваля. Просто флешки менее 4гиг не нашел. Но дело то не в этом, я не вывожу видеопоток в реальном времени на флешку с помощью МЕГИ :-) 
И стандартные примеры из библиотеки SD работают отлично. Размер и прочие параметры определяют корректно.

Задача сохранять параметры датчиков на флешку. Алгоритм такой.
1. Опрашиваются датчики, формируется строка для записи, если про память то строка не более 100 байт.
2. Ищем на SD последний файл, смотрим не превысил ли он размер, например 2кб
3. Если не превысил открываем его и пишем в него строку с данными датчикаов.
4. Если размер файла более 2кб то открываем новый, и пишем данные в него.

Так вот если я объявляю переменную типа File глобально, то при создании и последующем открытии на запись первого файла (DATA0001.CSV) и записи в него данных и последующем закрытии все хорошо, как только файл тсановится более 2кб я создаю новый файл (DATA0002.CSV) он создается, но при попытке записать в него данные МЕГА перегружается :-(

Если объявить переменную локально, например в loop() и все выполнять в пределах одной функции то все нормально. Но это мне немного не подходит так как всю работу с файлом придется писать в одной функции. 

То есть разница работы наблюдается если переменная типа File объявлена глобально (тогда не работает) или локально (тогда работает).

Просто если у кого есть возможность проверить работу скетчей и сказать результаты я был бы очень благодарен за помощь. Может дело в моих шилдах или SD карте. Так как если на другом комплекте (у меня к сожалению 1 только) все будет работать нормально значит надо что то думать с шилдами. Хотя очень странно.

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

С памятью нужно думать а не с шильдом... с ОПЕРАТИВКОЙ. Она нифига не резиновая.

Andrey12
Andrey12 аватар
Offline
Зарегистрирован: 26.12.2014

Puhlyaviy пишет:
С памятью нужно думать а не с шильдом... с ОПЕРАТИВКОЙ. Она нифига не резиновая.

Вот блин дурья башка, точно, память то разная берется если глобальная или локальная переменная :-) 

Спасиб за наводку, с первого раза не понял, посмотрел если объявить глобально, память действительно кушатеся нормально. Буду рыть сюда, еще раз СПАСИБО.

step962
Offline
Зарегистрирован: 23.05.2011

Andrey12 пишет:

Puhlyaviy пишет:
С памятью нужно думать а не с шильдом... с ОПЕРАТИВКОЙ. Она нифига не резиновая.

Вот блин дурья башка, точно, память то разная берется если глобальная или локальная переменная :-) 

Память берется одна и на же - RAM. Только глобальная переменная запихивается в нее по младшим адресам и навсегда (с точки зрения исполняемой программы, разумеется).

А локальная (не объявленная статической) - по старшим (там, где расположен стек, растущий вниз к области глобальных переменных) и лишь на время исполнения функции. Т.е., фактически, делится между функциями.

О "куче" умолчим...