Проблема с открытием нескольких текстовых файлов одновременно/по порядку с использованием <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);
}
@Abhinav, 👍1
Обсуждение2 ответа
Существует несколько вариантов библиотеки 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(); // Делаем это после каждой операции записи
}
Для людей, испытывающих аналогичные проблемы с созданием нескольких файлов на SD-карте, это может быть проблема с памятью. Вам необходимо иметь определенный объем неиспользуемой динамической памяти (по моему опыту, около 300 байт свободного места) для записи на SD-карту - и больше, если вы записываете несколько файлов. Следование инструкциям на этой странице может помочь.
- Сохранение файла .txt на SD-карту и чтение данных каждого содержимого в файл txt, а затем сохранение его в переменной
- DFPlayer для записи на SD-карту
- Попытка прочитать случайную строку с SD-карты
- Проблемы с чтением растровых изображений с SD-карты
- SD-карта не инициализируется
- Отправка значения с одного Arduino на другой
- Что означают эти контакты? Куда мне их подключить?
- Arduino непрерывно считывает значение АЦП с помощью прерывания
@LookAlterno Я проверю. В любом случае использование альтернативы выглядит правдоподобной идеей :), @Abhinav