SD - карта создает "лишний" файл?
Итак, возможно, я слишком устал, чтобы увидеть очевидную проблему здесь, но мой сценарий SD-карты вызывает создание "пустого" файла, а затем вторичного файла, который будет правильно создан.
Я пытаюсь хранить журналы данных, и я не хочу перезаписывать старые журналы, я просто хочу "переместить" их в конец очереди. Итак, я начинаю с шести файлов на SD-карте:
DATA.TXT
ДАННЫЕ~1.TXT
ДАННЫЕ~2.TXT
ДАННЫЕ~3.TXT
ДАННЫЕ~4.TXT
ДАННЫЕ~5.TXT
Все пишет в DATA.TXT
, и ДАННЫЕ~1.TXT
через ДАННЫЕ~5.TXT
это "старые" журналы, от самых старых до самых новых. Это означает, что в следующий раз, когда я загружаю Arduino, мне нужно содержимое DATA.TXT
для чтения в новый файл под названием DATA~6.TXT
, Я хочу старый DATA.TXT
для удаления, и я хочу новый DATA.TXT
чтобы быть созданным для остальной части программы. Это должно выглядеть так:
DATA.TXT <=== Новый, пустой файл, загрунтованный для регистрации новых данных
ДАННЫЕ~1.TXT
ДАННЫЕ~2.TXT
ДАННЫЕ~3.TXT
ДАННЫЕ~4.TXT
ДАННЫЕ~5.TXT
ДАННЫЕ~6.TXT <=== "Старый" DATA.TXT
На самом деле он создает два файла: вместо ДАННЫХ~6.TXT
удерживая содержимое, оно должно быть пустым-и файл называется DATA~7.TXT
создается с содержанием "старого" DATA.TXT
. После этого он пишет в "новую" DATA.TXT
как и должно. Что-то теряется (или добавляется) при сдвиге данных, почему-то выглядит так:
DATA.TXT <=== Новый, пустой файл, загрунтованный для регистрации новых данных
ДАННЫЕ~1.TXT
ДАННЫЕ~2.TXT
ДАННЫЕ~3.TXT
ДАННЫЕ~4.TXT
ДАННЫЕ~5.TXT
ДАННЫЕ~6.TXT
ДАННЫЕ~7.TXT <=== "Старый" DATA.TXT
EDIT: Каждый файл содержит тестовые данные ( например, - file DATA~1.TXT
содержит такую строку, как "ДАННЫЕ~1.TXT"
) Таким образом, я могу отслеживать, какие файлы "перемещаются" и куда они идут. Вот откуда я знаю, где "старый" DATA.TXT
файл идет, и откуда я знаю ДАННЫЕ~6.TXT
это "пусто." На самом деле это пустой файл, в котором нет данных.
ПРАВКА № 2: Как указано в комментариях ниже, Uno на самом деле не ждет последовательного соединения. Я только что проверил это, и это правда... как бы то ни было: я все еще получаю пустые ДАННЫЕ~6.TXT
и DATA.TXT
перемещается в ДАННЫЕ~7.TXT
без причины.
Теперь, когда вы знаете цель и (вероятно) видите проблему, вот код:
/*
* Проверяет слот для SD-карты, убеждаясь, что функциональный код не отсутствует.
* для того, чтобы процесс BIB правильно регистрировал данные.
*
*/
#include <SPI.h>
#include <SD.h>
String fileName = "DATA.TXT"; // Объявите имя файла с соглашениями об именовании FAT 8.3
File dataLog; // Хранить наш "открытый" файл в объекте
void setup(){
Serial.begin( 115200 );
while( !Serial ){ // Дождитесь открытия последовательного порта, прежде чем что-либо делать
}
Serial.println( "\nInitializing SD card..." ); // Start SD card
if( !SD.begin( 4 ) ){
Serial.println( "Инициализация не удалась!" );
while( 1 );
}
Serial.println( "Инициализация выполнена." );
Serial.println( "\nChecking if we have a unique filename..." );
if( SD.exists( fileName ) ) // Дайте нашему журналу данных уникальное имя файла, если текущее имя файла уже существует
moveFiles();
dataLog = SD.open( fileName, FILE_WRITE ); // Откройте наш файл для редактирования, если он еще не существует
Serial.println( "Created save file!" );
// Write to file the first time
if( dataLog ){
Serial.println( "\nWriting int test to file..." );
dataLog.println( "Testing Sequence1..." );
dataLog.println( "\tSequence1 complete." );
Serial.println( "\tFirst test written!" );
dataLog.close();
Serial.println( "\tData log closed." );
}
else
Serial.println( "---Error opening data log file!---" );
}
void loop(){
}
// Перемещает последний `DATA.TXT` to `DATA~x.TXT-где " х` - самое большое целое.
// Это делает "самый высокий" пронумерованный файл последним журналом данных, и `DATA.TXT-текущий журнал данных.
// Следует SFN8.3 стандартам именования, с 8 символами для имени файла, 4 символами для расширения и предшествующими
// периоды преобразуются в символы`~`.
// Это оставляет нам только 999 возможных "резервных" журналов данных.
void moveFiles(){
bool sdCardFull = false; // Keep track of if our SD card is "full" or not
byte num = 1;
File newFile;
String existingFile = String( "DATA~" ) + String( num ) + String( ".TXT" ); // Creates a filename of `DATA~num.TXT` to test
// Проверьте, существует ли это имя файла. Повторите "num", чтобы избежать перезаписи существующих файлов
while( SD.exists( existingFile ) ){
if( num == 999 ){ // If the SD card is full
sdCardFull = true;
noMoreRoom( sdCardFull );
}
num++;
existingFile = String( "DATA~" ) + String( num ) + String( ".TXT" );
}
dataLog = SD.open( fileName );
// Создайте новый файл с новым именем
newFile = SD.open( existingFile, FILE_WRITE );
// Переместить старый журнал данных в новое имя файла
while( dataLog.available() )
newFile.write( dataLog.read() );
// Close, remove, then re-open the data log
newFile.close();
dataLog.close();
SD.remove( fileName ); // Deletes the old data log
}
// Мы не можем найти хорошее имя файла для формата SFN8.3, так как все доступные имена файлов были
// израсходовано, поэтому мы остановим работу программы до тех пор, пока SD-карта не будет очищена, прежде чем мы "уничтожим"
// последний файл резервной копии.
void noMoreRoom( bool sdCardFull ){
/*
lcd.setCursor( 0, 0 );
lcd.print( " SD card is " );
lcd.setCursor( 0, 1 );
lcd.print( " too full!! " );
*/
Serial.println( "SD-карта заполнена, и мы не будем продолжать, пока она не будет очищена." );
while( sdCardFull ){} // Не делайте абсолютно ничего, пока SD-карта не будет "очищена"
}
@stillborn86, 👍1
Обсуждение1 ответ
Если в интегрированной среде разработки Arduino открыт последовательный монитор и вы выполняете загрузку, последовательный монитор отключается, чтобы освободить порт для avrdude. После завершения загрузки последовательный монитор снова подключается. При новом подключении Arduino сбрасывается.
Теперь, когда avrdude закончил загрузку, Arduino начинает работать и выполняет вашу функцию setup (). Он создает новый файл, и внезапно последовательный монитор снова подключается и сбрасывает Arduino. Программа установки() снова запускается и создает следующий файл.
Этого не произойдет, если последовательный монитор не открыт, но чтобы предотвратить это, вы можете поместить длительную задержку в начало настройки().
Если я загружу код, отформатирую SD-карту и подключу Arduino к коаксиальному разъему (без последовательного монитора), а затем подожду более минуты (пока Arduino выполнит любой необходимый код), проблема все еще существует. Так что я не на 100% убежден, что проблема здесь в последовательном мониторе. Вот почему я уверенно добавил в пост "ПРАВКА №2"., @stillborn86
- Как **получить** атрибуты для файлов SD?
- Возврат в родительский каталог с библиотекой SD
- Режимы открытия файлов на SD-карте Arduino добавление/перезапись
- Сохранение файла .txt на SD-карту и чтение данных каждого содержимого в файл txt, а затем сохранение его в переменной
- Использование SD-адаптера 5 В в системе 3,3 В
- Редактирование определенной позиции в файле, хранящемся на SD-карте
- Проблема с открытием нескольких текстовых файлов одновременно/по порядку с использованием <SD.h>
- Arduino SD подсчитывает файлы и открывает их последним, как это сделать?
Дай угадаю... вы подключаете плату (или программируете плату), затем открываете последовательный терминал, и программа "начинает работать"...? А как насчет периода между подключением его (или программированием) и открытием последовательного терминала? Тогда он тоже работает, вы знаете... (предполагая Uno - но вы не указываете, какую плату используете...), @Majenko
Да, это Уно... и Нано... и Про-Мини. И скетч должен быть пойман в петлю "while( !Serial)" до тех пор, пока не будет подключен последовательный монитор, верно?, @stillborn86
Нет, эта линия предназначена только для родных USB-плат, насколько я помню. Он не будет ждать ничего на Uno или Nano, @chrisl
Возможно, вам следует сначала проверить, действительно ли файл содержит данные, прежде чем перемещать его., @chrisl
"while (!Serial)` работает только для MCU с родным USB (32u4, SAMD), а не для Uno, Nano, Mega, Mini. Uno & co. reset on new connection. они начинают работать, а затем сбрасываются при новом подключении, @Juraj
Все файлы содержат данные с соответствующими именами файлов ( например, - `File "DATA~1.TXT"'). Их правильно перемещают. Вот откуда я знаю, что " ДАННЫЕ~6.TXT-пусто., @stillborn86
Даже если MCU работает без задержки,
DATA.TXT
все еще должен идти к " ДАННЫМ~6.TXT, новый
DATA.TXTдолжен быть создан с "тестовыми данными" в соответствии с кодом, затем последовательный монитор должен сбросить вещи, переместив файл "тестовые данные" в
ДАННЫЕ~7.TXT-и дублировать "тестовые данные" на DATA.TXT` верно? Но этого не происходит... Я до сих пор не могу объяснить, что происходит., @stillborn86Вы также видите это поведение с полной новой настройкой? (То есть все файлы удалены, позволяя коду начать с известной точки старта) Возможно, Arduino был однажды прерван сбросом, прежде чем он смог записать фактические данные в файл, @chrisl
На новой установке (отформатированная SD - карта без файлов на ней) я получаю два файла:
DATA.TXT
иДАННЫЕ~1.TXT', с обоими записанными "данными тестовой последовательности". Кроме имени файла, они идентичны, согласно
cmpи
md5sum`. Я до сих пор не уверен на 100%, почему он создает два файла... обычно один из них пуст, но в данном случае они идентичны., @stillborn86Вы можете выполнить несколько сбросов, нажав кнопку сброса или повторно открыв последовательный монитор, чтобы проверить, работает ли он при правильных обстоятельствах. Сброс во время записи на SD - карту может привести к повреждению данных. Возможно, целесообразно отключить сброс от последовательного, добавив конденсатор между сбросом и землей. Это предотвращает последовательный интерфейс для сброса микроконтроллера. Хотя это также предотвращает программирование, поэтому вам придется снова удалить конденсатор для программирования, @chrisl
попробуйте использовать
-
вместо~
, @Juraj@Juraj Я следил за [SFN8.3](https://en.wikipedia.org/wiki/8.3_filename) формат, который рекомендуется [Arduino](https://www.arduino.cc/en/Reference/SDCardNotes). Он **должен** работать с"~", но он **должен** также работать с" -`. Пробуя и то, и другое, ни то, ни другое не приводит к желаемому результату., @stillborn86