Проблема с открытием нескольких текстовых файлов одновременно/по порядку с использованием <SD.h>

Я хочу регистрировать данные аналогового датчика, используя 3 контакта: A1, A2, A3. Мой проект требует непрерывного сопоставления данных, поэтому потребовалась защита SD-карты. Однако мне нужно записать входящие данные в 3 разных текстовых файла, и для этой цели я предположил, что одновременное открытие 3 файлов может быть или не быть возможным, как указано здесь (я новичок, поэтому не все смог понять, да и ресурсов мало :)

Итак, на данный момент я поработал над тем, чтобы открыть три файла по порядку. Вместо того, чтобы открывать их все одновременно, записывать данные в каждый файл и затем закрывать их, я выполнил все три задачи: 1) отдельные функции для всех трех файлов и вызов их в функции цикла(), 2) сохранение всего содержимого в самой функции цикла(). Результатом для метода-1 было то, что ни один файл не был создан, а для метода-2 был создан только первый файл, а остальные - нет. Вот код для обеих версий. Что я могу делать неправильно? Заранее спасибо!

Моя плата — Arduino Uno. Да, я отформатировал SD-карту в FAT32. Моя проводка на месте, мой код — единственная возможная проблема, которую я вижу.

Метод 1

#include <SD.h>
File Cu_volt;
File Gunmet_volt;
File Al_volt;
static float volt_Cu, volt_Gunmet, volt_Al;

void setup() {
  Serial.begin(9600);
  analogReference(INTERNAL);
  pinMode(A1, INPUT);
  pinMode(A2, INPUT);
  pinMode(A3, INPUT);

  //Инициализируем модуль SD-карты, контакт CS установлен на 4
  Serial.println("INITIALIZING SD CARD...");
  //проверяем наличие ошибок SD
  if ( !SD.begin(4)) {
    Serial.println("INITIALIZATION FAIL...");
    while (1);
    return;
  }
  Serial.println("INITIALIZATION DONE");
}

void loop() {
  // считываем входные данные аналогового медного электрода контакта 0:
  // Преобразуем аналоговое показание (от 0 до 1023) в напряжение (от 0 до VRef=INTERNAl)
 copperFile();
 gunmetalFile();
 aluminiumFile();
 delay(3000);

void copperFile() {
  Cu_volt = SD.open("Copper.txt", O_RDWR | O_APPEND);
  if (!Cu_volt) {
    Cu_volt = SD.open("Copper.txt", O_RDWR | O_CREAT);
    if (!Cu_volt) {
      Serial.println("Failed to open file at all");      
    }    
  }
  volt_Cu = analogRead(A1) * (1.1 / 1023.0);
  // распечатываем значение read(COPPER):
  Serial.print("Copper voltage=");
  Serial.println(volt_Cu);
  if (Cu_volt) {
    Cu_volt.println(volt_Cu);
    Cu_volt.close();
  }
}

void gunmetalFile() {
  Gunmet_volt = SD.open("Gun_metal.txt", O_RDWR | O_APPEND);
  if (!Gunmet_volt) {
    Gunmet_volt = SD.open("Gun_metal.txt", O_RDWR | O_CREAT);
    if (!Gunmet_volt) {
      Serial.println("Failed to open file at all");
    }
  }
  volt_Gunmet = analogRead(A2) * (1.1 / 1023.0);
  // распечатываем прочитанное значение(GUNMETAL):
  Serial.print("Gun metal voltage=");
  Serial.println(volt_Gunmet);
  if (Gunmet_volt) {
    Gunmet_volt.println(volt_Gunmet);
    Gunmet_volt.close();
  }
}

void aluminiumFile(){
  //открываем алюминиевый файл
  Al_volt = SD.open("Aluminium.txt", O_RDWR | O_APPEND);
  if (!Al_volt) {
    Al_volt = SD.open("Aluminium.txt", O_RDWR | O_CREAT);
    if (!Al_volt) {
      Serial.println("Failed to open file at all");
    }
  }
   volt_Al = analogRead(A3) * (1.1 / 1023.0);
  // распечатываем прочитанное значение(АЛЮМИНИЙ):
  Serial.print("Aluminium voltage=");
  Serial.println(volt_Al);
  if (Al_volt) {
    Al_volt.println(volt_Al);
    Al_volt.close();
  }
} 

Метод 2

#include <SD.h>
File Cu_volt;
File Gunmet_volt;
File Al_volt;
static float volt_Cu, volt_Gunmet, volt_Al;

void setup() {
  // инициализируем последовательную связь со скоростью 9600 бит в секунду:
  Serial.begin(9600);
  analogReference(INTERNAL);
  pinMode(A1, INPUT);
  pinMode(A2, INPUT);
  pinMode(A3, INPUT);
  //Инициализируем модуль SD-карты, контакт CS установлен на 4
  Serial.println("INITIALIZING SD CARD...");
  //проверяем наличие ошибок SD
  if ( !SD.begin(4)) {
    Serial.println("INITIALIZATION FAIL...");
    while (1);
    return;
  }
  Serial.println("INITIALIZATION DONE");
}

void loop() {
  // считываем входные данные аналогового медного электрода контакта 0:
  // Преобразуем аналоговое показание (от 0 до 1023) в напряжение (от 0 до VRef=INTERNAl)
  volt_Cu = analogRead(A1) * (1.1 / 1023.0);
  // распечатываем прочитанное значение(МЕДЬ):
  Serial.print("Copper voltage=");
  Serial.println(volt_Cu);
  //открываем медный файл
  Cu_volt = SD.open("Copper.txt", O_RDWR | O_APPEND);
  if (!Cu_volt) {
    Cu_volt = SD.open("Copper.txt", O_RDWR | O_CREAT);
    if (!Cu_volt) {
      Serial.println("Failed to open file at all");
    }
  }
  if (Cu_volt) {
    Cu_volt.println(volt_Cu);
    Cu_volt.close();
  }
  volt_Gunmet = analogRead(A2) * (1.1 / 1023.0);
  // распечатываем прочитанное значение(GUNMETAL):
  Serial.print("Gun metal voltage=");
  Serial.println(volt_Gunmet);
  //открываем медный файл
  Gunmet_volt = SD.open("Gun_metal.txt", O_RDWR | O_APPEND);
  if (!Gunmet_volt) {
    Gunmet_volt = SD.open("Gun_metal.txt", O_RDWR | O_CREAT);
    if (!Gunmet_volt) {
      Serial.println("Failed to open file at all");
    }
  }
  if (Gunmet_volt) {
    Gunmet_volt.println(volt_Gunmet);
    Gunmet_volt.close();
  }
  volt_Al = analogRead(A3) * (1.1 / 1023.0);
  // распечатываем прочитанное значение(АЛЮМИНИЙ):
  Serial.print("Aluminium voltage=");
  Serial.println(volt_Al);
  //открываем алюминиевый файл
  Al_volt = SD.open("Aluminium.txt", O_RDWR | O_APPEND);
  if (!Al_volt) {
    Al_volt = SD.open("Aluminium.txt", O_RDWR | O_CREAT);
    if (!Al_volt) {
      Serial.println("Failed to open file at all");
    }
  }
 if (Al_volt) {
    Al_volt.println(volt_Al);
    Al_volt.close();
  }
  delay(3000);
}

, 👍1

Обсуждение

@LookAlterno Я проверю. В любом случае использование альтернативы выглядит правдоподобной идеей :), @Abhinav


2 ответа


1

Существует несколько вариантов библиотеки SD: некоторые поддерживают несколько файлов, другие — нет.

Попробуйте вызвать .begin (и .end) в каждом цикле записи и добавить .flush — см. ниже.

Если это работает с вашей библиотекой, выньте (.begin/.end) из цикла и повторите попытку.

#define FILENAME "myfile.txt"

void writeToFile() {
    File f;
    // начинаем и заканчиваем каждую запись
    if (SD.begin(10, 11, 12, 13)) { // Я использую старую библиотеку, которая позволяет переназначать контакты
        f = SD.open(FILENAME, FILE_WRITE);  // Это добавит и создаст, если еще не существует
        if(f) {
            f.println("a string");  // Ваши операции записи
        }
        f.flush();          // Это гарантировало, что буфер записи действительно перейдет в файл
                            // даже если размер блока меньше (512b?)

        f.close();          
        }
    SD.end();                   // Делаем это после каждой операции записи
}
,

1

Для людей, испытывающих аналогичные проблемы с созданием нескольких файлов на SD-карте, это может быть проблема с памятью. Вам необходимо иметь определенный объем неиспользуемой динамической памяти (по моему опыту, около 300 байт свободного места) для записи на SD-карту - и больше, если вы записываете несколько файлов. Следование инструкциям на этой странице может помочь.

,