Проблема с повторным пересчетом количества строк. Библиотека SD
- Войдите на сайт для отправки комментариев
Здравствуйте! Очень прошу о помощи, проблема с повторным запуском функции при работе с SD картой. Уже совсем замучался, а сроки диплома поджимают..
Имеется код:
#include <SPI.h
#include <SD.h>
String def_filename = "FILE"; //стандартное начало имени файла
String filename = "";
int slots_count = 20; //Количество файлов
int filesrows[20]; //массив со значениями количества строк в каждом файле
File workFile;
void setup() {
if (!SD.begin(10)) {
Serial.println("initialization failed!");
return;
}
upd_filesrows();
}
void upd_filesrows() {
for(int i = 1 ; i <= slots_count; i +=1) { //проверяем все файлы (от 1 до 20)
filename = def_filename + i; //составляем имя файла: FILE+i
char temp[filename.length()+1];
filename.toCharArray(temp, sizeof(temp)); //преобразуем в charArray
if (!SD.exists(temp)) { //проверяем, если такого файла на карте нет,
workFile = SD.open(temp, FILE_WRITE); //то создаем пустой файл
workFile.close(); //закрываем файл
filesrows[i-1] = 0; //записываем для него количество строк = 0
} else {
workFile = SD.open(temp); //если файл есть, то открываем
counter = 0; //обнуляем счетчик
while (workFile.available()) { //читаем все символы из файла до конца
char sd_t = workFile.read();
if (sd_t == '\n') counter++; //и увеличиваем счетчик, если символ - перенос строки
}
workFile.close(); //закрываем файл
filesrows[i-1] = counter; //записываем в массив количество строк в файле
}
filename = "";
}
}
И вроде как все работает, при инициализации недостающие файлы создаются, а у существующих пересчитываются строки и числа заносятся в массив. Проблема в том, что если в коде вызвать эту же функцию второй раз, все значения в массиве filesrows стабильно обнуляются. Причем не важно, что делали до этого. Можно просто вызвать функцию дважды и все элементы массива будут равны 0.
Почему это происходит и как это возможно исправить? Неужели проблема в библиотеке SD? До этого я столкнулся с проблемой чтения имен файлов, потому ввел фиксированные имена.
Возможно траблы в указателе и пройдясь один раз по файлу он остается в конце. Попробуйте после открытия его перемещать вначало. Например сразу после "
workFile = SD.open(temp);//если файл есть, то открываем"вызвать rewind();Хм... ошибок я не вижу, и вроде как должно все работать....
Поствте много разных
Serial.println и посмотрите в чем конкретно проблема, код вроде совсем не сложныйСпасибо за ответы!
А что за функция такая rewind такая? В библиотеке SD её нет, да и не гуглиться. Есть rewindDirectory(), но это для папок..
Да, код максимально прост - должен работать и работает. Но только 1 раз. А в проекте я хочу после изменений в файле запустить эту функцию второй раз, чтобы она пересчитала все опять.
Пробовал уже ставить для диагностики вывод, так и не понял то ли он файлы не находит (но тогда он должен был их стирать при открытии?) или строк не находит..
А, ну да... стандартная библиотека это враппер над библиотекой :)
rewind() есть у SdFile, но он приватный у File.
Впрочем это не важно. После "workFile = SD.open(temp); //если файл есть, то открываем" добавьте строчку "workFile.seek(0);" и посмотрите что будет.
--УДАЛЕНО. Простите, писал с работы, а тут фаервол иногда дублирует запросы и сообщение дважды отправляется..
Нет, workFile.seek(0) не помогла. Вызываю в setup() upd_filesrows(); два раза (на всякий случай через паузу). После первого в массиве есть значения (правильные количества строк), после второго уже только 0.
Может стринг какой то не обнуляется или еще чего не связанного с SD? Вообще по умолчанию файл открывается для чтения, а это подразумевает открытие файла с самого начала (запись с конца). По этому он после закрытия вроде как должен закрываться и все, в следующий раз с самого начала опять считать..
Кстати, вообще реально отказаться от стринга в моем случае? К примеру сделать имена файлов просто 1,2,3..20?
>ообще реально отказаться от стринга в моем случае?
Смотря от какого. От String (объет) - возможно, а от string (массив чаров, сишная строка) - не выйдет.
char fileName[]="file**.txt"; // 0123456789 - позиции символов #define FIRST_DIGIT_POS 4 // позиция первой звездочки #define SECOND_DIGIT_POS (FIRST_DIGIT_POS+1) // позиция второй звездочки void setup(){ Serial.begin(57600); for(byte i=0;i<20;i++){ buildFileName(i+1); // формируем имя файла //выводим что получилось. Serial.println(fileName); } } // заменяет ** на fileNo в массиве fileName[] void buildFileName(byte fileNo){ // "разбиваем" число на первую и вторую цифры byte firstDigit=fileNo/10; byte secondDigit=fileNo %10; // заменяем звездочки fileName[FIRST_DIGIT_POS]=firstDigit+'0';// заменяем первую зведочку, и сразу переводим цифру в ее ASCII код fileName[SECOND_DIGIT_POS]=secondDigit+'0'; // то же самое для второй } void loop(){ }Вывод:
Уменя тоже проблемма на подобии
Есть функция которая сканирует флешку и пишет в массив.
void scanSD() { kolfiles=0; memset(recfile, 0, sizeof(recfile)); File dir=SD.open("/"); while(true) { File entry = dir.openNextFile(); if (!entry) {break;} if (!entry.isDirectory() && entry.size()>15 && entry.size()<2600 && String(entry.name()).length()<=12) { strcpy(recfile[kolfiles], entry.name()); kolfiles++; if (kolfiles>29) { entry.close();break;} } entry.close(); } dir.rewindDirectory(); }Я добавляю и удаляю файлы с флешки и после этого вызываю эту функцию. Но первый раз функция отрабатывает отлично, а в дальнейшем 1 файл кудато пропадает. Подскажите что я делаю не так.